From 7bfa0b86e36b6722d2ac6134f03cb38cc545dcbf Mon Sep 17 00:00:00 2001 From: James Tabor Date: Thu, 30 Oct 2008 13:33:08 +0000 Subject: [PATCH] Implement GetFontUnicodeRanges, port from wine. Tested with wine gdi32 font crosstests. svn path=/trunk/; revision=37099 --- .../subsystems/win32/win32k/include/text.h | 1 + .../subsystems/win32/win32k/objects/font.c | 75 +++++++++++++++++++ .../win32/win32k/objects/freetype.c | 68 +++++++++++++++++ reactos/subsystems/win32/win32k/stubs/stubs.c | 13 ---- 4 files changed, 144 insertions(+), 13 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/text.h b/reactos/subsystems/win32/win32k/include/text.h index 0503c169546..c44c5b9b695 100644 --- a/reactos/subsystems/win32/win32k/include/text.h +++ b/reactos/subsystems/win32/win32k/include/text.h @@ -92,6 +92,7 @@ DWORD FASTCALL IntGdiGetCharSet(HDC); BOOL FASTCALL ftGdiGetTextMetricsW(HDC,PTMW_INTERNAL); DWORD FASTCALL ftGetFontLanguageInfo(PDC); INT FASTCALL ftGdiGetTextCharsetInfo(PDC,PFONTSIGNATURE,DWORD); +DWORD FASTCALL ftGetFontUnicodeRanges(PFONTGDI, PGLYPHSET); #define IntLockProcessPrivateFonts(W32Process) \ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&W32Process->PrivateFontListLock) diff --git a/reactos/subsystems/win32/win32k/objects/font.c b/reactos/subsystems/win32/win32k/objects/font.c index 27d96514296..76e7dfdf57a 100644 --- a/reactos/subsystems/win32/win32k/objects/font.c +++ b/reactos/subsystems/win32/win32k/objects/font.c @@ -62,6 +62,81 @@ NtGdiAddFontResourceW( return Ret; } + /* + * @implemented + */ +DWORD +APIENTRY +NtGdiGetFontUnicodeRanges( + IN HDC hdc, + OUT OPTIONAL LPGLYPHSET pgs) +{ + PDC pDc; + PDC_ATTR Dc_Attr; + HFONT hFont; + PTEXTOBJ TextObj; + PFONTGDI FontGdi; + DWORD Size = 0; + PGLYPHSET pgsSafe; + NTSTATUS Status = STATUS_SUCCESS; + + pDc = DC_LockDc(hdc); + if (!pDc) + { + SetLastWin32Error(ERROR_INVALID_HANDLE); + return 0; + } + + Dc_Attr = pDc->pDc_Attr; + if(!Dc_Attr) Dc_Attr = &pDc->Dc_Attr; + + hFont = Dc_Attr->hlfntNew; + TextObj = TEXTOBJ_LockText(hFont); + + if ( TextObj == NULL) + { + SetLastWin32Error(ERROR_INVALID_HANDLE); + goto Exit; + } + FontGdi = ObjToGDI(TextObj->Font, FONT); + + + Size = ftGetFontUnicodeRanges( FontGdi, NULL); + if (Size && pgs) + { + pgsSafe = ExAllocatePoolWithTag(PagedPool, Size, TAG_GDITEXT); + if (!pgsSafe) + { + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + Size = 0; + goto Exit; + } + + Size = ftGetFontUnicodeRanges( FontGdi, pgsSafe); + + if (Size) + { + _SEH_TRY + { + ProbeForWrite(pgsSafe, Size, 1); + RtlCopyMemory(pgs, pgsSafe, Size); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END + + if (!NT_SUCCESS(Status)) Size = 0; + } + ExFreePoolWithTag(pgsSafe, TAG_GDITEXT); + } +Exit: + TEXTOBJ_UnlockText(TextObj); + DC_UnlockDc(pDc); + return Size; +} + ULONG APIENTRY NtGdiGetGlyphOutline( diff --git a/reactos/subsystems/win32/win32k/objects/freetype.c b/reactos/subsystems/win32/win32k/objects/freetype.c index 9c156e1fd46..b00a282e7e0 100644 --- a/reactos/subsystems/win32/win32k/objects/freetype.c +++ b/reactos/subsystems/win32/win32k/objects/freetype.c @@ -3371,6 +3371,74 @@ ftGdiGetTextCharsetInfo( return Ret; } + +DWORD +FASTCALL +ftGetFontUnicodeRanges(PFONTGDI Font, PGLYPHSET glyphset) +{ + DWORD size = 0; + DWORD num_ranges = 0; + FT_Face face = Font->face; + + if (face->charmap->encoding == FT_ENCODING_UNICODE) + { + FT_UInt glyph_code = 0; + FT_ULong char_code, char_code_prev; + + char_code_prev = char_code = FT_Get_First_Char(face, &glyph_code); + + DPRINT("face encoding FT_ENCODING_UNICODE, number of glyphs %ld, first glyph %u, first char %04lx\n", + face->num_glyphs, glyph_code, char_code); + + if (!glyph_code) return 0; + + if (glyphset) + { + glyphset->ranges[0].wcLow = (USHORT)char_code; + glyphset->ranges[0].cGlyphs = 0; + glyphset->cGlyphsSupported = 0; + } + + num_ranges = 1; + while (glyph_code) + { + if (char_code < char_code_prev) + { + DPRINT1("expected increasing char code from FT_Get_Next_Char\n"); + return 0; + } + if (char_code - char_code_prev > 1) + { + num_ranges++; + if (glyphset) + { + glyphset->ranges[num_ranges - 1].wcLow = (USHORT)char_code; + glyphset->ranges[num_ranges - 1].cGlyphs = 1; + glyphset->cGlyphsSupported++; + } + } + else if (glyphset) + { + glyphset->ranges[num_ranges - 1].cGlyphs++; + glyphset->cGlyphsSupported++; + } + char_code_prev = char_code; + char_code = FT_Get_Next_Char(face, char_code, &glyph_code); + } + } + else + DPRINT1("encoding %u not supported\n", face->charmap->encoding); + + size = sizeof(GLYPHSET) + sizeof(WCRANGE) * (num_ranges - 1); + if (glyphset) + { + glyphset->cbThis = size; + glyphset->cRanges = num_ranges; + } + return size; +} + + DWORD FASTCALL ftGetFontLanguageInfo(PDC Dc) diff --git a/reactos/subsystems/win32/win32k/stubs/stubs.c b/reactos/subsystems/win32/win32k/stubs/stubs.c index 439b4765e53..e39e980b72d 100644 --- a/reactos/subsystems/win32/win32k/stubs/stubs.c +++ b/reactos/subsystems/win32/win32k/stubs/stubs.c @@ -2227,19 +2227,6 @@ NtGdiQueryFontAssocInfo( return 0; } - /* - * @unimplemented - */ -DWORD -APIENTRY -NtGdiGetFontUnicodeRanges( - IN HDC hdc, - OUT OPTIONAL LPGLYPHSET pgs) -{ - UNIMPLEMENTED; - return 0; -} - /* * @unimplemented */