gdi32: Allocate our glyph metrics in a 128 index chunk sparse array.
This commit is contained in:
parent
79326157f9
commit
80cc1af347
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue