Aric Stewart : gdi32: Allocate our glyph metrics in a 128 index chunk sparse array.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Aug 30 13:50:23 CDT 2007


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

Author: Aric Stewart <aric at codeweavers.com>
Date:   Thu Aug 30 19:17:23 2007 +0900

gdi32: Allocate our glyph metrics in a 128 index chunk sparse array.

---

 dlls/gdi32/freetype.c |   69 +++++++++++++++++++++++++++----------------------
 1 files changed, 38 insertions(+), 31 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 27955b3..9881f00 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -298,7 +298,7 @@ struct tagGdiFont {
     BYTE underline;
     BYTE strikeout;
     INT orientation;
-    GM *gm;
+    GM **gm;
     DWORD gmsize;
     struct list hfontlist;
     FONT_DESC font_desc;
@@ -320,7 +320,8 @@ typedef struct {
     struct list links;
 } SYSTEM_LINKS;
 
-#define INIT_GM_SIZE 128
+#define GM_BLOCK_SIZE 128
+#define FONT_GM(font,idx) (&(font)->gm[(idx) / GM_BLOCK_SIZE][(idx) % GM_BLOCK_SIZE])
 
 static struct list gdi_font_list = LIST_INIT(gdi_font_list);
 static struct list unused_gdi_font_list = LIST_INIT(unused_gdi_font_list);
@@ -2329,9 +2330,9 @@ static int get_nearest_charset(Face *face, int *cp)
 static GdiFont *alloc_font(void)
 {
     GdiFont *ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret));
-    ret->gmsize = INIT_GM_SIZE;
-    ret->gm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-			ret->gmsize * sizeof(*ret->gm));
+    ret->gmsize = 1;
+    ret->gm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GM*));
+    ret->gm[0] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GM) * GM_BLOCK_SIZE);
     ret->potm = NULL;
     ret->font_desc.matrix.eM11 = ret->font_desc.matrix.eM22 = 1.0;
     ret->total_kern_pairs = (DWORD)-1;
@@ -2344,6 +2345,7 @@ static GdiFont *alloc_font(void)
 static void free_font(GdiFont *font)
 {
     struct list *cursor, *cursor2;
+    int i;
 
     LIST_FOR_EACH_SAFE(cursor, cursor2, &font->child_fonts)
     {
@@ -2368,6 +2370,8 @@ static void free_font(GdiFont *font)
     HeapFree(GetProcessHeap(), 0, font->kern_pairs);
     HeapFree(GetProcessHeap(), 0, font->potm);
     HeapFree(GetProcessHeap(), 0, font->name);
+    for (i = 0; i < font->gmsize; i++)
+        HeapFree(GetProcessHeap(),0,font->gm[i]);
     HeapFree(GetProcessHeap(), 0, font->gm);
     HeapFree(GetProcessHeap(), 0, font);
 }
@@ -3381,17 +3385,20 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
         ft_face = font->ft_face;
     }
 
-    if(glyph_index >= font->gmsize) {
-        font->gmsize = (glyph_index / INIT_GM_SIZE + 1) * INIT_GM_SIZE;
+    if(glyph_index >= font->gmsize * GM_BLOCK_SIZE) {
+	font->gmsize = (glyph_index / GM_BLOCK_SIZE + 1);
 	font->gm = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, font->gm,
-			       font->gmsize * sizeof(*font->gm));
+			       font->gmsize * sizeof(GM*));
     } else {
-        if(format == GGO_METRICS && font->gm[glyph_index].init) {
-	    memcpy(lpgm, &font->gm[glyph_index].gm, sizeof(*lpgm));
+        if(format == GGO_METRICS && font->gm[glyph_index / GM_BLOCK_SIZE] != NULL && FONT_GM(font,glyph_index)->init ) {
+            *lpgm = FONT_GM(font,glyph_index)->gm;
 	    return 1; /* FIXME */
 	}
     }
 
+    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) || font->aveWidth || lpmat)
         load_flags |= FT_LOAD_NO_BITMAP;
 
@@ -3410,9 +3417,9 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
     left = (INT)(ft_face->glyph->metrics.horiBearingX * widthRatio) & -64;
     right = (INT)((ft_face->glyph->metrics.horiBearingX + ft_face->glyph->metrics.width) * widthRatio + 63) & -64;
 
-    font->gm[glyph_index].adv = (INT)((ft_face->glyph->metrics.horiAdvance * widthRatio) + 63) >> 6;
-    font->gm[glyph_index].lsb = left >> 6;
-    font->gm[glyph_index].bbx = (right - left) >> 6;
+    FONT_GM(font,glyph_index)->adv = (INT)((ft_face->glyph->metrics.horiAdvance * widthRatio) + 63) >> 6;
+    FONT_GM(font,glyph_index)->lsb = left >> 6;
+    FONT_GM(font,glyph_index)->bbx = (right - left) >> 6;
 
     /* Scaling transform */
     if(font->aveWidth) {
@@ -3468,7 +3475,7 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
 	top = (ft_face->glyph->metrics.horiBearingY + 63) & -64;
 	bottom = (ft_face->glyph->metrics.horiBearingY -
 		  ft_face->glyph->metrics.height) & -64;
-	lpgm->gmCellIncX = font->gm[glyph_index].adv;
+	lpgm->gmCellIncX = FONT_GM(font,glyph_index)->adv;
 	lpgm->gmCellIncY = 0;
     } else {
         INT xc, yc;
@@ -3509,8 +3516,8 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
     lpgm->gmptGlyphOrigin.x = left >> 6;
     lpgm->gmptGlyphOrigin.y = top >> 6;
 
-    memcpy(&font->gm[glyph_index].gm, lpgm, sizeof(*lpgm));
-    font->gm[glyph_index].init = TRUE;
+    FONT_GM(font,glyph_index)->gm = *lpgm;
+    FONT_GM(font,glyph_index)->init = TRUE;
 
     if(format == GGO_METRICS)
         return 1; /* FIXME */
@@ -4222,7 +4229,7 @@ BOOL WineEngGetCharWidth(GdiFont *font, UINT firstChar, UINT lastChar,
         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] = linked_font->gm[glyph_index].adv;
+	buffer[c - firstChar] = FONT_GM(linked_font,glyph_index)->adv;
     }
     return TRUE;
 }
@@ -4248,10 +4255,10 @@ BOOL WineEngGetCharABCWidths(GdiFont *font, UINT firstChar, UINT lastChar,
         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 = 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;
+	buffer[c - firstChar].abcA = FONT_GM(linked_font,glyph_index)->lsb;
+	buffer[c - firstChar].abcB = FONT_GM(linked_font,glyph_index)->bbx;
+	buffer[c - firstChar].abcC = FONT_GM(linked_font,glyph_index)->adv - FONT_GM(linked_font,glyph_index)->lsb -
+            FONT_GM(linked_font,glyph_index)->bbx;
     }
     return TRUE;
 }
@@ -4276,19 +4283,19 @@ BOOL WineEngGetCharABCWidthsI(GdiFont *font, UINT firstChar, UINT count, LPWORD
         for(c = firstChar; c < firstChar+count; c++) {
             WineEngGetGlyphOutline(linked_font, c, GGO_METRICS | GGO_GLYPH_INDEX,
                                    &gm, 0, NULL, NULL);
-            buffer[c - firstChar].abcA = linked_font->gm[c].lsb;
-            buffer[c - firstChar].abcB = linked_font->gm[c].bbx;
-            buffer[c - firstChar].abcC = linked_font->gm[c].adv - linked_font->gm[c].lsb 
-               - linked_font->gm[c].bbx;
+            buffer[c - firstChar].abcA = FONT_GM(linked_font,c)->lsb;
+            buffer[c - firstChar].abcB = FONT_GM(linked_font,c)->bbx;
+            buffer[c - firstChar].abcC = FONT_GM(linked_font,c)->adv - FONT_GM(linked_font,c)->lsb
+                - FONT_GM(linked_font,c)->bbx;
         }
     else
         for(c = 0; c < count; c++) {
             WineEngGetGlyphOutline(linked_font, pgi[c], GGO_METRICS | GGO_GLYPH_INDEX,
                                    &gm, 0, NULL, NULL);
-            buffer[c].abcA = linked_font->gm[pgi[c]].lsb;
-            buffer[c].abcB = linked_font->gm[pgi[c]].bbx;
-            buffer[c].abcC = linked_font->gm[pgi[c]].adv 
-               - linked_font->gm[pgi[c]].lsb - linked_font->gm[pgi[c]].bbx;
+            buffer[c].abcA = FONT_GM(linked_font,pgi[c])->lsb;
+            buffer[c].abcB = FONT_GM(linked_font,pgi[c])->bbx;
+            buffer[c].abcC = FONT_GM(linked_font,pgi[c])->adv
+                - FONT_GM(linked_font,pgi[c])->lsb - FONT_GM(linked_font,pgi[c])->bbx;
         }
 
     return TRUE;
@@ -4319,7 +4326,7 @@ BOOL WineEngGetTextExtentExPoint(GdiFont *font, LPCWSTR wstr, INT count,
         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 += linked_font->gm[glyph_index].adv;
+	size->cx += FONT_GM(linked_font,glyph_index)->adv;
         ext = size->cx;
         if (! pnfit || ext <= max_ext) {
             ++nfit;
@@ -4356,7 +4363,7 @@ BOOL WineEngGetTextExtentPointI(GdiFont *font, const WORD *indices, INT count,
         WineEngGetGlyphOutline(font, indices[idx],
 			       GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, NULL,
 			       NULL);
-	size->cx += font->gm[indices[idx]].adv;
+	size->cx += FONT_GM(font,indices[idx])->adv;
     }
     TRACE("return %d,%d\n", size->cx, size->cy);
     return TRUE;




More information about the wine-cvs mailing list