Dmitry Timoshkov : gdi32: Add support for scaling font metrics.

Alexandre Julliard julliard at winehq.org
Tue Jan 8 10:21:49 CST 2008


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

Author: Dmitry Timoshkov <dmitry at codeweavers.com>
Date:   Tue Jan  8 23:02:09 2008 +0800

gdi32: Add support for scaling font metrics.

---

 dlls/gdi32/freetype.c   |   67 ++++++++++++++++++++++++++++++++++++++--------
 dlls/gdi32/tests/font.c |    6 ----
 2 files changed, 55 insertions(+), 18 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 4d51341..480b8e5 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -319,7 +319,8 @@ struct tagGdiFont {
     DWORD gmsize;
     struct list hfontlist;
     FONT_DESC font_desc;
-    LONG aveWidth;
+    LONG aveWidth, ppem;
+    float scale_x, scale_y;
     SHORT yMax;
     SHORT yMin;
     OUTLINETEXTMETRICW *potm;
@@ -329,7 +330,6 @@ struct tagGdiFont {
     FONTSIGNATURE fs;
     GdiFont *base_font;
     struct list child_fonts;
-    LONG ppem;
 };
 
 typedef struct {
@@ -2439,7 +2439,6 @@ static FT_Face OpenFontFace(GdiFont *font, Face *face, LONG width, LONG height)
         if((err = pFT_Set_Pixel_Sizes(ft_face, 0, font->ppem)) != 0)
             WARN("FT_Set_Pixel_Sizes %d, %d rets %x\n", 0, font->ppem, err);
     } else {
-        font->ppem = height;
         if((err = pFT_Set_Pixel_Sizes(ft_face, width, height)) != 0)
             WARN("FT_Set_Pixel_Sizes %d, %d rets %x\n", width, height, err);
     }
@@ -3126,6 +3125,12 @@ found:
     TRACE("Chosen: %s %s (%s/%p:%ld)\n", debugstr_w(family->FamilyName),
 	  debugstr_w(face->StyleName), face->file, face->font_data_ptr, face->face_index);
 
+    ret->ppem = height;
+    ret->aveWidth = abs(lf.lfWidth);
+
+    ret->scale_x = 0.0;
+    ret->scale_y = 0.0;
+
     if(!face->scalable) {
         width = face->size.x_ppem >> 6;
         height = face->size.y_ppem >> 6;
@@ -3159,7 +3164,6 @@ found:
 
     TRACE("caching: gdiFont=%p  hfont=%p\n", ret, hfont);
 
-    ret->aveWidth = FT_IS_SCALABLE(ret->ft_face) ? abs(lf.lfWidth) : 0;
     list_add_head(&gdi_font_list, &ret->entry);
     return ret;
 }
@@ -3594,7 +3598,7 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
     INT left, right, top = 0, bottom = 0, adv, lsb, bbx;
     FT_Angle angle = 0;
     FT_Int load_flags = FT_LOAD_DEFAULT | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
-    float widthRatio = 1.0;
+    float widthRatio = 1.0, heightRatio = 1.0;
     FT_Matrix transMat = identityMat;
     BOOL needsTransform = FALSE;
 
@@ -3624,7 +3628,7 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
     if (!font->gm[glyph_index / GM_BLOCK_SIZE])
         font->gm[glyph_index / GM_BLOCK_SIZE] = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(GM) * GM_BLOCK_SIZE);
 
-    if(font->orientation || (format != GGO_METRICS && format != GGO_BITMAP && format != WINE_GGO_GRAY16_BITMAP) || font->aveWidth || lpmat)
+    if(font->orientation || (format != GGO_METRICS && format != GGO_BITMAP && format != WINE_GGO_GRAY16_BITMAP) || lpmat)
         load_flags |= FT_LOAD_NO_BITMAP;
 
     err = pFT_Load_Glyph(ft_face, glyph_index, load_flags);
@@ -3635,8 +3639,10 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
     }
 	
     /* Scaling factor */
-    if (font->aveWidth && font->potm) {
-        widthRatio = (float)font->aveWidth * font->font_desc.matrix.eM11 / (float) font->potm->otmTextMetrics.tmAveCharWidth;
+    if (font->scale_x != 0.0)
+    {
+        widthRatio = font->scale_x;
+        heightRatio = font->scale_y;
     }
 
     left = (INT)(ft_face->glyph->metrics.horiBearingX * widthRatio) & -64;
@@ -3652,7 +3658,7 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
         scaleMat.xx = FT_FixedFromFloat(widthRatio);
         scaleMat.xy = 0;
         scaleMat.yx = 0;
-        scaleMat.yy = (1 << 16);
+        scaleMat.yy = FT_FixedFromFloat(heightRatio);
 
         pFT_Matrix_Multiply(&scaleMat, &transMat);
         needsTransform = TRUE;
@@ -4130,6 +4136,39 @@ static BOOL get_bitmap_text_metrics(GdiFont *font)
     return TRUE;
 }
 
+
+static void scale_font_metrics(GdiFont *font, LPTEXTMETRICW ptm)
+{
+    if (font->scale_x == 0.0)
+    {
+        if (FT_IS_SCALABLE(font->ft_face) || !font->ppem)
+            font->scale_y = 1.0;
+        else
+        {
+            font->scale_y = (float)font->ppem * font->font_desc.matrix.eM22;
+            font->scale_y /= (float)font->potm->otmTextMetrics.tmHeight;
+        }
+
+        if (font->aveWidth)
+        {
+            font->scale_x = (float)font->aveWidth * font->font_desc.matrix.eM11;
+            font->scale_x /= (float)font->potm->otmTextMetrics.tmAveCharWidth;
+        }
+        else
+            font->scale_x = font->scale_y;
+
+        TRACE("font scale x: %f y: %f\n", font->scale_x, font->scale_y);
+    }
+    ptm->tmHeight = (float)ptm->tmHeight * font->scale_y;
+    ptm->tmAscent = (float)ptm->tmAscent * font->scale_y;
+    ptm->tmDescent = (float)ptm->tmDescent * font->scale_y;
+    ptm->tmInternalLeading = (float)ptm->tmInternalLeading * font->scale_y;
+    ptm->tmExternalLeading = (float)ptm->tmExternalLeading * font->scale_y;
+
+    ptm->tmAveCharWidth = (float)ptm->tmAveCharWidth * font->scale_x;
+    ptm->tmMaxCharWidth = (float)ptm->tmMaxCharWidth * font->scale_x;
+}
+
 /*************************************************************
  * WineEngGetTextMetrics
  *
@@ -4143,10 +4182,8 @@ BOOL WineEngGetTextMetrics(GdiFont *font, LPTEXTMETRICW ptm)
     }
     if(!font->potm) return FALSE;
     memcpy(ptm, &font->potm->otmTextMetrics, sizeof(*ptm));
+    scale_font_metrics(font, ptm);
 
-    if (font->aveWidth) {
-        ptm->tmAveCharWidth = font->aveWidth * font->font_desc.matrix.eM11;
-    }
     return TRUE;
 }
 
@@ -4176,7 +4213,10 @@ UINT WineEngGetOutlineTextMetrics(GdiFont *font, UINT cbSize,
 
     if(font->potm) {
         if(cbSize >= font->potm->otmSize)
+        {
 	    memcpy(potm, font->potm, font->potm->otmSize);
+            scale_font_metrics(font, &potm->otmTextMetrics);
+        }
 	return font->potm->otmSize;
     }
 
@@ -4404,7 +4444,10 @@ UINT WineEngGetOutlineTextMetrics(GdiFont *font, UINT cbSize,
     ret = needed;
 
     if(potm && needed <= cbSize)
+    {
         memcpy(potm, font->potm, font->potm->otmSize);
+        scale_font_metrics(font, &potm->otmTextMetrics);
+    }
 
 end:
     HeapFree(GetProcessHeap(), 0, style_nameW);
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index b6e8327..7d73c19 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -244,20 +244,14 @@ static void test_bitmap_font(void)
     bitmap_lf.lfHeight = height_orig * 2;
     bitmap_lf.lfWidth *= 3;
     hfont = create_font("3x2", &bitmap_lf);
-todo_wine
-{
     test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 2);
-}
     DeleteObject(hfont);
 
     /* test integer scaling 3x3 */
     bitmap_lf.lfHeight = height_orig * 3;
     bitmap_lf.lfWidth = 0;
     hfont = create_font("3x3", &bitmap_lf);
-todo_wine
-{
     test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 3);
-}
     DeleteObject(hfont);
 
     ReleaseDC(0, hdc);




More information about the wine-cvs mailing list