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>
This commit is contained in:
Konstantin Ritt 2013-03-09 21:39:21 +02:00 committed by The Qt Project
parent 74494ea29e
commit cfa663d62b
6 changed files with 80 additions and 54 deletions

View File

@ -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)

View File

@ -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;
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;
hbFace = freetype->hbFace;
// ###
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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;