diff options
author | Konstantin Ritt <ritt.ks@gmail.com> | 2013-03-09 21:39:21 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-03-13 14:46:26 +0100 |
commit | cfa663d62b147c4050359e036f17a6b1b6a8b4fe (patch) | |
tree | 1ae4bbde87ccee0f00878c29f292c99ab2eb32d5 | |
parent | 74494ea29ebc6e152348ed6a6c1e2c9399ddb204 (diff) |
Avoid using HB types in QFontEngine API
This affects HB_Font and HB_Face.
As of now, the Hurfbuzz API usage is concentrated in qfontengine(|_ft).cpp
and qtextengine.cpp, thus it is a lot easier to switch to Hurfbuzz-NG.
Change-Id: Ie06959efd5d6080fe44c407d9f5de0a07dd1c210
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Reviewed-by: Josh Faust <jfaust@suitabletech.com>
-rw-r--r-- | src/gui/text/qfontengine.cpp | 74 | ||||
-rw-r--r-- | src/gui/text/qfontengine_ft.cpp | 32 | ||||
-rw-r--r-- | src/gui/text/qfontengine_ft_p.h | 4 | ||||
-rw-r--r-- | src/gui/text/qfontengine_p.h | 21 | ||||
-rw-r--r-- | src/gui/text/qfontengine_qpf.cpp | 1 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 4 |
6 files changed, 81 insertions, 55 deletions
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index dadc2de394..2bf33863f7 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -165,19 +165,33 @@ static HB_Error hb_getSFntTable(void *font, HB_Tag tableTag, HB_Byte *buffer, HB return HB_Err_Ok; } +static void hb_freeFace(void *face) +{ + qHBFreeFace((HB_Face)face); +} + // QFontEngine QFontEngine::QFontEngine() - : QObject(), ref(0) + : QObject(), ref(0), + font_(0), font_destroy_func(0), + face_(0), face_destroy_func(0) { cache_count = 0; fsType = 0; symbol = false; - memset(&hbFont, 0, sizeof(hbFont)); - hbFont.klass = &hb_fontClass; - hbFont.userData = this; - hbFace = 0; + { + 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; } @@ -185,7 +199,15 @@ QFontEngine::QFontEngine() QFontEngine::~QFontEngine() { m_glyphCaches.clear(); - qHBFreeFace(hbFace); + + if (font_ && font_destroy_func) { + font_destroy_func(font_); + font_ = 0; + } + if (face_ && face_destroy_func) { + face_destroy_func(face_); + face_ = 0; + } } QFixed QFontEngine::lineThickness() const @@ -206,39 +228,37 @@ QFixed QFontEngine::underlinePosition() const return ((lineThickness() * 2) + 3) / 6; } -HB_Font QFontEngine::harfbuzzFont() const +void *QFontEngine::harfbuzzFont() const { - if (!hbFont.x_ppem) { + HB_FontRec *hbFont = (HB_FontRec *)font_; + if (!hbFont->x_ppem) { QFixed emSquare = emSquareSize(); - hbFont.x_ppem = fontDef.pixelSize; - hbFont.y_ppem = fontDef.pixelSize * fontDef.stretch / 100; - hbFont.x_scale = (QFixed(hbFont.x_ppem * (1 << 16)) / emSquare).value(); - hbFont.y_scale = (QFixed(hbFont.y_ppem * (1 << 16)) / emSquare).value(); + hbFont->x_ppem = fontDef.pixelSize; + hbFont->y_ppem = fontDef.pixelSize * fontDef.stretch / 100; + hbFont->x_scale = (QFixed(hbFont->x_ppem * (1 << 16)) / emSquare).value(); + hbFont->y_scale = (QFixed(hbFont->y_ppem * (1 << 16)) / emSquare).value(); } - return &hbFont; + return font_; } -HB_Face QFontEngine::harfbuzzFace() const +void *QFontEngine::harfbuzzFace() const { - if (!hbFace) { - hbFace = qHBNewFace(const_cast<QFontEngine *>(this), hb_getSFntTable); + if (!face_) { + HB_Face hbFace = qHBNewFace(const_cast<QFontEngine *>(this), hb_getSFntTable); Q_CHECK_PTR(hbFace); - } - return hbFace; -} + if (hbFace->font_for_init != 0) + hbFace = qHBLoadFace(hbFace); -HB_Face QFontEngine::initializedHarfbuzzFace() const -{ - HB_Face face = harfbuzzFace(); - if (face != 0 && face->font_for_init != 0) - face = qHBLoadFace(face); - - return face; + face_ = (void *)hbFace; + face_destroy_func = hb_freeFace; + } + return face_; } bool QFontEngine::supportsScript(QChar::Script script) const { - return initializedHarfbuzzFace()->supported_scripts[script_to_hbscript(script)]; + HB_Face hbFace = (HB_Face)harfbuzzFace(); + return hbFace->supported_scripts[script_to_hbscript(script)]; } glyph_metrics_t QFontEngine::boundingBox(glyph_t glyph, const QTransform &matrix) diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 6cac4b9205..8486810299 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -46,6 +46,8 @@ #include "qfontengine_ft_p.h" #include "private/qimage_p.h" +#include <private/qharfbuzz_p.h> + #ifndef QT_NO_FREETYPE #include "qfile.h" @@ -258,8 +260,12 @@ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id, } newFreetype->face = face; - newFreetype->hbFace = qHBNewFace(face, hb_getSFntTable); - Q_CHECK_PTR(newFreetype->hbFace); + 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->ref.store(1); newFreetype->xsize = 0; newFreetype->ysize = 0; @@ -313,7 +319,7 @@ void QFreetypeFace::release(const QFontEngine::FaceId &face_id) { QtFreetypeData *freetypeData = qt_getFreetypeData(); if (!ref.deref()) { - qHBFreeFace(hbFace); + qHBFreeFace((HB_Face)hbFace); FT_Done_Face(face); if(freetypeData->faces.contains(face_id)) freetypeData->faces.take(face_id); @@ -654,7 +660,6 @@ QFontEngineFT::~QFontEngineFT() { if (freetype) freetype->release(face_id); - hbFace = 0; // we share the face in QFreeTypeFace, don't let ~QFontEngine delete it } bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format, @@ -691,7 +696,7 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format, symbol = bool(fontDef.family.contains(QLatin1String("symbol"), Qt::CaseInsensitive)); } // ##### - freetype->hbFace->isSymbolFont = symbol; + ((HB_Face)freetype->hbFace)->isSymbolFont = symbol; lbearing = rbearing = SHRT_MIN; freetype->computeSize(fontDef, &xsize, &ysize, &defaultGlyphSet.outline_drawing); @@ -729,12 +734,17 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format, if (line_thickness < 1) line_thickness = 1; - 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; - - hbFace = freetype->hbFace; + 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; diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index 9963d307ba..434eb76c33 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -69,8 +69,6 @@ #include <qmutex.h> -#include "private/qharfbuzz_copy_p.h" - QT_BEGIN_NAMESPACE class QFontEngineFTRawFont; @@ -101,7 +99,7 @@ struct QFreetypeFace } FT_Face face; - HB_Face hbFace; + void *hbFace; int xsize; // 26.6 int ysize; // 26.6 FT_Matrix matrix; diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 4f29aff9d7..3c7746b3c9 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -60,8 +60,6 @@ #include "private/qtextengine_p.h" #include "private/qfont_p.h" -#include "private/qharfbuzz_copy_p.h" - #include <private/qfontengineglyphcache_p.h> QT_BEGIN_NAMESPACE @@ -77,6 +75,7 @@ struct QGlyphLayout; ((quint32)(ch4)) \ ) +typedef void (*qt_destroy_func_t) (void *user_data); class Q_GUI_EXPORT QFontEngine : public QObject { @@ -162,11 +161,6 @@ public: /* returns 0 as glyph index for non existent glyphs */ virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const = 0; - - /** - * This is a callback from harfbuzz. The font engine uses the font-system in use to find out the - * advances of each glyph and set it on the layout. - */ virtual void recalcAdvances(QGlyphLayout *, ShaperFlags) const {} virtual void doKerning(QGlyphLayout *, ShaperFlags) const; @@ -248,9 +242,8 @@ public: virtual QFontEngine *cloneWithSize(qreal /*pixelSize*/) const { return 0; } - HB_Font harfbuzzFont() const; - HB_Face harfbuzzFace() const; - HB_Face initializedHarfbuzzFace() const; + void *harfbuzzFont() const; + void *harfbuzzFace() const; bool supportsScript(QChar::Script script) const; virtual int getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints); @@ -273,12 +266,16 @@ public: QAtomicInt ref; QFontDef fontDef; + + mutable void *font_; + mutable qt_destroy_func_t font_destroy_func; + mutable void *face_; + mutable qt_destroy_func_t face_destroy_func; + uint cache_cost; // amount of mem used in kb by the font int cache_count; uint fsType : 16; bool symbol; - mutable HB_FontRec hbFont; - mutable HB_Face hbFace; struct KernPair { uint left_right; QFixed adjust; diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp index 56d4c29f1c..def671c62f 100644 --- a/src/gui/text/qfontengine_qpf.cpp +++ b/src/gui/text/qfontengine_qpf.cpp @@ -50,6 +50,7 @@ #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 diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index fdedfded12..2814b5ae12 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1111,8 +1111,8 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const si.descent = qMax(actualFontEngine->descent(), si.descent); si.leading = qMax(actualFontEngine->leading(), si.leading); - shaper_item.font = actualFontEngine->harfbuzzFont(); - shaper_item.face = actualFontEngine->initializedHarfbuzzFace(); + shaper_item.font = (HB_Font)actualFontEngine->harfbuzzFont(); + shaper_item.face = (HB_Face)actualFontEngine->harfbuzzFace(); shaper_item.glyphIndicesPresent = true; |