fonts: linking #6

Huw D M Davies h.davies1 at physics.ox.ac.uk
Wed Sep 7 09:03:37 CDT 2005


        Huw Davies <huw at codeweavers.com>
        Have ExtTextOut call into the font linking mechanism.
        GetCharWidth, GetCharABCWidths and GetTextExtentPoint should
        return the widths of a linked font's glyphs.
-- 
Huw Davies
huw at codeweavers.com
Index: dlls/gdi/font.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/font.c,v
retrieving revision 1.15
diff -u -p -r1.15 font.c
--- dlls/gdi/font.c	23 Aug 2005 09:38:59 -0000	1.15
+++ dlls/gdi/font.c	7 Sep 2005 13:57:49 -0000
@@ -1795,12 +1795,6 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x,
 
     if(flags & ETO_GLYPH_INDEX)
         glyphs = (const WORD*)reordered_str;
-    else if(dc->gdiFont)
-    {
-        glyphs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR));
-        GetGlyphIndicesW(hdc, reordered_str, count, (WORD*)glyphs, 0);
-        flags |= ETO_GLYPH_INDEX;
-    }
 
     if(lprect)
         TRACE("rect: %ld,%ld - %ld,%ld\n", lprect->left, lprect->top, lprect->right,
@@ -1891,7 +1885,7 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x,
                 deltas[i] = tmpsz.cx;
             }
             
-            if (dc->breakExtra && reordered_str[i] == tm.tmBreakChar)
+            if (!(flags & ETO_GLYPH_INDEX) && dc->breakExtra && reordered_str[i] == tm.tmBreakChar)
             {
                 deltas[i] = deltas[i] + dc->breakExtra;
             }
@@ -1979,8 +1973,74 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x,
         }
     }
 
-    ret = dc->funcs->pExtTextOut(dc->physDev, x, y, (flags & ~ETO_OPAQUE), &rc,
-                                 (flags & ETO_GLYPH_INDEX) ? glyphs: reordered_str, count, deltas);
+    if(FontIsLinked(hdc) && !(flags & ETO_GLYPH_INDEX))
+    {
+        HFONT orig_font = dc->hFont, cur_font;
+        UINT glyph;
+        WORD *glyphs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WORD));
+        INT span = 0, *offsets = NULL, i;
+
+        for(i = 0; i < count; i++)
+        {
+            WineEngGetLinkedHFont(dc, reordered_str[i], &cur_font, &glyph);
+            if(cur_font != dc->hFont)
+            {
+                if(!offsets)
+                {
+                    int j;
+                    offsets = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*deltas));
+                    offsets[0] = 0;
+                    if(!deltas)
+                    {
+                        SIZE tmpsz;
+                        for(j = 1; j < count; j++)
+                        {
+                            GetTextExtentPointW(hdc, reordered_str + j - 1, 1, &tmpsz);
+                            offsets[j] = offsets[j-1] + INTERNAL_XWSTODS(dc, tmpsz.cx);
+                        }
+                    }
+                    else
+                    {
+                        for(j = 1; j < count; j++)
+                            offsets[j] = offsets[j-1] + deltas[j];
+                    }
+                }
+                if(span)
+                {
+                    dc->funcs->pExtTextOut(dc->physDev, x + offsets[i - span] * cosEsc, y - offsets[i - span] * sinEsc,
+                                           (flags & ~ETO_OPAQUE) | ETO_GLYPH_INDEX, &rc,
+                                           glyphs, span, deltas ? deltas + i - span : NULL);
+                    span = 0;
+                }
+                SelectObject(hdc, cur_font);
+            }
+            glyphs[span++] = glyph;
+
+            if(i == count - 1)
+            {
+                ret = dc->funcs->pExtTextOut(dc->physDev, x + (offsets ? offsets[count - span] * cosEsc : 0),
+                                             y - (offsets ? offsets[count - span] * sinEsc : 0),
+                                             (flags & ~ETO_OPAQUE) | ETO_GLYPH_INDEX, &rc,
+                                             glyphs, span, deltas ? deltas + count - span : NULL);
+                SelectObject(hdc, orig_font);
+                HeapFree(GetProcessHeap(), 0, glyphs); 
+                HeapFree(GetProcessHeap(), 0, offsets);
+           }
+        }
+    }
+    else
+    {
+        WORD *glyphs = NULL;
+        if(!(flags & ETO_GLYPH_INDEX) && dc->gdiFont)
+        {
+            glyphs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WORD));
+            GetGlyphIndicesW(hdc, reordered_str, count, glyphs, 0);
+            flags |= ETO_GLYPH_INDEX;
+        }
+        ret = dc->funcs->pExtTextOut(dc->physDev, x, y, (flags & ~ETO_OPAQUE), &rc,
+                                     (flags & ETO_GLYPH_INDEX) ? glyphs: reordered_str, count, deltas);
+        HeapFree(GetProcessHeap(), 0, glyphs);
+    }
 
     if (lf.lfUnderline || lf.lfStrikeOut)
     {
@@ -2045,8 +2105,6 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x,
 
 done:
     HeapFree(GetProcessHeap(), 0, deltas);
-    if(glyphs && glyphs != reordered_str)
-        HeapFree(GetProcessHeap(), 0, (WORD*)glyphs);
     if(reordered_str != str)
         HeapFree(GetProcessHeap(), 0, reordered_str);
 
Index: dlls/gdi/freetype.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/freetype.c,v
retrieving revision 1.97
diff -u -p -r1.97 freetype.c
--- dlls/gdi/freetype.c	7 Sep 2005 13:26:49 -0000	1.97
+++ dlls/gdi/freetype.c	7 Sep 2005 13:57:49 -0000
@@ -3346,14 +3346,15 @@ BOOL WineEngGetCharWidth(GdiFont font, U
     UINT c;
     GLYPHMETRICS gm;
     FT_UInt glyph_index;
+    GdiFont linked_font;
 
     TRACE("%p, %d, %d, %p\n", font, firstChar, lastChar, buffer);
 
     for(c = firstChar; c <= lastChar; c++) {
-        glyph_index = get_glyph_index(font, c);
-        WineEngGetGlyphOutline(font, glyph_index, GGO_METRICS | GGO_GLYPH_INDEX,
+        get_glyph_index_linked(font, c, &linked_font, &glyph_index);
+        WineEngGetGlyphOutline(linked_font, glyph_index, GGO_METRICS | GGO_GLYPH_INDEX,
                                &gm, 0, NULL, NULL);
-	buffer[c - firstChar] = font->gm[glyph_index].adv;
+	buffer[c - firstChar] = linked_font->gm[glyph_index].adv;
     }
     return TRUE;
 }
@@ -3368,6 +3369,7 @@ BOOL WineEngGetCharABCWidths(GdiFont fon
     UINT c;
     GLYPHMETRICS gm;
     FT_UInt glyph_index;
+    GdiFont linked_font;
 
     TRACE("%p, %d, %d, %p\n", font, firstChar, lastChar, buffer);
 
@@ -3375,13 +3377,13 @@ BOOL WineEngGetCharABCWidths(GdiFont fon
         return FALSE;
 
     for(c = firstChar; c <= lastChar; c++) {
-        glyph_index = get_glyph_index(font, c);
-        WineEngGetGlyphOutline(font, glyph_index, GGO_METRICS | GGO_GLYPH_INDEX,
+        get_glyph_index_linked(font, c, &linked_font, &glyph_index);
+        WineEngGetGlyphOutline(linked_font, glyph_index, GGO_METRICS | GGO_GLYPH_INDEX,
                                &gm, 0, NULL, NULL);
-	buffer[c - firstChar].abcA = font->gm[glyph_index].lsb;
-	buffer[c - firstChar].abcB = font->gm[glyph_index].bbx;
-	buffer[c - firstChar].abcC = font->gm[glyph_index].adv - font->gm[glyph_index].lsb -
-	  font->gm[glyph_index].bbx;
+	buffer[c - firstChar].abcA = linked_font->gm[glyph_index].lsb;
+	buffer[c - firstChar].abcB = linked_font->gm[glyph_index].bbx;
+	buffer[c - firstChar].abcC = linked_font->gm[glyph_index].adv - linked_font->gm[glyph_index].lsb -
+	  linked_font->gm[glyph_index].bbx;
     }
     return TRUE;
 }
@@ -3397,6 +3399,7 @@ BOOL WineEngGetTextExtentPoint(GdiFont f
     GLYPHMETRICS gm;
     TEXTMETRICW tm;
     FT_UInt glyph_index;
+    GdiFont linked_font;
 
     TRACE("%p, %s, %d, %p\n", font, debugstr_wn(wstr, count), count,
 	  size);
@@ -3406,10 +3409,10 @@ BOOL WineEngGetTextExtentPoint(GdiFont f
     size->cy = tm.tmHeight;
 
     for(idx = 0; idx < count; idx++) {
-	glyph_index = get_glyph_index(font, wstr[idx]);
-        WineEngGetGlyphOutline(font, glyph_index, GGO_METRICS | GGO_GLYPH_INDEX,
+        get_glyph_index_linked(font, wstr[idx], &linked_font, &glyph_index);
+        WineEngGetGlyphOutline(linked_font, glyph_index, GGO_METRICS | GGO_GLYPH_INDEX,
                                &gm, 0, NULL, NULL);
-	size->cx += font->gm[glyph_index].adv;
+	size->cx += linked_font->gm[glyph_index].adv;
     }
     TRACE("return %ld,%ld\n", size->cx, size->cy);
     return TRUE;



More information about the wine-patches mailing list