gdi32: Add support for emulating bold faces of bitmap fonts.
Dmitry Timoshkov
dmitry at baikal.ru
Mon Apr 16 02:37:39 CDT 2012
---
dlls/gdi32/freetype.c | 28 ++++++++++++++++++++++++++-
dlls/gdi32/tests/font.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 75 insertions(+), 1 deletion(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 0a5d3c3..eb3f9b5 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -5669,12 +5669,27 @@ static inline BYTE get_max_level( UINT format )
return 255;
}
-static const BYTE masks[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
+static void emulate_bold_glyph(BYTE *buf, int pitch, int height)
+{
+ int x, y;
+ BYTE *p = buf;
+
+ for (y = 0; y < height; y++)
+ {
+ for (x = pitch - 1; x >= 0; x--)
+ {
+ p[x] |= p[x] >> 1;
+ if (x > 0) p[x] |= p[x - 1] << 7;
+ }
+ p += pitch;
+ }
+}
static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
LPGLYPHMETRICS lpgm, DWORD buflen, LPVOID buf,
const MAT2* lpmat)
{
+ static const BYTE masks[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
static const FT_Matrix identityMat = {(1 << 16), 0, 0, (1 << 16)};
FT_Face ft_face = incoming_font->ft_face;
GdiFont *font = incoming_font;
@@ -5917,6 +5932,9 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
return GDI_ERROR;
}
+ if (font->fake_bold && !FT_IS_SCALABLE(ft_face) && ft_face->glyph->format == ft_glyph_format_bitmap)
+ emulate_bold_glyph(ft_face->glyph->bitmap.buffer, ft_face->glyph->bitmap.pitch, ft_face->glyph->bitmap.rows);
+
switch(format) {
case GGO_BITMAP:
width = lpgm->gmBlackBoxX;
@@ -6425,6 +6443,14 @@ static BOOL get_bitmap_text_metrics(GdiFont *font)
TM.tmPitchAndFamily = ft_face->face_flags & FT_FACE_FLAG_FIXED_WIDTH ? 0 : TMPF_FIXED_PITCH;
TM.tmCharSet = font->charset;
}
+ if (font->fake_bold && TM.tmWeight == FW_NORMAL)
+ {
+ TM.tmWeight = FW_BOLD;
+ TM.tmAveCharWidth++;
+ TM.tmMaxCharWidth++;
+ TM.tmOverhang++;
+ if (font->aveWidth) font->aveWidth++; /* avoid metrics rescaling */
+ }
#undef TM
return TRUE;
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index 9bd5f1c..c330b33 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -957,6 +957,7 @@ static void test_bitmap_font_metrics(void)
that make the max width bigger */
if(strcmp(lf.lfFaceName, "System") || lf.lfCharSet != ANSI_CHARSET)
ok(tm.tmMaxCharWidth == fd[i].max_char_width, "%s(%d): tm.tmMaxCharWidth %d != %d\n", fd[i].face_name, height, tm.tmMaxCharWidth, fd[i].max_char_width);
+ ok(tm.tmOverhang == 0, "%s(%d): tm.tmOverhang %d != 0\n", fd[i].face_name, height, tm.tmOverhang);
}
else
skip("Skipping font metrics test for system langid 0x%x\n",
@@ -964,6 +965,53 @@ static void test_bitmap_font_metrics(void)
}
SelectObject(hdc, old_hfont);
DeleteObject(hfont);
+
+ lf.lfWeight = FW_BOLD;
+ hfont = create_font(lf.lfFaceName, &lf);
+ old_hfont = SelectObject(hdc, hfont);
+ bRet = GetTextMetrics(hdc, &tm);
+ ok(bRet, "GetTextMetrics error %d\n", GetLastError());
+ if (fd[i].dpi == tm.tmDigitizedAspectX)
+ {
+ trace("matched %s, height %d charset %x dpi %d\n", lf.lfFaceName, lf.lfHeight, lf.lfCharSet, fd[i].dpi);
+ if (fd[i].skip_lang_id == 0 || system_lang_id != fd[i].skip_lang_id)
+ {
+ if (fd[i].weight == FW_NORMAL)
+ ok(tm.tmWeight == FW_BOLD, "%s(%d): tm.tmWeight %d != FW_BOLD\n", fd[i].face_name, height, tm.tmWeight);
+ else
+ ok(tm.tmWeight == fd[i].weight, "%s(%d): tm.tmWeight %d != %d\n", fd[i].face_name, height, tm.tmWeight, fd[i].weight);
+ if (fd[i].height & FH_SCALE)
+ ok(tm.tmHeight == fd[i].scaled_height, "%s(%d): tm.tmHeight %d != %d\n", fd[i].face_name, height, tm.tmHeight, fd[i].scaled_height);
+ else
+ ok(tm.tmHeight == fd[i].height, "%s(%d): tm.tmHeight %d != %d\n", fd[i].face_name, fd[i].height, tm.tmHeight, fd[i].height);
+ ok(tm.tmAscent == fd[i].ascent, "%s(%d): tm.tmAscent %d != %d\n", fd[i].face_name, height, tm.tmAscent, fd[i].ascent);
+ ok(tm.tmDescent == fd[i].descent, "%s(%d): tm.tmDescent %d != %d\n", fd[i].face_name, height, tm.tmDescent, fd[i].descent);
+ ok(tm.tmInternalLeading == fd[i].int_leading, "%s(%d): tm.tmInternalLeading %d != %d\n", fd[i].face_name, height, tm.tmInternalLeading, fd[i].int_leading);
+ ok(tm.tmExternalLeading == fd[i].ext_leading, "%s(%d): tm.tmExternalLeading %d != %d\n", fd[i].face_name, height, tm.tmExternalLeading, fd[i].ext_leading);
+ if (fd[i].weight == FW_NORMAL)
+ {
+ ok(tm.tmAveCharWidth == fd[i].ave_char_width + 1, "%s(%d): tm.tmAveCharWidth %d != %d\n", fd[i].face_name, height, tm.tmAveCharWidth, fd[i].ave_char_width + 1);
+ /* Don't run the max char width test on System/ANSI_CHARSET. We have extra characters in our font
+ that make the max width bigger */
+ if (strcmp(lf.lfFaceName, "System") || lf.lfCharSet != ANSI_CHARSET)
+ ok(tm.tmMaxCharWidth == fd[i].max_char_width + 1, "%s(%d): tm.tmMaxCharWidth %d != %d\n", fd[i].face_name, height, tm.tmMaxCharWidth, fd[i].max_char_width + 1);
+ ok(tm.tmOverhang == 1, "%s(%d): tm.tmOverhang %d != 1\n", fd[i].face_name, height, tm.tmOverhang);
+ }
+ else
+ {
+ ok(tm.tmAveCharWidth == fd[i].ave_char_width, "%s(%d): tm.tmAveCharWidth %d != %d\n", fd[i].face_name, height, tm.tmAveCharWidth, fd[i].ave_char_width);
+ /* Don't run the max char width test on System/ANSI_CHARSET. We have extra characters in our font
+ that make the max width bigger */
+ if (strcmp(lf.lfFaceName, "System") || lf.lfCharSet != ANSI_CHARSET)
+ ok(tm.tmMaxCharWidth == fd[i].max_char_width, "%s(%d): tm.tmMaxCharWidth %d != %d\n", fd[i].face_name, height, tm.tmMaxCharWidth, fd[i].max_char_width);
+ ok(tm.tmOverhang == 0, "%s(%d): tm.tmOverhang %d != 0\n", fd[i].face_name, height, tm.tmOverhang);
+ }
+ }
+ else
+ skip("Skipping font metrics test for system langid 0x%x\n", system_lang_id);
+ }
+ SelectObject(hdc, old_hfont);
+ DeleteObject(hfont);
}
}
--
1.7.9.4
More information about the wine-patches
mailing list