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