Aric Stewart : gdi32: Fix up glyph metrics for tategaki glyphs.

Alexandre Julliard julliard at winehq.org
Tue May 28 15:16:59 CDT 2013


Module: wine
Branch: master
Commit: 72f584aef879fbabc7544d3848337b6bdf7e0787
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=72f584aef879fbabc7544d3848337b6bdf7e0787

Author: Aric Stewart <aric at codeweavers.com>
Date:   Fri May 24 11:00:41 2013 -0500

gdi32: Fix up glyph metrics for tategaki glyphs.

---

 dlls/gdi32/freetype.c |   57 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 459f49a..bf4e4c3 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -5918,6 +5918,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
     FT_Bitmap ft_bitmap;
     FT_Error err;
     INT left, right, top = 0, bottom = 0, adv;
+    INT origin_x = 0, origin_y = 0;
     FT_Angle angle = 0;
     FT_Int load_flags = FT_LOAD_DEFAULT | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
     double widthRatio = 1.0;
@@ -5926,6 +5927,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
     FT_Matrix transMatTategaki;
     BOOL needsTransform = FALSE;
     BOOL tategaki = (font->name[0] == '@');
+    BOOL vertical_metrics;
     UINT original_index;
     LONG avgAdvance = 0;
     FT_Fixed em_scale;
@@ -6084,7 +6086,14 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
         needsTransform = TRUE;
     }
 
+    vertical_metrics = (tategaki && FT_HAS_VERTICAL(ft_face));
+    /* there is a freetype bug where vertical metrics are only
+       properly scaled and correct in 2.4.0 or greater */
+    if ((vertical_metrics) && (FT_Version.major < 2 || (FT_Version.major == 2 && FT_Version.minor < 4)))
+        vertical_metrics = FALSE;
+
     if (needsTransform || format != GGO_BITMAP) load_flags |= FT_LOAD_NO_BITMAP;
+    if (vertical_metrics) load_flags |= FT_LOAD_VERTICAL_LAYOUT;
 
     err = pFT_Load_Glyph(ft_face, glyph_index, load_flags);
 
@@ -6135,6 +6144,8 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
 	bottom = (metrics.horiBearingY - metrics.height) & -64;
 	lpgm->gmCellIncX = adv;
 	lpgm->gmCellIncY = 0;
+        origin_x = left;
+        origin_y = top;
     } else {
         INT xc, yc;
 	FT_Vector vec;
@@ -6163,6 +6174,43 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
 	bottom = bottom & -64;
 	top = (top + 63) & -64;
 
+        if (tategaki)
+        {
+            for(xc = 0; xc < 2; xc++)
+            {
+                for(yc = 0; yc < 2; yc++)
+                {
+                    if (vertical_metrics)
+                    {
+                        vec.x = metrics.vertBearingY + xc * metrics.height;
+                        vec.y = metrics.horiBearingX - yc * (metrics.vertBearingX * 2);
+                    }
+                    else
+                    {
+                        vec.x = metrics.horiBearingY - xc * metrics.height;
+                        vec.y = metrics.horiBearingX + yc * metrics.width;
+                    }
+
+                    TRACE ("Vec %ld,%ld\n", vec.x>>6, vec.y>>6);
+                    pFT_Vector_Transform(&vec, &transMat);
+                    if(xc == 0 && yc == 0) {
+                        origin_x = vec.x;
+                        origin_y = vec.y;
+                    } else {
+                        if(vec.x < origin_x) origin_x = vec.x;
+                        if(vec.y > origin_y) origin_y = vec.y;
+                    }
+                }
+            }
+            origin_x = origin_x & -64;
+            origin_y = (origin_y + 63) & -64;
+        }
+        else
+        {
+            origin_x = left;
+            origin_y = top;
+        }
+
 	TRACE("transformed box: (%d,%d - %d,%d)\n", left, top, right, bottom);
 	vec.x = metrics.horiAdvance;
 	vec.y = 0;
@@ -6177,7 +6225,10 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
 	    lpgm->gmCellIncX = pFT_MulFix(vec.x, em_scale) * 2;
 	}
 
-        vec.x = metrics.horiAdvance;
+        if (vertical_metrics)
+            vec.x = metrics.vertAdvance;
+        else
+            vec.x = metrics.horiAdvance;
         vec.y = 0;
         pFT_Vector_Transform(&vec, &transMatUnrotated);
         if (!avgAdvance || vec.y)
@@ -6192,8 +6243,8 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
 
     lpgm->gmBlackBoxX = (right - left) >> 6;
     lpgm->gmBlackBoxY = (top - bottom) >> 6;
-    lpgm->gmptGlyphOrigin.x = left >> 6;
-    lpgm->gmptGlyphOrigin.y = top >> 6;
+    lpgm->gmptGlyphOrigin.x = origin_x >> 6;
+    lpgm->gmptGlyphOrigin.y = origin_y >> 6;
     abc->abcA = left >> 6;
     abc->abcB = (right - left) >> 6;
     abc->abcC = adv - abc->abcA - abc->abcB;




More information about the wine-cvs mailing list