summaryrefslogtreecommitdiffstats
path: root/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp')
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp21
1 files changed, 16 insertions, 5 deletions
diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
index c9fe129d4e..52ce36b0e3 100644
--- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
+++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
@@ -750,13 +750,16 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
// fake bold
if ((fontDef.weight >= QFont::Bold) && !(face->style_flags & FT_STYLE_FLAG_BOLD) && !FT_IS_FIXED_WIDTH(face) && !qEnvironmentVariableIsSet("QT_NO_SYNTHESIZED_BOLD")) {
if (const TT_OS2 *os2 = reinterpret_cast<const TT_OS2 *>(FT_Get_Sfnt_Table(face, ft_sfnt_os2))) {
- if (os2->usWeightClass < 700 && fontDef.pixelSize < 64)
+ if (os2->usWeightClass < 700 &&
+ (fontDef.pixelSize < 64 || qEnvironmentVariableIsSet("QT_NO_SYNTHESIZED_BOLD_LIMIT"))) {
embolden = true;
+ }
}
}
// underline metrics
line_thickness = QFixed::fromFixed(FT_MulFix(face->underline_thickness, face->size->metrics.y_scale));
- underline_position = QFixed::fromFixed(-FT_MulFix(face->underline_position, face->size->metrics.y_scale));
+ QFixed center_position = QFixed::fromFixed(-FT_MulFix(face->underline_position, face->size->metrics.y_scale));
+ underline_position = center_position - line_thickness / 2;
} else {
// ad hoc algorithm
int score = fontDef.weight * fontDef.pixelSize;
@@ -903,7 +906,7 @@ int QFontEngineFT::loadFlags(QGlyphSet *set, GlyphFormat format, int flags,
static inline bool areMetricsTooLarge(const QFontEngineFT::GlyphInfo &info)
{
// false if exceeds QFontEngineFT::Glyph metrics
- return info.width > 0xFF || info.height > 0xFF;
+ return info.width > 0xFF || info.height > 0xFF || info.linearAdvance > 0x7FFF;
}
static inline void transformBoundingBox(int *left, int *top, int *right, int *bottom, FT_Matrix *matrix)
@@ -1051,6 +1054,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
info.height = TRUNC(top - bottom);
// If any of the metrics are too large to fit, don't cache them
+ // Also, avoid integer overflow when linearAdvance is to large to fit in a signed short
if (areMetricsTooLarge(info))
return nullptr;
@@ -1078,7 +1082,11 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
renderMode = FT_RENDER_MODE_MONO;
break;
case Format_A32:
- Q_ASSERT(hsubpixel || vfactor != 1);
+ if (!hsubpixel && vfactor == 1) {
+ qWarning("Format_A32 requested, but subpixel layout is unknown.");
+ return nullptr;
+ }
+
renderMode = hsubpixel ? FT_RENDER_MODE_LCD : FT_RENDER_MODE_LCD_V;
break;
case Format_A8:
@@ -1777,7 +1785,10 @@ glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph, const QTransform &matr
glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixelPosition, const QTransform &matrix, QFontEngine::GlyphFormat format)
{
- Glyph *g = loadGlyphFor(glyph, subPixelPosition, format, matrix, true);
+ // When rendering glyphs into a cache via the alphaMap* functions, we disable
+ // outline drawing. To ensure the bounding box matches the rendered glyph, we
+ // need to do the same here.
+ Glyph *g = loadGlyphFor(glyph, subPixelPosition, format, matrix, true, true);
glyph_metrics_t overall;
if (g) {