Index: reactos/win32ss/gdi/eng/stubs.c =================================================================== --- reactos/win32ss/gdi/eng/stubs.c (revision 74270) +++ reactos/win32ss/gdi/eng/stubs.c (working copy) @@ -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( Index: reactos/win32ss/gdi/ntgdi/font.c =================================================================== --- reactos/win32ss/gdi/ntgdi/font.c (revision 74270) +++ reactos/win32ss/gdi/ntgdi/font.c (working copy) @@ -478,6 +478,60 @@ return Ret; } +HANDLE +APIENTRY +NtGdiAddFontMemResourceEx( + IN PVOID pvBuffer, + IN DWORD cjBuffer, + IN DESIGNVECTOR *pdv, + IN ULONG cjDV, + OUT DWORD *pNumFonts) +{ + PVOID Buffer; + HANDLE Ret; + DWORD NumFonts = 0; + + DPRINT("NtGdiAddFontMemResourceEx\n"); + DBG_UNREFERENCED_PARAMETER(pdv); + DBG_UNREFERENCED_PARAMETER(cjDV); + + if (!pvBuffer || !cjBuffer) + return NULL; + + Buffer = ExAllocatePoolWithTag(PagedPool, cjBuffer, TAG_FONT); + + _SEH2_TRY + { + ProbeForRead(pvBuffer, cjBuffer, sizeof(BYTE)); + RtlCopyMemory(Buffer, pvBuffer, cjBuffer); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + 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; +} + + /* * @unimplemented */ Index: reactos/win32ss/gdi/ntgdi/freetype.c =================================================================== --- reactos/win32ss/gdi/ntgdi/freetype.c (revision 74270) +++ reactos/win32ss/gdi/ntgdi/freetype.c (working copy) @@ -703,6 +703,7 @@ DWORD Characteristics; UNICODE_STRING RegValueName; BOOL IsTrueType; + PFONT_ENTRY Entry; } GDI_LOAD_FONT, *PGDI_LOAD_FONT; static INT FASTCALL @@ -728,6 +729,8 @@ FT_ULong os2_ulCodePageRange1; FT_UShort os2_usWeightClass; + pLoadFont->Entry = NULL; + if (SharedFace == NULL && CharSetIndex == -1) { /* load a face from memory */ @@ -780,19 +783,26 @@ } /* set file name */ - FontGDI->Filename = ExAllocatePoolWithTag(PagedPool, - pFileName->Length + sizeof(UNICODE_NULL), - GDITAG_PFF); - if (FontGDI->Filename == NULL) + if (pFileName) { - EngFreeMem(FontGDI); - SharedFace_Release(SharedFace); - ExFreePoolWithTag(Entry, TAG_FONT); - EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); - return 0; /* failure */ + 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; } - RtlCopyMemory(FontGDI->Filename, pFileName->Buffer, pFileName->Length); - FontGDI->Filename[pFileName->Length / sizeof(WCHAR)] = UNICODE_NULL; + else + { + FontGDI->Filename = NULL; /* FIXME: Is this safe? */ + } /* set face */ FontGDI->SharedFace = SharedFace; @@ -806,7 +816,8 @@ Status = RtlAnsiStringToUnicodeString(&Entry->FaceName, &AnsiFaceName, TRUE); if (!NT_SUCCESS(Status)) { - ExFreePoolWithTag(FontGDI->Filename, GDITAG_PFF); + if (FontGDI->Filename) + ExFreePoolWithTag(FontGDI->Filename, GDITAG_PFF); EngFreeMem(FontGDI); SharedFace_Release(SharedFace); ExFreePoolWithTag(Entry, TAG_FONT); @@ -944,6 +955,9 @@ } } + /* Fixme: We whould link all fonts added! */ + + pLoadFont->Entry = Entry; return FontCount; /* number of loaded fonts */ } @@ -1060,6 +1074,28 @@ return FontCount; } +HANDLE FASTCALL +IntGdiAddFontMemResource(PVOID Buffer, DWORD dwSize, PDWORD pNumAdded) +{ + GDI_LOAD_FONT LoadFont; + INT FontCount; + + LoadFont.pFileName = NULL; + LoadFont.Buffer = Buffer; + LoadFont.BufferSize = dwSize; + LoadFont.Characteristics = FR_PRIVATE | FR_NOT_ENUM; + LoadFont.IsTrueType = FALSE; + FontCount = IntGdiLoadFontsFromMemory(&LoadFont, NULL, -1, -1); + + *pNumAdded = FontCount; + if (FontCount > 0) + { + return LoadFont.Entry; + } + + return NULL; +} + // FIXME: Add RemoveFontResource BOOL FASTCALL Index: reactos/win32ss/gdi/ntgdi/text.h =================================================================== --- reactos/win32ss/gdi/ntgdi/text.h (revision 74270) +++ reactos/win32ss/gdi/ntgdi/text.h (working copy) @@ -113,6 +113,7 @@ 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); ULONG FASTCALL ftGdiGetGlyphOutline(PDC,WCHAR,UINT,LPGLYPHMETRICS,ULONG,PVOID,LPMAT2,BOOL); INT FASTCALL IntGetOutlineTextMetrics(PFONTGDI,UINT,OUTLINETEXTMETRICW *); BOOL FASTCALL TextIntUpdateSize(PDC,PTEXTOBJ,PFONTGDI,BOOL);