gdi32: Implement GetFontUnicodeRanges.

This commit is contained in:
Hans Leidekker 2007-03-01 20:30:12 +01:00 committed by Alexandre Julliard
parent abe3428f8b
commit 748032e0fb
4 changed files with 142 additions and 2 deletions

View File

@ -3326,9 +3326,19 @@ BOOL WINAPI GetCharWidthI(HDC hdc, UINT first, UINT count, LPWORD glyphs, LPINT
/***********************************************************************
* GetFontUnicodeRanges (GDI32.@)
*
* Retrieve a list of supported Unicode characters in a font.
*
* PARAMS
* hdc [I] Handle to a device context.
* lpgs [O] GLYPHSET structure specifying supported character ranges.
*
* RETURNS
* Success: Number of bytes written to the buffer pointed to by lpgs.
* Failure: 0
*
*/
DWORD WINAPI GetFontUnicodeRanges(HDC hdc, LPGLYPHSET lpgs)
{
FIXME("(%p, %p): stub\n", hdc, lpgs);
return 0;
return WineEngGetFontUnicodeRanges(hdc, lpgs);
}

View File

@ -4398,6 +4398,91 @@ BOOL WineEngGetLinkedHFont(DC *dc, WCHAR c, HFONT *new_hfont, UINT *glyph)
return ret;
}
/* Retrieve a list of supported Unicode ranges for a given font.
* Can be called with NULL gs to calculate the buffer size. Returns
* the number of ranges found.
*/
static DWORD get_font_unicode_ranges(FT_Face face, GLYPHSET *gs)
{
DWORD num_ranges = 0;
if (face->charmap->encoding == FT_ENCODING_UNICODE && pFT_Get_First_Char)
{
FT_UInt glyph_code;
FT_ULong char_code, char_code_prev;
glyph_code = 0;
char_code_prev = char_code = pFT_Get_First_Char(face, &glyph_code);
TRACE("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 (gs)
{
gs->ranges[0].wcLow = (USHORT)char_code;
gs->ranges[0].cGlyphs = 0;
gs->cGlyphsSupported = 0;
}
num_ranges = 1;
while (glyph_code)
{
if (char_code < char_code_prev)
{
ERR("expected increasing char code from FT_Get_Next_Char\n");
return 0;
}
if (char_code - char_code_prev > 1)
{
num_ranges++;
if (gs)
{
gs->ranges[num_ranges - 1].wcLow = (USHORT)char_code;
gs->ranges[num_ranges - 1].cGlyphs = 1;
gs->cGlyphsSupported++;
}
}
else if (gs)
{
gs->ranges[num_ranges - 1].cGlyphs++;
gs->cGlyphsSupported++;
}
char_code_prev = char_code;
char_code = pFT_Get_Next_Char(face, char_code, &glyph_code);
}
}
else
FIXME("encoding %u not supported\n", face->charmap->encoding);
return num_ranges;
}
DWORD WineEngGetFontUnicodeRanges(HDC hdc, LPGLYPHSET glyphset)
{
DWORD size = 0;
DC *dc = DC_GetDCPtr(hdc);
TRACE("(%p, %p)\n", hdc, glyphset);
if (!dc) return 0;
if (dc->gdiFont)
{
DWORD num_ranges = get_font_unicode_ranges(dc->gdiFont->ft_face, glyphset);
size = sizeof(GLYPHSET) + sizeof(WCRANGE) * (num_ranges - 1);
if (glyphset)
{
glyphset->cbThis = size;
glyphset->cRanges = num_ranges;
}
}
GDI_ReleaseObj(hdc);
return size;
}
/*************************************************************
* FontIsLinked
@ -4813,6 +4898,12 @@ BOOL WineEngGetLinkedHFont(DC *dc, WCHAR c, HFONT *new_hfont, UINT *glyph)
return FALSE;
}
DWORD WineEngGetFontUnicodeRanges(HDC hdc, LPGLYPHSET glyphset)
{
FIXME("(%p, %p): stub\n", hdc, glyphset);
return 0;
}
BOOL WINAPI FontIsLinked(HDC hdc)
{
return FALSE;

View File

@ -423,6 +423,7 @@ extern BOOL WineEngGetCharABCWidthsI(GdiFont *font, UINT firstChar,
UINT count, LPWORD pgi, LPABC buffer);
extern BOOL WineEngGetCharWidth(GdiFont*, UINT, UINT, LPINT);
extern DWORD WineEngGetFontData(GdiFont*, DWORD, DWORD, LPVOID, DWORD);
extern DWORD WineEngGetFontUnicodeRanges(HDC, LPGLYPHSET);
extern DWORD WineEngGetGlyphIndices(GdiFont *font, LPCWSTR lpstr, INT count,
LPWORD pgi, DWORD flags);
extern DWORD WineEngGetGlyphOutline(GdiFont*, UINT glyph, UINT format,

View File

@ -1088,6 +1088,43 @@ static void test_font_charset(void)
skip("Symbol or Wingdings is not installed\n");
}
static void test_GetFontUnicodeRanges(void)
{
LOGFONTA lf;
HDC hdc;
HFONT hfont, hfont_old;
DWORD size, i;
GLYPHSET *gs;
memset(&lf, 0, sizeof(lf));
lstrcpyA(lf.lfFaceName, "Arial");
hfont = create_font("Arial", &lf);
hdc = GetDC(0);
hfont_old = SelectObject(hdc, hfont);
size = GetFontUnicodeRanges(NULL, NULL);
ok(!size, "GetFontUnicodeRanges succeeded unexpectedly\n");
size = GetFontUnicodeRanges(hdc, NULL);
ok(size, "GetFontUnicodeRanges failed unexpectedly\n");
gs = HeapAlloc(GetProcessHeap(), 0, size);
size = GetFontUnicodeRanges(hdc, gs);
ok(size, "GetFontUnicodeRanges failed\n");
for (i = 0; i < gs->cRanges; i++)
trace("%03d wcLow %04x cGlyphs %u\n", i, gs->ranges[i].wcLow, gs->ranges[i].cGlyphs);
trace("found %u ranges\n", gs->cRanges);
HeapFree(GetProcessHeap(), 0, gs);
SelectObject(hdc, hfont_old);
DeleteObject(hfont);
ReleaseDC(NULL, hdc);
}
START_TEST(font)
{
test_logfont();
@ -1101,4 +1138,5 @@ START_TEST(font)
test_GetOutlineTextMetrics();
test_SetTextJustification();
test_font_charset();
test_GetFontUnicodeRanges();
}