From ceb81eee206918e95ce13ab823fa3c57d86078fe Mon Sep 17 00:00:00 2001 From: Aric Stewart Date: Tue, 4 Jun 2013 09:05:50 -0500 Subject: [PATCH] gdi32: Turn off tategaki if the unicode code point is outside of the rotated ranges. --- dlls/gdi32/freetype.c | 74 +++++++++++++++++++++++++++++++++++++++++++------ dlls/gdi32/tests/font.c | 2 +- 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index bf4e4c3f6c7..f884307d150 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -537,7 +537,7 @@ static const WCHAR font_mutex_nameW[] = {'_','_','W','I','N','E','_','F','O','N' static const WCHAR szDefaultFallbackLink[] = {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0}; static BOOL use_default_fallback = FALSE; -static BOOL get_glyph_index_linked(GdiFont *font, UINT c, GdiFont **linked_font, FT_UInt *glyph); +static BOOL get_glyph_index_linked(GdiFont *font, UINT c, GdiFont **linked_font, FT_UInt *glyph, BOOL *vert); static BOOL get_outline_text_metrics(GdiFont *font); static BOOL get_bitmap_text_metrics(GdiFont *font); static BOOL get_text_metrics(GdiFont *font, LPTEXTMETRICW ptm); @@ -585,7 +585,6 @@ static const WCHAR internal_system_link[] = {'S','o','f','t','w','a','r','e','\\ /* These are all structures needed for the GSUB table */ #define GSUB_TAG MS_MAKE_TAG('G', 'S', 'U', 'B') -#define TATEGAKI_LOWER_BOUND 0x02F1 typedef struct { DWORD version; @@ -5903,6 +5902,55 @@ static inline BYTE get_max_level( UINT format ) return 255; } +static const struct { WCHAR lower; WCHAR upper;} unrotate_ranges[] = + { + {0x0000, 0x10FF}, + /* Hangul Jamo */ + {0x1200, 0x17FF}, + /* Mongolian */ + {0x18B0, 0x1FFF}, + /* General Punctuation */ + {0x2070, 0x209F}, + /* Currency Symbols */ + /* Combining Diacritical Marks for Symbols */ + /* Letterlike Symbols */ + {0x2150, 0x245F}, + /* Enclosed Alphanumerics */ + {0x2500, 0x259F}, + /* Geometric Shapes */ + /* Miscellaneous Symbols */ + /* Dingbats */ + /* Miscellaneous Mathematical Symbols-A */ + /* Supplemental Arrows-A */ + {0x2800, 0x2E7F}, + /* East Asian scripts and symbols */ + {0xA000, 0xABFF}, + /* Hangul Syllables */ + /* Hangul Jamo Extended-B */ + {0xD800, 0xF8FF}, + /* CJK Compatibility Ideographs */ + {0xFB00, 0xFE0F}, + /* Vertical Forms */ + /* Combining Half Marks */ + /* CJK Compatibility Forms */ + {0xFE50, 0xFEFF}, + /* Halfwidth and Fullwidth Forms */ + {0xFFEF, 0xFFFF}, + }; + +static BOOL check_unicode_tategaki(WCHAR uchar) +{ + int i; + for (i = 0 ;; i++) + { + if (uchar < unrotate_ranges[i].lower) + return TRUE; + + if (uchar >= unrotate_ranges[i].lower && uchar <= unrotate_ranges[i].upper) + return FALSE; + } +} + static const BYTE masks[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, @@ -5943,10 +5991,17 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, glyph_index = glyph; original_index = glyph; format &= ~GGO_GLYPH_INDEX; + /* TODO: Window also turns off tategaki for glyphs passed in by index + if their unicode code points fall outside of the range that is + rotated. */ } else { - get_glyph_index_linked(incoming_font, glyph, &font, &glyph_index); + BOOL vert; + get_glyph_index_linked(incoming_font, glyph, &font, &glyph_index, &vert); ft_face = font->ft_face; original_index = glyph_index; + /* We know what unicode ranges get rotated */ + if (!vert && tategaki) + tategaki = check_unicode_tategaki(glyph); } if(format & GGO_UNHINTED) { @@ -5954,10 +6009,6 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, format &= ~GGO_UNHINTED; } - /* tategaki never appears to happen to lower glyph index */ - if (glyph_index < TATEGAKI_LOWER_BOUND ) - tategaki = FALSE; - if(original_index >= font->gmsize * GM_BLOCK_SIZE) { font->gmsize = (original_index / GM_BLOCK_SIZE + 1); font->gm = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, font->gm, @@ -7348,9 +7399,9 @@ static BOOL load_child_font(GdiFont *font, CHILD_FONT *child) return TRUE; } -static BOOL get_glyph_index_linked(GdiFont *font, UINT c, GdiFont **linked_font, FT_UInt *glyph) +static BOOL get_glyph_index_linked(GdiFont *font, UINT c, GdiFont **linked_font, FT_UInt *glyph, BOOL* vert) { - FT_UInt g; + FT_UInt g,o; CHILD_FONT *child_font; if(font->base_font) @@ -7360,7 +7411,9 @@ static BOOL get_glyph_index_linked(GdiFont *font, UINT c, GdiFont **linked_font, if((*glyph = get_glyph_index(font, c))) { + o = *glyph; *glyph = get_GSUB_vert_glyph(font, *glyph); + *vert = (o != *glyph); return TRUE; } @@ -7373,15 +7426,18 @@ static BOOL get_glyph_index_linked(GdiFont *font, UINT c, GdiFont **linked_font, if(!child_font->font->ft_face) continue; g = get_glyph_index(child_font->font, c); + o = g; g = get_GSUB_vert_glyph(child_font->font, g); if(g) { *glyph = g; *linked_font = child_font->font; + *vert = (o != g); return TRUE; } } *glyph = get_default_char_index(font); + *vert = FALSE; return FALSE; } diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index b57a6308e4c..087d57205a1 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -4831,7 +4831,7 @@ static void test_vertical_font(void) check_vertical_font("@WineTestVertical", &installed, &selected, &gm, &vgi); ok(installed, "@WineTestVertical is not installed\n"); ok(selected, "@WineTestVertical is not selected\n"); - todo_wine ok(gm.gmBlackBoxX > gm.gmBlackBoxY, + ok(gm.gmBlackBoxX > gm.gmBlackBoxY, "gmBlackBoxX(%u) should be less than gmBlackBoxY(%u) if vertical\n", gm.gmBlackBoxX, gm.gmBlackBoxY); -- 2.11.4.GIT