[Wine-patches] [eterhack] gdi32: Fix problems with "Symbol type A" font (eterbug #2609).
Alexander Morozov
amorozov на etersoft.ru
Пт Июл 31 20:14:39 MSD 2009
----------- следующая часть -----------
From 9e2212922d1bec8c65ad56591e5c347d44e86e39 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Fri, 31 Jul 2009 19:47:46 +0400
Subject: [eterhack] gdi32: Fix problems with "Symbol type A" font (eterbug #2609).
---
dlls/gdi32/freetype.c | 128 +++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 107 insertions(+), 21 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index a4a2068..0a3194a 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -4487,19 +4487,36 @@ static FT_UInt get_GSUB_vert_glyph(const GdiFont *font, UINT glyph)
static FT_UInt get_glyph_index(const GdiFont *font, UINT glyph)
{
- FT_UInt glyphId;
+ FT_UInt glyphId = 0;
- if(font->ft_face->charmap->encoding == FT_ENCODING_NONE) {
+ if(font->ft_face->charmap->encoding == FT_ENCODING_MS_SYMBOL)
+ {
+ if(glyph < 0x100)
+ glyphId = pFT_Get_Char_Index(font->ft_face, glyph + 0xf000);
+ if(glyph >= 0xf020 && glyph < 0xf100)
+ glyphId = pFT_Get_Char_Index(font->ft_face, glyph - 0xf000);
+ if(glyphId)
+ return get_GSUB_vert_glyph(font,glyphId);
+ }
+
+ if(font->ft_face->charmap->encoding == FT_ENCODING_NONE ||
+ font->ft_face->charmap->encoding == FT_ENCODING_MS_SYMBOL)
+ {
WCHAR wc = (WCHAR)glyph;
BOOL default_used;
BOOL *default_used_pointer;
FT_UInt ret;
char buf;
+ UINT codepage;
default_used_pointer = NULL;
default_used = FALSE;
if (codepage_sets_default_used(font->codepage))
default_used_pointer = &default_used;
- if(!WideCharToMultiByte(font->codepage, 0, &wc, 1, &buf, sizeof(buf), NULL, default_used_pointer) || default_used)
+ if (font->ft_face->charmap->encoding == FT_ENCODING_MS_SYMBOL)
+ codepage = CP_ACP;
+ else
+ codepage = font->codepage;
+ if(!WideCharToMultiByte(codepage, 0, &wc, 1, &buf, sizeof(buf), NULL, default_used_pointer) || default_used)
ret = 0;
else
ret = pFT_Get_Char_Index(font->ft_face, (unsigned char)buf);
@@ -4507,8 +4524,6 @@ static FT_UInt get_glyph_index(const GdiFont *font, UINT glyph)
return get_GSUB_vert_glyph(font,ret);
}
- if(font->ft_face->charmap->encoding == FT_ENCODING_MS_SYMBOL && glyph < 0x100)
- glyph = glyph + 0xf000;
glyphId = pFT_Get_Char_Index(font->ft_face, glyph);
return get_GSUB_vert_glyph(font,glyphId);
}
@@ -6135,6 +6150,31 @@ BOOL WineEngGetLinkedHFont(DC *dc, WCHAR c, HFONT *new_hfont, UINT *glyph)
LeaveCriticalSection( &freetype_cs );
return ret;
}
+
+int cmp_wchar(const void *w1, const void *w2)
+{
+ return *(WCHAR *)w1 - *(WCHAR *)w2;
+}
+
+void add_glyph(GLYPHSET *gs, FT_ULong char_code, FT_ULong char_code_prev,
+ DWORD *num_ranges)
+{
+ 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++;
+ }
+}
/* Retrieve a list of supported Unicode ranges for a given font.
* Can be called with NULL gs to calculate the buffer size. Returns
@@ -6144,7 +6184,9 @@ 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)
+ if (!pFT_Get_First_Char) return 0;
+
+ if (face->charmap->encoding == FT_ENCODING_UNICODE)
{
FT_UInt glyph_code;
FT_ULong char_code, char_code_prev;
@@ -6172,25 +6214,69 @@ static DWORD get_font_unicode_ranges(FT_Face face, GLYPHSET *gs)
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++;
- }
+ add_glyph(gs, char_code, char_code_prev, &num_ranges);
char_code_prev = char_code;
char_code = pFT_Get_Next_Char(face, char_code, &glyph_code);
}
}
+ else if (face->charmap->encoding == FT_ENCODING_MS_SYMBOL)
+ {
+ FT_UInt glyph_code = 0;
+ FT_ULong char_code, prev_char, cur_char;
+ ULONG p;
+ WCHAR wchars[0x1e0];
+ unsigned char chars[0x100];
+
+ char_code = pFT_Get_First_Char(face, &glyph_code);
+
+ TRACE("face encoding FT_ENCODING_MS_SYMBOL, number of glyphs %ld, first glyph %u, first char %04lx\n",
+ face->num_glyphs, glyph_code, char_code);
+
+ if (!glyph_code) return 0;
+
+ for (p = 0; p < 0x100; ++p) chars[p] = p;
+ MultiByteToWideChar(CP_ACP, 0, (LPSTR)chars, 0x100, wchars, 0x100);
+ MultiByteToWideChar(CP_SYMBOL, 0, (LPSTR)chars + 0x20, 0xe0, wchars + 0x100, 0xe0);
+ qsort(wchars, 0x1e0, sizeof(WCHAR), cmp_wchar);
+
+ while (glyph_code && char_code < 0x100)
+ char_code = pFT_Get_Next_Char(face, char_code, &glyph_code);
+
+ if (wchars[0] <= char_code || !glyph_code)
+ {
+ cur_char = wchars[0];
+ p = 1;
+ }
+ else
+ {
+ cur_char = char_code;
+ p = 0;
+ }
+ prev_char = cur_char;
+ if (gs)
+ {
+ gs->ranges[0].wcLow = cur_char;
+ gs->ranges[0].cGlyphs = 0;
+ gs->cGlyphsSupported = 0;
+ }
+ num_ranges = 1;
+ while (glyph_code || p <= 0x1e0)
+ {
+ if (cur_char < prev_char)
+ {
+ ERR("expected increasing char code\n");
+ return 0;
+ }
+ add_glyph(gs, cur_char, prev_char, &num_ranges);
+ prev_char = cur_char;
+ if (cur_char == char_code)
+ char_code = pFT_Get_Next_Char(face, char_code, &glyph_code);
+ if ((p < 0x1e0 && wchars[p] <= char_code) || !glyph_code)
+ cur_char = wchars[p++];
+ else
+ cur_char = char_code;
+ }
+ }
else
FIXME("encoding %u not supported\n", face->charmap->encoding);
--
1.6.3.3
Подробная информация о списке рассылки Wine-patches