gdi32: Implement WineEngGetCharABCWidthsFloat and forward GetCharABCWidthsFloat to it.

Hans Leidekker hans at codeweavers.com
Fri Dec 11 04:38:24 CST 2009


Fixes http://bugs.winehq.org/show_bug.cgi?id=18120
---
 dlls/gdi32/font.c        |   40 +++++++++++++++++++++++-----------------
 dlls/gdi32/freetype.c    |   32 ++++++++++++++++++++++++++++++++
 dlls/gdi32/gdi_private.h |    2 ++
 3 files changed, 57 insertions(+), 17 deletions(-)

diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 7f8f6f6..eea53fd 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -2908,34 +2908,40 @@ BOOL WINAPI GetCharABCWidthsFloatA( HDC hdc, UINT first, UINT last, LPABCFLOAT a
  * RETURNS
  *    Success: TRUE
  *    Failure: FALSE
- *
- * BUGS
- *    Only works with TrueType fonts. It also doesn't return real
- *    floats but converted integers because it's implemented on
- *    top of GetCharABCWidthsW.
  */
 BOOL WINAPI GetCharABCWidthsFloatW( HDC hdc, UINT first, UINT last, LPABCFLOAT abcf )
 {
-    ABC *abc, *abc_base;
-    unsigned int i, size = sizeof(ABC) * (last - first + 1);
-    BOOL ret;
+    UINT i;
+    BOOL ret = FALSE;
+    DC *dc = get_dc_ptr( hdc );
+
+    TRACE("%p, %d, %d, %p\n", hdc, first, last, abcf);
+
+    if (!dc) return FALSE;
 
-    TRACE("%p, %d, %d, %p - partial stub\n", hdc, first, last, abcf);
+    if (!abcf)
+    {
+        release_dc_ptr( dc );
+        return FALSE;
+    }
 
-    abc = abc_base = HeapAlloc( GetProcessHeap(), 0, size );
-    if (!abc) return FALSE;
+    if (dc->gdiFont)
+        ret = WineEngGetCharABCWidthsFloat( dc->gdiFont, first, last, abcf );
+    else
+        FIXME("stub\n");
 
-    ret = GetCharABCWidthsW( hdc, first, last, abc );
     if (ret)
     {
-        for (i = first; i <= last; i++, abc++, abcf++)
+        /* convert device units to logical */
+        for (i = first; i <= last; i++, abcf++)
         {
-            abcf->abcfA = abc->abcA;
-            abcf->abcfB = abc->abcB;
-            abcf->abcfC = abc->abcC;
+            abcf->abcfA = abcf->abcfA * dc->xformVport2World.eM11;
+            abcf->abcfB = abcf->abcfB * dc->xformVport2World.eM11;
+            abcf->abcfC = abcf->abcfC * dc->xformVport2World.eM11;
         }
     }
-    HeapFree( GetProcessHeap(), 0, abc_base );
+
+    release_dc_ptr( dc );
     return ret;
 }
 
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index ed37a25..9e6555c 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -5913,6 +5913,38 @@ BOOL WineEngGetCharABCWidths(GdiFont *font, UINT firstChar, UINT lastChar,
 }
 
 /*************************************************************
+ * WineEngGetCharABCWidthsFloat
+ *
+ */
+BOOL WineEngGetCharABCWidthsFloat(GdiFont *font, UINT first, UINT last, LPABCFLOAT buffer)
+{
+    static const MAT2 identity = {{0,1}, {0,0}, {0,0}, {0,1}};
+    UINT c;
+    GLYPHMETRICS gm;
+    FT_UInt glyph_index;
+    GdiFont *linked_font;
+
+    TRACE("%p, %d, %d, %p\n", font, first, last, buffer);
+
+    GDI_CheckNotLock();
+    EnterCriticalSection( &freetype_cs );
+
+    for (c = first; c <= last; c++)
+    {
+        get_glyph_index_linked(font, c, &linked_font, &glyph_index);
+        WineEngGetGlyphOutline(linked_font, glyph_index, GGO_METRICS | GGO_GLYPH_INDEX,
+                               &gm, 0, NULL, &identity);
+        buffer[c - first].abcfA = FONT_GM(linked_font, glyph_index)->lsb;
+        buffer[c - first].abcfB = FONT_GM(linked_font, glyph_index)->bbx;
+        buffer[c - first].abcfC = FONT_GM(linked_font, glyph_index)->adv -
+                                  FONT_GM(linked_font, glyph_index)->lsb -
+                                  FONT_GM(linked_font, glyph_index)->bbx;
+    }
+    LeaveCriticalSection( &freetype_cs );
+    return TRUE;
+}
+
+/*************************************************************
  * WineEngGetCharABCWidthsI
  *
  */
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index 670ef41..d5f9112 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -412,6 +412,8 @@ extern BOOL WineEngDestroyFontInstance(HFONT handle) DECLSPEC_HIDDEN;
 extern DWORD WineEngEnumFonts(LPLOGFONTW, FONTENUMPROCW, LPARAM) DECLSPEC_HIDDEN;
 extern BOOL WineEngGetCharABCWidths(GdiFont *font, UINT firstChar,
                                     UINT lastChar, LPABC buffer) DECLSPEC_HIDDEN;
+extern BOOL WineEngGetCharABCWidthsFloat(GdiFont *font, UINT firstChar,
+                                         UINT lastChar, LPABCFLOAT buffer) DECLSPEC_HIDDEN;
 extern BOOL WineEngGetCharABCWidthsI(GdiFont *font, UINT firstChar,
                                     UINT count, LPWORD pgi, LPABC buffer) DECLSPEC_HIDDEN;
 extern BOOL WineEngGetCharWidth(GdiFont*, UINT, UINT, LPINT) DECLSPEC_HIDDEN;
-- 
1.6.3.3




More information about the wine-patches mailing list