Author: mjansen
Date: Sat Apr 8 17:32:45 2017
New Revision: 74285
URL:
http://svn.reactos.org/svn/reactos?rev=74285&view=rev
Log:
[WIN32SS] Implement NtGdiAddFontMemResourceEx and NtGdiRemoveFontMemResourceEx.
CORE-13046
Added:
trunk/reactos/win32ss/gdi/ntgdi/font.h (with props)
Modified:
trunk/reactos/win32ss/gdi/eng/stubs.c
trunk/reactos/win32ss/gdi/ntgdi/font.c
trunk/reactos/win32ss/gdi/ntgdi/freetype.c
trunk/reactos/win32ss/gdi/ntgdi/init.c
trunk/reactos/win32ss/gdi/ntgdi/text.h
trunk/reactos/win32ss/user/ntuser/win32.h
Modified: trunk/reactos/win32ss/gdi/eng/stubs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/eng/stubs.c?re…
==============================================================================
--- trunk/reactos/win32ss/gdi/eng/stubs.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/eng/stubs.c [iso-8859-1] Sat Apr 8 17:32:45 2017
@@ -838,22 +838,6 @@
/*
* @unimplemented
*/
-HANDLE
-APIENTRY
-NtGdiAddFontMemResourceEx(
- IN PVOID pvBuffer,
- IN DWORD cjBuffer,
- IN DESIGNVECTOR *pdv,
- IN ULONG cjDV,
- OUT DWORD *pNumFonts)
-{
- UNIMPLEMENTED;
- return NULL;
-}
-
-/*
- * @unimplemented
- */
BOOL
APIENTRY
NtGdiRemoveMergeFont(
@@ -1324,18 +1308,6 @@
{
UNIMPLEMENTED;
return 0;
-}
-
-/*
- * @unimplemented
- */
-BOOL
-APIENTRY
-NtGdiRemoveFontMemResourceEx(
- IN HANDLE hMMFont)
-{
- UNIMPLEMENTED;
- return FALSE;
}
/*
Modified: trunk/reactos/win32ss/gdi/ntgdi/font.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/font.c?r…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/font.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/font.c [iso-8859-1] Sat Apr 8 17:32:45 2017
@@ -478,6 +478,71 @@
return Ret;
}
+HANDLE
+APIENTRY
+NtGdiAddFontMemResourceEx(
+ IN PVOID pvBuffer,
+ IN DWORD cjBuffer,
+ IN DESIGNVECTOR *pdv,
+ IN ULONG cjDV,
+ OUT DWORD *pNumFonts)
+{
+ _SEH2_VOLATILE PVOID Buffer = NULL;
+ HANDLE Ret;
+ DWORD NumFonts = 0;
+
+ DPRINT("NtGdiAddFontMemResourceEx\n");
+ DBG_UNREFERENCED_PARAMETER(pdv);
+ DBG_UNREFERENCED_PARAMETER(cjDV);
+
+ if (!pvBuffer || !cjBuffer)
+ return NULL;
+
+ _SEH2_TRY
+ {
+ ProbeForRead(pvBuffer, cjBuffer, sizeof(BYTE));
+ Buffer = ExAllocatePoolWithQuotaTag(PagedPool, cjBuffer, TAG_FONT);
+ RtlCopyMemory(Buffer, pvBuffer, cjBuffer);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ if (Buffer != NULL)
+ {
+ ExFreePoolWithTag(Buffer, TAG_FONT);
+ }
+ _SEH2_YIELD(return NULL);
+ }
+ _SEH2_END;
+
+ Ret = IntGdiAddFontMemResource(Buffer, cjBuffer, &NumFonts);
+ ExFreePoolWithTag(Buffer, TAG_FONT);
+
+ _SEH2_TRY
+ {
+ ProbeForWrite(pNumFonts, sizeof(NumFonts), 1);
+ *pNumFonts = NumFonts;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Leak it? */
+ _SEH2_YIELD(return NULL);
+ }
+ _SEH2_END;
+
+
+ return Ret;
+}
+
+
+BOOL
+APIENTRY
+NtGdiRemoveFontMemResourceEx(
+ IN HANDLE hMMFont)
+{
+ return IntGdiRemoveFontMemResource(hMMFont);
+}
+
+
/*
* @unimplemented
*/
Added: trunk/reactos/win32ss/gdi/ntgdi/font.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/font.h?r…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/font.h (added)
+++ trunk/reactos/win32ss/gdi/ntgdi/font.h [iso-8859-1] Sat Apr 8 17:32:45 2017
@@ -0,0 +1,64 @@
+#pragma once
+
+
+typedef struct _FONT_ENTRY
+{
+ LIST_ENTRY ListEntry;
+ FONTGDI *Font;
+ UNICODE_STRING FaceName;
+ BYTE NotEnum;
+} FONT_ENTRY, *PFONT_ENTRY;
+
+typedef struct _FONT_ENTRY_MEM
+{
+ LIST_ENTRY ListEntry;
+ FONT_ENTRY *Entry;
+} FONT_ENTRY_MEM, *PFONT_ENTRY_MEM;
+
+typedef struct _FONT_ENTRY_COLL_MEM
+{
+ LIST_ENTRY ListEntry;
+ UINT Handle;
+ FONT_ENTRY_MEM *Entry;
+} FONT_ENTRY_COLL_MEM, *PFONT_ENTRY_COLL_MEM;
+
+typedef struct _FONT_CACHE_ENTRY
+{
+ LIST_ENTRY ListEntry;
+ int GlyphIndex;
+ FT_Face Face;
+ FT_BitmapGlyph BitmapGlyph;
+ int Height;
+ MATRIX mxWorldToDevice;
+} FONT_CACHE_ENTRY, *PFONT_CACHE_ENTRY;
+
+
+/*
+ * FONTSUBST_... --- constants for font substitutes
+ */
+#define FONTSUBST_FROM 0
+#define FONTSUBST_TO 1
+#define FONTSUBST_FROM_AND_TO 2
+
+/*
+ * FONTSUBST_ENTRY --- font substitute entry
+ */
+typedef struct FONTSUBST_ENTRY
+{
+ LIST_ENTRY ListEntry;
+ UNICODE_STRING FontNames[FONTSUBST_FROM_AND_TO];
+ BYTE CharSets[FONTSUBST_FROM_AND_TO];
+} FONTSUBST_ENTRY, *PFONTSUBST_ENTRY;
+
+
+typedef struct GDI_LOAD_FONT
+{
+ PUNICODE_STRING pFileName;
+ PVOID Buffer;
+ ULONG BufferSize;
+ DWORD Characteristics;
+ UNICODE_STRING RegValueName;
+ BOOL IsTrueType;
+ PFONT_ENTRY_MEM PrivateEntry;
+} GDI_LOAD_FONT, *PGDI_LOAD_FONT;
+
Propchange: trunk/reactos/win32ss/gdi/ntgdi/font.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/win32ss/gdi/ntgdi/freetype.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/freetype…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/freetype.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/freetype.c [iso-8859-1] Sat Apr 8 17:32:45 2017
@@ -31,6 +31,7 @@
#include FT_INTERNAL_TRUETYPE_TYPES_H
#include <gdi/eng/floatobj.h>
+#include "font.h"
#define NDEBUG
#include <debug.h>
@@ -90,13 +91,6 @@
}
}
-typedef struct _FONT_ENTRY
-{
- LIST_ENTRY ListEntry;
- FONTGDI *Font;
- UNICODE_STRING FaceName;
- BYTE NotEnum;
-} FONT_ENTRY, *PFONT_ENTRY;
/* The FreeType library is not thread safe, so we have
to serialize access to it */
@@ -120,15 +114,6 @@
#define MAX_FONT_CACHE 256
-typedef struct _FONT_CACHE_ENTRY
-{
- LIST_ENTRY ListEntry;
- int GlyphIndex;
- FT_Face Face;
- FT_BitmapGlyph BitmapGlyph;
- int Height;
- MATRIX mxWorldToDevice;
-} FONT_CACHE_ENTRY, *PFONT_CACHE_ENTRY;
static LIST_ENTRY FontCacheListHead;
static UINT FontCacheNumEntries;
@@ -200,23 +185,6 @@
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ SYMBOL_CHARSET, CP_SYMBOL, {{0,0,0,0},{FS_SYMBOL,0}} }
};
-
-/*
- * FONTSUBST_... --- constants for font substitutes
- */
-#define FONTSUBST_FROM 0
-#define FONTSUBST_TO 1
-#define FONTSUBST_FROM_AND_TO 2
-
-/*
- * FONTSUBST_ENTRY --- font substitute entry
- */
-typedef struct FONTSUBST_ENTRY
-{
- LIST_ENTRY ListEntry;
- UNICODE_STRING FontNames[FONTSUBST_FROM_AND_TO];
- BYTE CharSets[FONTSUBST_FROM_AND_TO];
-} FONTSUBST_ENTRY, *PFONTSUBST_ENTRY;
/* list head */
static RTL_STATIC_LIST_HEAD(FontSubstListHead);
@@ -695,22 +663,13 @@
return FW_NORMAL;
}
-typedef struct GDI_LOAD_FONT
-{
- PUNICODE_STRING pFileName;
- PVOID Buffer;
- ULONG BufferSize;
- DWORD Characteristics;
- UNICODE_STRING RegValueName;
- BOOL IsTrueType;
-} GDI_LOAD_FONT, *PGDI_LOAD_FONT;
-
static INT FASTCALL
IntGdiLoadFontsFromMemory(PGDI_LOAD_FONT pLoadFont,
PSHARED_FACE SharedFace, FT_Long FontIndex, INT CharSetIndex)
{
FT_Error Error;
PFONT_ENTRY Entry;
+ FONT_ENTRY_MEM* PrivateEntry = NULL;
FONTGDI * FontGDI;
NTSTATUS Status;
FT_Face Face;
@@ -780,19 +739,48 @@
}
/* set file name */
- FontGDI->Filename = ExAllocatePoolWithTag(PagedPool,
- pFileName->Length +
sizeof(UNICODE_NULL),
- GDITAG_PFF);
- if (FontGDI->Filename == NULL)
- {
- EngFreeMem(FontGDI);
- SharedFace_Release(SharedFace);
- ExFreePoolWithTag(Entry, TAG_FONT);
- EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return 0; /* failure */
- }
- RtlCopyMemory(FontGDI->Filename, pFileName->Buffer, pFileName->Length);
- FontGDI->Filename[pFileName->Length / sizeof(WCHAR)] = UNICODE_NULL;
+ if (pFileName)
+ {
+ FontGDI->Filename = ExAllocatePoolWithTag(PagedPool,
+ pFileName->Length +
sizeof(UNICODE_NULL),
+ GDITAG_PFF);
+ if (FontGDI->Filename == NULL)
+ {
+ EngFreeMem(FontGDI);
+ SharedFace_Release(SharedFace);
+ ExFreePoolWithTag(Entry, TAG_FONT);
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return 0; /* failure */
+ }
+ RtlCopyMemory(FontGDI->Filename, pFileName->Buffer, pFileName->Length);
+ FontGDI->Filename[pFileName->Length / sizeof(WCHAR)] = UNICODE_NULL;
+ }
+ else
+ {
+ FontGDI->Filename = NULL;
+
+ PrivateEntry = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_ENTRY_MEM),
TAG_FONT);
+ if (!PrivateEntry)
+ {
+ if (FontGDI->Filename)
+ ExFreePoolWithTag(FontGDI->Filename, GDITAG_PFF);
+ EngFreeMem(FontGDI);
+ SharedFace_Release(SharedFace);
+ ExFreePoolWithTag(Entry, TAG_FONT);
+ return 0;
+ }
+
+ PrivateEntry->Entry = Entry;
+ if (pLoadFont->PrivateEntry)
+ {
+ InsertTailList(&pLoadFont->PrivateEntry->ListEntry,
&PrivateEntry->ListEntry);
+ }
+ else
+ {
+ InitializeListHead(&PrivateEntry->ListEntry);
+ pLoadFont->PrivateEntry = PrivateEntry;
+ }
+ }
/* set face */
FontGDI->SharedFace = SharedFace;
@@ -806,7 +794,20 @@
Status = RtlAnsiStringToUnicodeString(&Entry->FaceName, &AnsiFaceName,
TRUE);
if (!NT_SUCCESS(Status))
{
- ExFreePoolWithTag(FontGDI->Filename, GDITAG_PFF);
+ if (PrivateEntry)
+ {
+ if (pLoadFont->PrivateEntry == PrivateEntry)
+ {
+ pLoadFont->PrivateEntry = NULL;
+ }
+ else
+ {
+ RemoveEntryList(&PrivateEntry->ListEntry);
+ }
+ ExFreePoolWithTag(PrivateEntry, TAG_FONT);
+ }
+ if (FontGDI->Filename)
+ ExFreePoolWithTag(FontGDI->Filename, GDITAG_PFF);
EngFreeMem(FontGDI);
SharedFace_Release(SharedFace);
ExFreePoolWithTag(Entry, TAG_FONT);
@@ -1010,6 +1011,7 @@
LoadFont.Characteristics = Characteristics;
RtlInitUnicodeString(&LoadFont.RegValueName, NULL);
LoadFont.IsTrueType = FALSE;
+ LoadFont.PrivateEntry = NULL;
FontCount = IntGdiLoadFontsFromMemory(&LoadFont, NULL, -1, -1);
ObDereferenceObject(SectionObject);
@@ -1060,7 +1062,99 @@
return FontCount;
}
+HANDLE FASTCALL
+IntGdiAddFontMemResource(PVOID Buffer, DWORD dwSize, PDWORD pNumAdded)
+{
+ GDI_LOAD_FONT LoadFont;
+ FONT_ENTRY_COLL_MEM* EntryCollection;
+ INT FontCount;
+ HANDLE Ret = 0;
+
+ LoadFont.pFileName = NULL;
+ LoadFont.Buffer = Buffer;
+ LoadFont.BufferSize = dwSize;
+ LoadFont.Characteristics = FR_PRIVATE | FR_NOT_ENUM;
+ RtlInitUnicodeString(&LoadFont.RegValueName, NULL);
+ LoadFont.IsTrueType = FALSE;
+ LoadFont.PrivateEntry = NULL;
+ FontCount = IntGdiLoadFontsFromMemory(&LoadFont, NULL, -1, -1);
+
+ RtlFreeUnicodeString(&LoadFont.RegValueName);
+
+ *pNumAdded = FontCount;
+ if (FontCount > 0)
+ {
+ EntryCollection = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_ENTRY_COLL_MEM),
TAG_FONT);
+ if (EntryCollection)
+ {
+ PPROCESSINFO Win32Process = PsGetCurrentProcessWin32Process();
+ EntryCollection->Entry = LoadFont.PrivateEntry;
+ IntLockProcessPrivateFonts(Win32Process);
+ EntryCollection->Handle = ++Win32Process->PrivateMemFontHandleCount;
+ InsertTailList(&Win32Process->PrivateMemFontListHead,
&EntryCollection->ListEntry);
+ IntUnLockProcessPrivateFonts(Win32Process);
+ Ret = (HANDLE)EntryCollection->Handle;
+ }
+ }
+
+ return Ret;
+}
+
// FIXME: Add RemoveFontResource
+
+VOID FASTCALL
+IntGdiCleanupMemEntry(PFONT_ENTRY_MEM Head)
+{
+ PLIST_ENTRY Entry;
+ PFONT_ENTRY_MEM FontEntry;
+
+ while (!IsListEmpty(&Head->ListEntry))
+ {
+ Entry = RemoveHeadList(&Head->ListEntry);
+ FontEntry = CONTAINING_RECORD(Entry, FONT_ENTRY_MEM, ListEntry);
+
+ // Delete FontEntry->Entry (FONT_ENTRY*)
+ ExFreePoolWithTag(FontEntry, TAG_FONT);
+ }
+
+ // Delete Head->Entry (FONT_ENTRY*)
+ ExFreePoolWithTag(Head, TAG_FONT);
+}
+
+BOOL FASTCALL
+IntGdiRemoveFontMemResource(HANDLE hMMFont)
+{
+ PLIST_ENTRY Entry;
+ PFONT_ENTRY_COLL_MEM CurrentEntry;
+ PFONT_ENTRY_COLL_MEM EntryCollection = NULL;
+ PPROCESSINFO Win32Process = PsGetCurrentProcessWin32Process();
+
+ IntLockProcessPrivateFonts(Win32Process);
+ Entry = Win32Process->PrivateMemFontListHead.Flink;
+ while (Entry != &Win32Process->PrivateMemFontListHead)
+ {
+ CurrentEntry = CONTAINING_RECORD(Entry, FONT_ENTRY_COLL_MEM, ListEntry);
+
+ if (CurrentEntry->Handle == (UINT)hMMFont)
+ {
+ EntryCollection = CurrentEntry;
+ RemoveEntryList(Entry);
+ break;
+ }
+
+ Entry = Entry->Flink;
+ }
+ IntUnLockProcessPrivateFonts(Win32Process);
+
+ if (EntryCollection)
+ {
+ IntGdiCleanupMemEntry(EntryCollection->Entry);
+ ExFreePoolWithTag(EntryCollection, TAG_FONT);
+ return TRUE;
+ }
+ return FALSE;
+}
+
BOOL FASTCALL
IntIsFontRenderingEnabled(VOID)
Modified: trunk/reactos/win32ss/gdi/ntgdi/init.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/init.c?r…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/init.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/init.c [iso-8859-1] Sat Apr 8 17:32:45 2017
@@ -21,6 +21,8 @@
ASSERT(ppiCurrent);
InitializeListHead(&ppiCurrent->PrivateFontListHead);
+ InitializeListHead(&ppiCurrent->PrivateMemFontListHead);
+ ppiCurrent->PrivateMemFontHandleCount = 0;
ExInitializeFastMutex(&ppiCurrent->PrivateFontListLock);
InitializeListHead(&ppiCurrent->GDIBrushAttrFreeList);
Modified: trunk/reactos/win32ss/gdi/ntgdi/text.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/text.h?r…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/text.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/text.h [iso-8859-1] Sat Apr 8 17:32:45 2017
@@ -113,6 +113,8 @@
ULONG FASTCALL FontGetObject(PTEXTOBJ TextObj, ULONG Count, PVOID Buffer);
VOID FASTCALL IntLoadSystemFonts(VOID);
INT FASTCALL IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics);
+HANDLE FASTCALL IntGdiAddFontMemResource(PVOID Buffer, DWORD dwSize, PDWORD pNumAdded);
+BOOL FASTCALL IntGdiRemoveFontMemResource(HANDLE hMMFont);
ULONG FASTCALL
ftGdiGetGlyphOutline(PDC,WCHAR,UINT,LPGLYPHMETRICS,ULONG,PVOID,LPMAT2,BOOL);
INT FASTCALL IntGetOutlineTextMetrics(PFONTGDI,UINT,OUTLINETEXTMETRICW *);
BOOL FASTCALL TextIntUpdateSize(PDC,PTEXTOBJ,PFONTGDI,BOOL);
Modified: trunk/reactos/win32ss/user/ntuser/win32.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/win32.…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/win32.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/win32.h [iso-8859-1] Sat Apr 8 17:32:45 2017
@@ -273,6 +273,9 @@
/* ReactOS */
FAST_MUTEX PrivateFontListLock;
LIST_ENTRY PrivateFontListHead;
+ LIST_ENTRY PrivateMemFontListHead;
+ UINT PrivateMemFontHandleCount;
+
FAST_MUTEX DriverObjListLock;
LIST_ENTRY DriverObjListHead;
W32HEAP_USER_MAPPING HeapMappings;