mirror of
https://github.com/reactos/reactos.git
synced 2025-05-22 18:45:00 +00:00
Implement GetFontUnicodeRanges, port from wine. Tested with wine gdi32 font crosstests.
svn path=/trunk/; revision=37099
This commit is contained in:
parent
a233789dd4
commit
7bfa0b86e3
4 changed files with 144 additions and 13 deletions
|
@ -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)
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -2227,19 +2227,6 @@ NtGdiQueryFontAssocInfo(
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
DWORD
|
||||
APIENTRY
|
||||
NtGdiGetFontUnicodeRanges(
|
||||
IN HDC hdc,
|
||||
OUT OPTIONAL LPGLYPHSET pgs)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue