summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorKonstantin Ritt <ritt.ks@gmail.com>2013-08-10 20:05:36 +0300
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-08-20 20:09:20 +0200
commit227e9a40cfeb7e00658cd343266e9d4140a4ebcf (patch)
tree7862e0a91fb4f5d3893bddaf97a462058f7cc615 /src/gui
parentcbb4a882622e1d4edbcfbcfb71dab446065e986d (diff)
Get rid of HB dependency in FT font engine
Instead of loading HB face in QFreetypeFace::getFace(), defer allocation until the first FT font engine for that face gets initialized; then, QFreetypeFace "reparents" and manages the loaded HB face. Change-Id: I2ac8ead4c6ed25d341af9c9cf0c34dfb979f8390 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/text/qfontengine.cpp24
-rw-r--r--src/gui/text/qfontengine_ft.cpp63
-rw-r--r--src/gui/text/qfontengine_ft_p.h4
-rw-r--r--src/gui/text/qfontengine_p.h9
-rw-r--r--src/gui/text/qfontengine_qpf.cpp3
5 files changed, 42 insertions, 61 deletions
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 6a6e67abb0..d8a8e34b0b 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -143,7 +143,7 @@ int QFontEngine::getPointInOutline(glyph_t glyph, int flags, quint32 point, QFix
Q_UNUSED(xpos)
Q_UNUSED(ypos)
Q_UNUSED(nPoints)
- return HB_Err_Not_Covered;
+ return Err_Not_Covered;
}
static HB_Error hb_getPointInOutline(HB_Font font, HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints)
@@ -203,17 +203,6 @@ QFontEngine::QFontEngine()
fsType = 0;
symbol = false;
- {
- HB_FontRec *hbFont = (HB_FontRec *) malloc(sizeof(HB_FontRec));
- Q_CHECK_PTR(hbFont);
- memset(hbFont, 0, sizeof(HB_FontRec));
- hbFont->klass = &hb_fontClass;
- hbFont->userData = this;
-
- font_ = (void *)hbFont;
- font_destroy_func = free;
- }
-
glyphFormat = -1;
m_subPixelPositionCount = 0;
@@ -262,8 +251,12 @@ QFixed QFontEngine::underlinePosition() const
void *QFontEngine::harfbuzzFont() const
{
- HB_FontRec *hbFont = (HB_FontRec *)font_;
- if (!hbFont->x_ppem) {
+ if (!font_) {
+ HB_FontRec *hbFont = (HB_FontRec *) malloc(sizeof(HB_FontRec));
+ Q_CHECK_PTR(hbFont);
+ hbFont->klass = &hb_fontClass;
+ hbFont->userData = const_cast<QFontEngine *>(this);
+
qint64 emSquare = emSquareSize().truncate();
Q_ASSERT(emSquare == emSquareSize().toInt()); // ensure no truncation
if (emSquare == 0)
@@ -273,6 +266,9 @@ void *QFontEngine::harfbuzzFont() const
// same as QFixed(x)/QFixed(emSquare) but without int32 overflow for x
hbFont->x_scale = (((qint64)hbFont->x_ppem << 6) * 0x10000L + (emSquare >> 1)) / emSquare;
hbFont->y_scale = (((qint64)hbFont->y_ppem << 6) * 0x10000L + (emSquare >> 1)) / emSquare;
+
+ font_ = (void *)hbFont;
+ font_destroy_func = free;
}
return font_;
}
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 7b4925a9c8..cad9b02f41 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -46,8 +46,6 @@
#include "qfontengine_ft_p.h"
#include "private/qimage_p.h"
-#include <private/qharfbuzz_p.h>
-
#ifndef QT_NO_FREETYPE
#include "qfile.h"
@@ -118,24 +116,6 @@ QT_BEGIN_NAMESPACE
#define TRUNC(x) ((x) >> 6)
#define ROUND(x) (((x)+32) & -64)
-static HB_Error hb_getSFntTable(void *font, HB_Tag tableTag, HB_Byte *buffer, HB_UInt *length)
-{
-#if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) > 20103
- FT_Face face = (FT_Face)font;
- FT_ULong ftlen = *length;
- FT_Error error = 0;
-
- if ( !FT_IS_SFNT(face) )
- return HB_Err_Invalid_Argument;
-
- error = FT_Load_Sfnt_Table(face, tableTag, 0, buffer, &ftlen);
- *length = ftlen;
- return (HB_Error)error;
-#else
- return HB_Err_Invalid_Argument;
-#endif
-}
-
// -------------------------- Freetype support ------------------------------
class QtFreetypeData
@@ -191,19 +171,19 @@ int QFreetypeFace::getPointInOutline(glyph_t glyph, int flags, quint32 point, QF
return error;
if (face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
- return HB_Err_Invalid_SubTable;
+ return Err_Invalid_SubTable;
*nPoints = face->glyph->outline.n_points;
if (!(*nPoints))
- return HB_Err_Ok;
+ return Err_Ok;
if (point > *nPoints)
- return HB_Err_Invalid_SubTable;
+ return Err_Invalid_SubTable;
*xpos = QFixed::fromFixed(face->glyph->outline.points[point].x);
*ypos = QFixed::fromFixed(face->glyph->outline.points[point].y);
- return HB_Err_Ok;
+ return Err_Ok;
}
extern QByteArray qt_fontdata_from_index(int);
@@ -260,11 +240,8 @@ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id,
}
newFreetype->face = face;
- HB_Face hbFace = qHBNewFace(face, hb_getSFntTable);
- Q_CHECK_PTR(hbFace);
- if (hbFace->font_for_init != 0)
- hbFace = qHBLoadFace(hbFace);
- newFreetype->hbFace = (void *)hbFace;
+ newFreetype->hbFace = 0;
+ newFreetype->hbFace_destroy_func = 0;
newFreetype->ref.store(1);
newFreetype->xsize = 0;
@@ -319,7 +296,10 @@ void QFreetypeFace::release(const QFontEngine::FaceId &face_id)
{
QtFreetypeData *freetypeData = qt_getFreetypeData();
if (!ref.deref()) {
- qHBFreeFace((HB_Face)hbFace);
+ if (hbFace && hbFace_destroy_func) {
+ hbFace_destroy_func(hbFace);
+ hbFace = 0;
+ }
FT_Done_Face(face);
if(freetypeData->faces.contains(face_id))
freetypeData->faces.take(face_id);
@@ -695,8 +675,6 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
if (FT_Get_PS_Font_Info(freetype->face, &psrec) == FT_Err_Ok) {
symbol = bool(fontDef.family.contains(QLatin1String("symbol"), Qt::CaseInsensitive));
}
- // #####
- ((HB_Face)freetype->hbFace)->isSymbolFont = symbol;
lbearing = rbearing = SHRT_MIN;
freetype->computeSize(fontDef, &xsize, &ysize, &defaultGlyphSet.outline_drawing);
@@ -734,18 +712,6 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
if (line_thickness < 1)
line_thickness = 1;
- HB_FontRec *hbFont = (HB_FontRec *)font_;
- hbFont->x_ppem = face->size->metrics.x_ppem;
- hbFont->y_ppem = face->size->metrics.y_ppem;
- hbFont->x_scale = face->size->metrics.x_scale;
- hbFont->y_scale = face->size->metrics.y_scale;
-
- // ###
- if (face_ && face_destroy_func)
- face_destroy_func(face_);
- face_ = freetype->hbFace;
- face_destroy_func = 0; // we share the face in QFreeTypeFace, don't let ~QFontEngine delete it
-
metrics = face->size->metrics;
/*
@@ -773,6 +739,15 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
fontDef.styleName = QString::fromUtf8(face->style_name);
+ if (!freetype->hbFace) {
+ freetype->hbFace = harfbuzzFace();
+ freetype->hbFace_destroy_func = face_destroy_func;
+ } else {
+ Q_ASSERT(!face_);
+ face_ = freetype->hbFace;
+ }
+ face_destroy_func = 0; // we share the HB face in QFreeTypeFace, so do not let ~QFontEngine() destroy it
+
unlockFace();
fsType = freetype->fsType();
diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h
index bd4c855b91..e2e99893c8 100644
--- a/src/gui/text/qfontengine_ft_p.h
+++ b/src/gui/text/qfontengine_ft_p.h
@@ -99,7 +99,6 @@ struct QFreetypeFace
}
FT_Face face;
- void *hbFace;
int xsize; // 26.6
int ysize; // 26.6
FT_Matrix matrix;
@@ -124,6 +123,9 @@ private:
QAtomicInt ref;
QMutex _lock;
QByteArray fontData;
+
+ void *hbFace;
+ qt_destroy_func_t hbFace_destroy_func;
};
// If this is exported this breaks compilation of the windows
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index 855f0099ff..4427000d03 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -75,6 +75,15 @@ struct QGlyphLayout;
((quint32)(ch4)) \
)
+// ### this only used in getPointInOutline(), refactor it and then remove these magic numbers
+enum HB_Compat_Error {
+ Err_Ok = 0x0000,
+ Err_Not_Covered = 0xFFFF,
+ Err_Invalid_Argument = 0x1A66,
+ Err_Invalid_SubTable_Format = 0x157F,
+ Err_Invalid_SubTable = 0x1570
+};
+
typedef void (*qt_destroy_func_t) (void *user_data);
class Q_GUI_EXPORT QFontEngine : public QObject
diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp
index def671c62f..78bc3f871a 100644
--- a/src/gui/text/qfontengine_qpf.cpp
+++ b/src/gui/text/qfontengine_qpf.cpp
@@ -50,7 +50,6 @@
#include <QtCore/qbuffer.h>
#if !defined(QT_NO_FREETYPE)
#include "private/qfontengine_ft_p.h"
-#include <private/qharfbuzz_p.h>
#endif
#include "private/qcore_unix_p.h" // overrides QT_OPEN
@@ -858,7 +857,7 @@ void QFontEngineQPF::doKerning(QGlyphLayout *g, QFontEngine::ShaperFlags flags)
int QFontEngineQPF::getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints)
{
if (!freetype)
- return HB_Err_Not_Covered;
+ return Err_Not_Covered;
lockFace();
int result = freetype->getPointInOutline(glyph, flags, point, xpos, ypos, nPoints);
unlockFace();