summaryrefslogtreecommitdiffstats
path: root/src/gui/text/qfontengine_ft.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/text/qfontengine_ft.cpp')
-rw-r--r--src/gui/text/qfontengine_ft.cpp173
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();