diff options
Diffstat (limited to 'src/gui/text/qfontengine_ft.cpp')
-rw-r--r-- | src/gui/text/qfontengine_ft.cpp | 173 |
1 files changed, 99 insertions, 74 deletions
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 112dda0d75..de6da88245 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -320,8 +320,9 @@ void QFreetypeFace::release(const QFontEngine::FaceId &face_id) cleanup(); - if (freetypeData->faces.contains(face_id)) - freetypeData->faces.take(face_id); + auto it = freetypeData->faces.constFind(face_id); + if (it != freetypeData->faces.constEnd()) + freetypeData->faces.erase(it); if (freetypeData->faces.isEmpty()) { FT_Done_FreeType(freetypeData->library); @@ -414,6 +415,7 @@ QFontEngine::Properties QFreetypeFace::properties() const p.italicAngle = 0; p.capHeight = p.ascent; p.lineWidth = face->underline_thickness; + return p; } @@ -585,8 +587,7 @@ static void convertRGBToARGB_helper(const uchar *src, uint *dst, int width, int uchar green = src[x + 1]; uchar blue = src[x + 1 + offs]; LcdFilter::filterPixel(red, green, blue); - // alpha = green - *dd++ = (green << 24) | (red << 16) | (green << 8) | blue; + *dd++ = (0xFF << 24) | (red << 16) | (green << 8) | blue; } dst += width; src += src_pitch; @@ -611,8 +612,7 @@ static void convertRGBToARGB_V_helper(const uchar *src, uint *dst, int width, in uchar green = src[x + src_pitch]; uchar blue = src[x + src_pitch + offs]; LcdFilter::filterPixel(red, green, blue); - // alpha = green - *dst++ = (green << 24) | (red << 16) | (green << 8) | blue; + *dst++ = (0XFF << 24) | (red << 16) | (green << 8) | blue; } src += 3*src_pitch; } @@ -782,8 +782,14 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format, FT_Select_Size(face, i); if (face->size->metrics.ascender + face->size->metrics.descender > 0) { + FT_Pos leading = metrics.height - metrics.ascender + metrics.descender; metrics.ascender = face->size->metrics.ascender; metrics.descender = face->size->metrics.descender; + if (metrics.descender > 0 + && QString::fromUtf8(face->family_name) == QLatin1String("Courier New")) { + metrics.descender *= -1; + } + metrics.height = metrics.ascender - metrics.descender + leading; } FT_Set_Char_Size(face, xsize, ysize, 0, 0); @@ -883,10 +889,47 @@ static inline bool areMetricsTooLarge(const QFontEngineFT::GlyphInfo &info) || (uchar)(info.height) != info.height; } +static inline void transformBoundingBox(int *left, int *top, int *right, int *bottom, FT_Matrix *matrix) +{ + int l, r, t, b; + FT_Vector vector; + vector.x = *left; + vector.y = *top; + FT_Vector_Transform(&vector, matrix); + l = r = vector.x; + t = b = vector.y; + vector.x = *right; + vector.y = *top; + FT_Vector_Transform(&vector, matrix); + if (l > vector.x) l = vector.x; + if (r < vector.x) r = vector.x; + if (t < vector.y) t = vector.y; + if (b > vector.y) b = vector.y; + vector.x = *right; + vector.y = *bottom; + FT_Vector_Transform(&vector, matrix); + if (l > vector.x) l = vector.x; + if (r < vector.x) r = vector.x; + if (t < vector.y) t = vector.y; + if (b > vector.y) b = vector.y; + vector.x = *left; + vector.y = *bottom; + FT_Vector_Transform(&vector, matrix); + if (l > vector.x) l = vector.x; + if (r < vector.x) r = vector.x; + if (t < vector.y) t = vector.y; + if (b > vector.y) b = vector.y; + *left = l; + *right = r; + *top = t; + *bottom = b; +} + QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, QFixed subPixelPosition, GlyphFormat format, - bool fetchMetricsOnly) const + bool fetchMetricsOnly, + bool disableOutlineDrawing) const { // Q_ASSERT(freetype->lock == 1); @@ -971,11 +1014,20 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, info.xOff = TRUNC(ROUND(slot->advance.x)); info.yOff = 0; - if ((set && set->outline_drawing) || fetchMetricsOnly) { - int left = FLOOR(slot->metrics.horiBearingX); - int right = CEIL(slot->metrics.horiBearingX + slot->metrics.width); - int top = CEIL(slot->metrics.horiBearingY); - int bottom = FLOOR(slot->metrics.horiBearingY - slot->metrics.height); + if ((set && set->outline_drawing && !disableOutlineDrawing) || fetchMetricsOnly) { + int left = slot->metrics.horiBearingX; + int right = slot->metrics.horiBearingX + slot->metrics.width; + int top = slot->metrics.horiBearingY; + int bottom = slot->metrics.horiBearingY - slot->metrics.height; + + if (transform && slot->format != FT_GLYPH_FORMAT_BITMAP) + transformBoundingBox(&left, &top, &right, &bottom, &matrix); + + left = FLOOR(left); + right = CEIL(right); + bottom = FLOOR(bottom); + top = CEIL(top); + info.x = TRUNC(left); info.y = TRUNC(top); info.width = TRUNC(right - left); @@ -1038,40 +1090,8 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, int right = slot->metrics.horiBearingX + slot->metrics.width; int top = slot->metrics.horiBearingY; int bottom = slot->metrics.horiBearingY - slot->metrics.height; - if(transform && slot->format != FT_GLYPH_FORMAT_BITMAP) { - int l, r, t, b; - FT_Vector vector; - vector.x = left; - vector.y = top; - FT_Vector_Transform(&vector, &matrix); - l = r = vector.x; - t = b = vector.y; - vector.x = right; - vector.y = top; - FT_Vector_Transform(&vector, &matrix); - if (l > vector.x) l = vector.x; - if (r < vector.x) r = vector.x; - if (t < vector.y) t = vector.y; - if (b > vector.y) b = vector.y; - vector.x = right; - vector.y = bottom; - FT_Vector_Transform(&vector, &matrix); - if (l > vector.x) l = vector.x; - if (r < vector.x) r = vector.x; - if (t < vector.y) t = vector.y; - if (b > vector.y) b = vector.y; - vector.x = left; - vector.y = bottom; - FT_Vector_Transform(&vector, &matrix); - if (l > vector.x) l = vector.x; - if (r < vector.x) r = vector.x; - if (t < vector.y) t = vector.y; - if (b > vector.y) b = vector.y; - left = l; - right = r; - top = t; - bottom = b; - } + if (transform && slot->format != FT_GLYPH_FORMAT_BITMAP) + transformBoundingBox(&left, &top, &right, &bottom, &matrix); left = FLOOR(left); right = CEIL(right); bottom = FLOOR(bottom); @@ -1299,6 +1319,18 @@ QFixed QFontEngineFT::ascent() const return v; } +QFixed QFontEngineFT::capHeight() const +{ + TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2); + if (os2 && os2->version >= 2) { + lockFace(); + QFixed answer = QFixed::fromFixed(FT_MulFix(os2->sCapHeight, freetype->face->size->metrics.y_scale)); + unlockFace(); + return answer; + } + return calculatedCapHeight(); +} + QFixed QFontEngineFT::descent() const { QFixed v = QFixed::fromFixed(-metrics.descender); @@ -1317,33 +1349,25 @@ QFixed QFontEngineFT::leading() const QFixed QFontEngineFT::xHeight() const { - if (!isScalableBitmap()) { - TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2); - if (os2 && os2->sxHeight) { - lockFace(); - QFixed answer = QFixed(os2->sxHeight * freetype->face->size->metrics.y_ppem) / emSquareSize(); - unlockFace(); - return answer; - } - } else { - return QFixed(freetype->face->size->metrics.y_ppem) * scalableBitmapScaleFactor; + TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2); + if (os2 && os2->sxHeight) { + lockFace(); + QFixed answer = QFixed(os2->sxHeight * freetype->face->size->metrics.y_ppem) / emSquareSize(); + unlockFace(); + return answer; } + return QFontEngine::xHeight(); } QFixed QFontEngineFT::averageCharWidth() const { - if (!isScalableBitmap()) { - TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2); - if (os2 && os2->xAvgCharWidth) { - lockFace(); - QFixed answer = QFixed(os2->xAvgCharWidth * freetype->face->size->metrics.x_ppem) / emSquareSize(); - unlockFace(); - return answer; - } - } else { - const qreal aspectRatio = (qreal)xsize / ysize; - return QFixed::fromReal(fontDef.pixelSize * aspectRatio); + TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2); + if (os2 && os2->xAvgCharWidth) { + lockFace(); + QFixed answer = QFixed(os2->xAvgCharWidth * freetype->face->size->metrics.x_ppem) / emSquareSize(); + unlockFace(); + return answer; } return QFontEngine::averageCharWidth(); @@ -1842,7 +1866,7 @@ static inline QImage alphaMapFromGlyphData(QFontEngineFT::Glyph *glyph, QFontEng bytesPerLine = (glyph->width + 3) & ~3; break; case QFontEngine::Format_A32: - format = QImage::Format_ARGB32; + format = QImage::Format_RGB32; bytesPerLine = glyph->width * 4; break; default: @@ -1908,10 +1932,11 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format, const QTransform &t, - bool fetchBoundingBox) + bool fetchBoundingBox, + bool disableOutlineDrawing) { QGlyphSet *glyphSet = loadGlyphSet(t); - if (glyphSet != 0 && glyphSet->outline_drawing && !fetchBoundingBox) + if (glyphSet != 0 && glyphSet->outline_drawing && !disableOutlineDrawing && !fetchBoundingBox) return 0; Glyph *glyph = glyphSet != 0 ? glyphSet->getGlyph(g, subPixelPosition) : 0; @@ -1925,7 +1950,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g, FT_Matrix ftMatrix = glyphSet != 0 ? glyphSet->transformationMatrix : QTransformToFTMatrix(t); FT_Matrix_Multiply(&ftMatrix, &m); freetype->matrix = m; - glyph = loadGlyph(glyphSet, g, subPixelPosition, format, false); + glyph = loadGlyph(glyphSet, g, subPixelPosition, format, false, disableOutlineDrawing); unlockFace(); } @@ -1941,7 +1966,7 @@ QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition, const { const GlyphFormat neededFormat = antialias ? Format_A8 : Format_Mono; - Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t); + Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t, false, true); QImage img = alphaMapFromGlyphData(glyph, neededFormat); img = img.copy(); @@ -1952,7 +1977,7 @@ QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition, const if (!img.isNull()) return img; - return QFontEngine::alphaMapForGlyph(g); + return QFontEngine::alphaMapForGlyph(g, subPixelPosition, t); } QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t) @@ -1962,7 +1987,7 @@ QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, co const GlyphFormat neededFormat = Format_A32; - Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t); + Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t, false, true); QImage img = alphaMapFromGlyphData(glyph, neededFormat); img = img.copy(); |