gdi32: Add support for scaling font metrics.
This commit is contained in:
parent
29a0b3622c
commit
535053b927
|
@ -319,7 +319,8 @@ struct tagGdiFont {
|
|||
DWORD gmsize;
|
||||
struct list hfontlist;
|
||||
FONT_DESC font_desc;
|
||||
LONG aveWidth;
|
||||
LONG aveWidth, ppem;
|
||||
float scale_x, scale_y;
|
||||
SHORT yMax;
|
||||
SHORT yMin;
|
||||
OUTLINETEXTMETRICW *potm;
|
||||
|
@ -329,7 +330,6 @@ struct tagGdiFont {
|
|||
FONTSIGNATURE fs;
|
||||
GdiFont *base_font;
|
||||
struct list child_fonts;
|
||||
LONG ppem;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
@ -2439,7 +2439,6 @@ static FT_Face OpenFontFace(GdiFont *font, Face *face, LONG width, LONG height)
|
|||
if((err = pFT_Set_Pixel_Sizes(ft_face, 0, font->ppem)) != 0)
|
||||
WARN("FT_Set_Pixel_Sizes %d, %d rets %x\n", 0, font->ppem, err);
|
||||
} else {
|
||||
font->ppem = height;
|
||||
if((err = pFT_Set_Pixel_Sizes(ft_face, width, height)) != 0)
|
||||
WARN("FT_Set_Pixel_Sizes %d, %d rets %x\n", width, height, err);
|
||||
}
|
||||
|
@ -3126,6 +3125,12 @@ found:
|
|||
TRACE("Chosen: %s %s (%s/%p:%ld)\n", debugstr_w(family->FamilyName),
|
||||
debugstr_w(face->StyleName), face->file, face->font_data_ptr, face->face_index);
|
||||
|
||||
ret->ppem = height;
|
||||
ret->aveWidth = abs(lf.lfWidth);
|
||||
|
||||
ret->scale_x = 0.0;
|
||||
ret->scale_y = 0.0;
|
||||
|
||||
if(!face->scalable) {
|
||||
width = face->size.x_ppem >> 6;
|
||||
height = face->size.y_ppem >> 6;
|
||||
|
@ -3159,7 +3164,6 @@ found:
|
|||
|
||||
TRACE("caching: gdiFont=%p hfont=%p\n", ret, hfont);
|
||||
|
||||
ret->aveWidth = FT_IS_SCALABLE(ret->ft_face) ? abs(lf.lfWidth) : 0;
|
||||
list_add_head(&gdi_font_list, &ret->entry);
|
||||
return ret;
|
||||
}
|
||||
|
@ -3594,7 +3598,7 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
|
|||
INT left, right, top = 0, bottom = 0, adv, lsb, bbx;
|
||||
FT_Angle angle = 0;
|
||||
FT_Int load_flags = FT_LOAD_DEFAULT | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
|
||||
float widthRatio = 1.0;
|
||||
float widthRatio = 1.0, heightRatio = 1.0;
|
||||
FT_Matrix transMat = identityMat;
|
||||
BOOL needsTransform = FALSE;
|
||||
|
||||
|
@ -3624,7 +3628,7 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
|
|||
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 && format != WINE_GGO_GRAY16_BITMAP) || font->aveWidth || lpmat)
|
||||
if(font->orientation || (format != GGO_METRICS && format != GGO_BITMAP && format != WINE_GGO_GRAY16_BITMAP) || lpmat)
|
||||
load_flags |= FT_LOAD_NO_BITMAP;
|
||||
|
||||
err = pFT_Load_Glyph(ft_face, glyph_index, load_flags);
|
||||
|
@ -3635,8 +3639,10 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
|
|||
}
|
||||
|
||||
/* Scaling factor */
|
||||
if (font->aveWidth && font->potm) {
|
||||
widthRatio = (float)font->aveWidth * font->font_desc.matrix.eM11 / (float) font->potm->otmTextMetrics.tmAveCharWidth;
|
||||
if (font->scale_x != 0.0)
|
||||
{
|
||||
widthRatio = font->scale_x;
|
||||
heightRatio = font->scale_y;
|
||||
}
|
||||
|
||||
left = (INT)(ft_face->glyph->metrics.horiBearingX * widthRatio) & -64;
|
||||
|
@ -3652,7 +3658,7 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
|
|||
scaleMat.xx = FT_FixedFromFloat(widthRatio);
|
||||
scaleMat.xy = 0;
|
||||
scaleMat.yx = 0;
|
||||
scaleMat.yy = (1 << 16);
|
||||
scaleMat.yy = FT_FixedFromFloat(heightRatio);
|
||||
|
||||
pFT_Matrix_Multiply(&scaleMat, &transMat);
|
||||
needsTransform = TRUE;
|
||||
|
@ -4130,6 +4136,39 @@ static BOOL get_bitmap_text_metrics(GdiFont *font)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void scale_font_metrics(GdiFont *font, LPTEXTMETRICW ptm)
|
||||
{
|
||||
if (font->scale_x == 0.0)
|
||||
{
|
||||
if (FT_IS_SCALABLE(font->ft_face) || !font->ppem)
|
||||
font->scale_y = 1.0;
|
||||
else
|
||||
{
|
||||
font->scale_y = (float)font->ppem * font->font_desc.matrix.eM22;
|
||||
font->scale_y /= (float)font->potm->otmTextMetrics.tmHeight;
|
||||
}
|
||||
|
||||
if (font->aveWidth)
|
||||
{
|
||||
font->scale_x = (float)font->aveWidth * font->font_desc.matrix.eM11;
|
||||
font->scale_x /= (float)font->potm->otmTextMetrics.tmAveCharWidth;
|
||||
}
|
||||
else
|
||||
font->scale_x = font->scale_y;
|
||||
|
||||
TRACE("font scale x: %f y: %f\n", font->scale_x, font->scale_y);
|
||||
}
|
||||
ptm->tmHeight = (float)ptm->tmHeight * font->scale_y;
|
||||
ptm->tmAscent = (float)ptm->tmAscent * font->scale_y;
|
||||
ptm->tmDescent = (float)ptm->tmDescent * font->scale_y;
|
||||
ptm->tmInternalLeading = (float)ptm->tmInternalLeading * font->scale_y;
|
||||
ptm->tmExternalLeading = (float)ptm->tmExternalLeading * font->scale_y;
|
||||
|
||||
ptm->tmAveCharWidth = (float)ptm->tmAveCharWidth * font->scale_x;
|
||||
ptm->tmMaxCharWidth = (float)ptm->tmMaxCharWidth * font->scale_x;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* WineEngGetTextMetrics
|
||||
*
|
||||
|
@ -4143,10 +4182,8 @@ BOOL WineEngGetTextMetrics(GdiFont *font, LPTEXTMETRICW ptm)
|
|||
}
|
||||
if(!font->potm) return FALSE;
|
||||
memcpy(ptm, &font->potm->otmTextMetrics, sizeof(*ptm));
|
||||
scale_font_metrics(font, ptm);
|
||||
|
||||
if (font->aveWidth) {
|
||||
ptm->tmAveCharWidth = font->aveWidth * font->font_desc.matrix.eM11;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -4176,7 +4213,10 @@ UINT WineEngGetOutlineTextMetrics(GdiFont *font, UINT cbSize,
|
|||
|
||||
if(font->potm) {
|
||||
if(cbSize >= font->potm->otmSize)
|
||||
{
|
||||
memcpy(potm, font->potm, font->potm->otmSize);
|
||||
scale_font_metrics(font, &potm->otmTextMetrics);
|
||||
}
|
||||
return font->potm->otmSize;
|
||||
}
|
||||
|
||||
|
@ -4404,7 +4444,10 @@ UINT WineEngGetOutlineTextMetrics(GdiFont *font, UINT cbSize,
|
|||
ret = needed;
|
||||
|
||||
if(potm && needed <= cbSize)
|
||||
{
|
||||
memcpy(potm, font->potm, font->potm->otmSize);
|
||||
scale_font_metrics(font, &potm->otmTextMetrics);
|
||||
}
|
||||
|
||||
end:
|
||||
HeapFree(GetProcessHeap(), 0, style_nameW);
|
||||
|
|
|
@ -244,20 +244,14 @@ static void test_bitmap_font(void)
|
|||
bitmap_lf.lfHeight = height_orig * 2;
|
||||
bitmap_lf.lfWidth *= 3;
|
||||
hfont = create_font("3x2", &bitmap_lf);
|
||||
todo_wine
|
||||
{
|
||||
test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 2);
|
||||
}
|
||||
DeleteObject(hfont);
|
||||
|
||||
/* test integer scaling 3x3 */
|
||||
bitmap_lf.lfHeight = height_orig * 3;
|
||||
bitmap_lf.lfWidth = 0;
|
||||
hfont = create_font("3x3", &bitmap_lf);
|
||||
todo_wine
|
||||
{
|
||||
test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 3);
|
||||
}
|
||||
DeleteObject(hfont);
|
||||
|
||||
ReleaseDC(0, hdc);
|
||||
|
|
Loading…
Reference in New Issue