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.cpp84
1 files changed, 35 insertions, 49 deletions
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index b79f971156..8ae178c6ad 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -891,8 +891,6 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
FT_Matrix_Multiply(&m, &matrix);
}
- FT_Library library = qt_getFreetype();
-
info.xOff = TRUNC(ROUND(slot->advance.x));
info.yOff = 0;
@@ -930,12 +928,12 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
return g;
}
- uchar *glyph_buffer = 0;
int glyph_buffer_size = 0;
+ QScopedArrayPointer<uchar> glyph_buffer;
#if defined(QT_USE_FREETYPE_LCDFILTER)
bool useFreetypeRenderGlyph = false;
if (slot->format == FT_GLYPH_FORMAT_OUTLINE && (hsubpixel || vfactor != 1)) {
- err = FT_Library_SetLcdFilter(library, (FT_LcdFilter)lcdFilterType);
+ err = FT_Library_SetLcdFilter(slot->library, (FT_LcdFilter)lcdFilterType);
if (err == FT_Err_Ok)
useFreetypeRenderGlyph = true;
}
@@ -946,7 +944,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
if (err != FT_Err_Ok)
qWarning("render glyph failed err=%x face=%p, glyph=%d", err, face, glyph);
- FT_Library_SetLcdFilter(library, FT_LCD_FILTER_NONE);
+ FT_Library_SetLcdFilter(slot->library, FT_LCD_FILTER_NONE);
info.height = slot->bitmap.rows / vfactor;
info.width = hsubpixel ? slot->bitmap.width / 3 : slot->bitmap.width;
@@ -954,12 +952,12 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
info.y = slot->bitmap_top;
glyph_buffer_size = info.width * info.height * 4;
- glyph_buffer = new uchar[glyph_buffer_size];
+ glyph_buffer.reset(new uchar[glyph_buffer_size]);
if (hsubpixel)
- convertRGBToARGB(slot->bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_RGB, false);
+ convertRGBToARGB(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_RGB, false);
else if (vfactor != 1)
- convertRGBToARGB_V(slot->bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_VRGB, false);
+ convertRGBToARGB_V(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_VRGB, false);
} else
#endif
{
@@ -1030,26 +1028,30 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
|| ((signed char)(info.xOff) != info.xOff));
if (large_glyph) {
- delete [] glyph_buffer;
return 0;
}
int pitch = (format == Format_Mono ? ((info.width + 31) & ~31) >> 3 :
(format == Format_A8 ? (info.width + 3) & ~3 : info.width * 4));
- glyph_buffer_size = pitch * info.height;
- glyph_buffer = new uchar[glyph_buffer_size];
- memset(glyph_buffer, 0, glyph_buffer_size);
+ if (glyph_buffer_size < pitch * info.height) {
+ glyph_buffer_size = pitch * info.height;
+ glyph_buffer.reset(new uchar[glyph_buffer_size]);
+ }
+ memset(glyph_buffer.data(), 0, glyph_buffer_size);
if (slot->format == FT_GLYPH_FORMAT_OUTLINE) {
FT_Bitmap bitmap;
bitmap.rows = info.height*vfactor;
bitmap.width = hpixels;
bitmap.pitch = format == Format_Mono ? (((info.width + 31) & ~31) >> 3) : ((bitmap.width + 3) & ~3);
- if (!hsubpixel && vfactor == 1 && format != Format_A32)
- bitmap.buffer = glyph_buffer;
- else
- bitmap.buffer = new uchar[bitmap.rows*bitmap.pitch];
- memset(bitmap.buffer, 0, bitmap.rows*bitmap.pitch);
+ int bitmap_buffer_size = bitmap.rows * bitmap.pitch;
+ if (!hsubpixel && vfactor == 1 && format != Format_A32) {
+ Q_ASSERT(glyph_buffer_size <= bitmap_buffer_size);
+ bitmap.buffer = glyph_buffer.data();
+ } else {
+ bitmap.buffer = new uchar[bitmap_buffer_size];
+ memset(bitmap.buffer, 0, bitmap_buffer_size);
+ }
bitmap.pixel_mode = format == Format_Mono ? FT_PIXEL_MODE_MONO : FT_PIXEL_MODE_GRAY;
FT_Matrix matrix;
matrix.xx = (hsubpixel ? 3 : 1) << 16;
@@ -1058,11 +1060,11 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
FT_Outline_Transform(&slot->outline, &matrix);
FT_Outline_Translate (&slot->outline, (hsubpixel ? -3*left +(4<<6) : -left), -bottom*vfactor);
- FT_Outline_Get_Bitmap(library, &slot->outline, &bitmap);
+ FT_Outline_Get_Bitmap(slot->library, &slot->outline, &bitmap);
if (hsubpixel) {
Q_ASSERT (bitmap.pixel_mode == FT_PIXEL_MODE_GRAY);
Q_ASSERT(antialias);
- uchar *convoluted = new uchar[bitmap.rows*bitmap.pitch];
+ uchar *convoluted = new uchar[bitmap_buffer_size];
bool useLegacyLcdFilter = false;
#if defined(FC_LCD_FILTER) && defined(FT_LCD_FILTER_H)
useLegacyLcdFilter = (lcdFilterType == FT_LCD_FILTER_LEGACY);
@@ -1072,20 +1074,20 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
convoluteBitmap(bitmap.buffer, convoluted, bitmap.width, info.height, bitmap.pitch);
buffer = convoluted;
}
- convertRGBToARGB(buffer + 1, (uint *)glyph_buffer, info.width, info.height, bitmap.pitch, subpixelType != Subpixel_RGB, useLegacyLcdFilter);
+ convertRGBToARGB(buffer + 1, (uint *)glyph_buffer.data(), info.width, info.height, bitmap.pitch, subpixelType != Subpixel_RGB, useLegacyLcdFilter);
delete [] convoluted;
} else if (vfactor != 1) {
- convertRGBToARGB_V(bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, bitmap.pitch, subpixelType != Subpixel_VRGB, true);
+ convertRGBToARGB_V(bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, bitmap.pitch, subpixelType != Subpixel_VRGB, true);
} else if (format == Format_A32 && bitmap.pixel_mode == FT_PIXEL_MODE_GRAY) {
- convertGRAYToARGB(bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, bitmap.pitch);
+ convertGRAYToARGB(bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, bitmap.pitch);
}
- if (bitmap.buffer != glyph_buffer)
+ if (bitmap.buffer != glyph_buffer.data())
delete [] bitmap.buffer;
} else if (slot->format == FT_GLYPH_FORMAT_BITMAP) {
Q_ASSERT(slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO);
uchar *src = slot->bitmap.buffer;
- uchar *dst = glyph_buffer;
+ uchar *dst = glyph_buffer.data();
int h = slot->bitmap.rows;
if (format == Format_Mono) {
int bytes = ((info.width + 7) & ~7) >> 3;
@@ -1130,7 +1132,6 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
}
} else {
qWarning("QFontEngine: Glyph neither outline nor bitmap format=%d", slot->format);
- delete [] glyph_buffer;
return 0;
}
}
@@ -1149,7 +1150,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
g->advance = info.xOff;
g->format = format;
delete [] g->data;
- g->data = glyph_buffer;
+ g->data = glyph_buffer.take();
if (set)
set->setGlyph(glyph, subPixelPosition, g);
@@ -1333,14 +1334,14 @@ static inline FT_Matrix QTransformToFTMatrix(const QTransform &matrix)
return m;
}
-QFontEngineFT::QGlyphSet *QFontEngineFT::loadTransformedGlyphSet(const QTransform &matrix)
+QFontEngineFT::QGlyphSet *QFontEngineFT::loadGlyphSet(const QTransform &matrix)
{
if (matrix.type() > QTransform::TxShear || !cacheEnabled)
return 0;
// FT_Set_Transform only supports scalable fonts
if (!FT_IS_SCALABLE(freetype->face))
- return 0;
+ return matrix.type() <= QTransform::TxTranslate ? &defaultGlyphSet : Q_NULLPTR;
FT_Matrix m = QTransformToFTMatrix(matrix);
@@ -1757,15 +1758,11 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe
QFontEngineFT::Glyph *glyph;
QScopedPointer<QFontEngineFT::Glyph> glyphGuard;
if (cacheEnabled) {
- QFontEngineFT::QGlyphSet *gset = &defaultGlyphSet;
+ QGlyphSet *gset = loadGlyphSet(t);
QFontEngine::HintStyle hintStyle = default_hint_style;
if (t.type() >= QTransform::TxScale) {
// disable hinting if the glyphs are transformed
default_hint_style = HintNone;
- if (t.isAffine())
- gset = loadTransformedGlyphSet(t);
- else
- gset = 0;
}
if (gset) {
@@ -1842,31 +1839,20 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g,
const QTransform &t,
bool fetchBoundingBox)
{
- FT_Face face = 0;
- QGlyphSet *glyphSet = 0;
- FT_Matrix ftMatrix = QTransformToFTMatrix(t);
- if (cacheEnabled) {
- if (t.type() > QTransform::TxTranslate && FT_IS_SCALABLE(freetype->face))
- glyphSet = loadTransformedGlyphSet(t);
- else
- glyphSet = &defaultGlyphSet;
- Q_ASSERT(glyphSet != 0);
- }
-
+ QGlyphSet *glyphSet = loadGlyphSet(t);
if (glyphSet != 0 && glyphSet->outline_drawing && !fetchBoundingBox)
return 0;
Glyph *glyph = glyphSet != 0 ? glyphSet->getGlyph(g, subPixelPosition) : 0;
- if (!glyph || glyph->format != format) {
- face = lockFace();
+ if (!glyph || glyph->format != format || (!fetchBoundingBox && !glyph->data)) {
+ lockFace();
FT_Matrix m = this->matrix;
+ FT_Matrix ftMatrix = glyphSet != 0 ? glyphSet->transformationMatrix : QTransformToFTMatrix(t);
FT_Matrix_Multiply(&ftMatrix, &m);
freetype->matrix = m;
glyph = loadGlyph(glyphSet, g, subPixelPosition, format, false);
- }
-
- if (face)
unlockFace();
+ }
return glyph;
}