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

This commit is contained in:
Aric Stewart 2007-08-30 19:17:23 +09:00 committed by Alexandre Julliard
parent 79326157f9
commit 80cc1af347
1 changed files with 38 additions and 31 deletions

View File

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