summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>2010-03-17 13:40:24 (GMT)
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>2010-03-17 13:58:20 (GMT)
commit1ebeb971d3382aec0fff927ce2d6ea7b0452584f (patch)
tree0400dae576726845e85f2ca407def59b0ca261b4 /src
parentc950a2594f7c3102930541800edac5384827846d (diff)
downloadQt-1ebeb971d3382aec0fff927ce2d6ea7b0452584f.zip
Qt-1ebeb971d3382aec0fff927ce2d6ea7b0452584f.tar.gz
Qt-1ebeb971d3382aec0fff927ce2d6ea7b0452584f.tar.bz2
Optimize getting bearings of a glyph on Windows for true type fonts
Usually, the bearing of a glyph is calculated based on the bounding box of the glyph. However, retrieving these bounds is a costly operation on Windows. For true type fonts, we can retrieve the bearings directly by getting the ABC widths, so as an optimization we implement a new virtual function in QFontEngine which retrieves the bearings of the glyph. The default implementation uses boundingBox, but on Windows we try to take the shortcut. Reviewed-by: Simon Hausmann
Diffstat (limited to 'src')
-rw-r--r--src/gui/text/qfontengine.cpp14
-rw-r--r--src/gui/text/qfontengine_p.h3
-rw-r--r--src/gui/text/qfontengine_win.cpp24
-rw-r--r--src/gui/text/qfontengine_win_p.h2
-rw-r--r--src/gui/text/qfontmetrics.cpp21
-rw-r--r--src/gui/text/qtextlayout.cpp6
6 files changed, 59 insertions, 11 deletions
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index c000457..3ec389f 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -379,6 +379,14 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
Q_ASSERT(positions.size() == glyphs_out.size());
}
+void QFontEngine::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rightBearing)
+{
+ glyph_metrics_t gi = boundingBox(glyph);
+ if (leftBearing != 0)
+ *leftBearing = gi.x.toReal();
+ if (rightBearing != 0)
+ *rightBearing = (gi.xoff - gi.x - gi.width).toReal();
+}
glyph_metrics_t QFontEngine::tightBoundingBox(const QGlyphLayout &glyphs)
{
@@ -1385,6 +1393,12 @@ glyph_metrics_t QFontEngineMulti::boundingBox(const QGlyphLayout &glyphs)
return overall;
}
+void QFontEngineMulti::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rightBearing)
+{
+ int which = highByte(glyph);
+ engine(which)->getGlyphBearings(stripped(glyph), leftBearing, rightBearing);
+}
+
void QFontEngineMulti::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs,
QPainterPath *path, QTextItem::RenderFlags flags)
{
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index 71ab5a5..e645caf 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -206,6 +206,8 @@ public:
virtual qreal minLeftBearing() const { return qreal(); }
virtual qreal minRightBearing() const { return qreal(); }
+ virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
+
virtual const char *name() const = 0;
virtual bool canRender(const QChar *string, int len) = 0;
@@ -374,6 +376,7 @@ public:
virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const;
virtual void addOutlineToPath(qreal, qreal, const QGlyphLayout &, QPainterPath *, QTextItem::RenderFlags flags);
+ virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
virtual QFixed ascent() const;
virtual QFixed descent() const;
diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp
index 1a815d3..a133b48 100644
--- a/src/gui/text/qfontengine_win.cpp
+++ b/src/gui/text/qfontengine_win.cpp
@@ -649,6 +649,30 @@ static const ushort char_table[] = {
static const int char_table_entries = sizeof(char_table)/sizeof(ushort);
+void QFontEngineWin::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rightBearing)
+{
+ HDC hdc = shared_dc();
+ SelectObject(hdc, hfont);
+
+#ifndef Q_WS_WINCE
+ if (ttf)
+#endif
+
+ {
+ ABC abcWidths;
+ GetCharABCWidthsI(hdc, glyph, 1, 0, &abcWidths);
+ if (leftBearing)
+ *leftBearing = abcWidths.abcA;
+ if (rightBearing)
+ *rightBearing = abcWidths.abcC;
+ }
+
+#ifndef Q_WS_WINCE
+ else {
+ QFontEngine::getGlyphBearings(glyph, leftBearing, rightBearing);
+ }
+#endif
+}
qreal QFontEngineWin::minLeftBearing() const
{
diff --git a/src/gui/text/qfontengine_win_p.h b/src/gui/text/qfontengine_win_p.h
index f9d8f8b..f19e48e 100644
--- a/src/gui/text/qfontengine_win_p.h
+++ b/src/gui/text/qfontengine_win_p.h
@@ -106,6 +106,8 @@ public:
virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform);
virtual QImage alphaRGBMapForGlyph(glyph_t t, int margin, const QTransform &xform);
+ virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
+
int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs, bool mirrored) const;
void getCMap();
diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp
index 41d0af1..44a18de 100644
--- a/src/gui/text/qfontmetrics.cpp
+++ b/src/gui/text/qfontmetrics.cpp
@@ -472,8 +472,9 @@ int QFontMetrics::leftBearing(QChar ch) const
int nglyphs = 9;
engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
// ### can nglyphs != 1 happen at all? Not currently I think
- glyph_metrics_t gi = engine->boundingBox(glyphs.glyphs[0]);
- return qRound(gi.x);
+ qreal lb;
+ engine->getGlyphBearings(glyphs.glyphs[0], &lb);
+ return qRound(lb);
}
/*!
@@ -506,8 +507,9 @@ int QFontMetrics::rightBearing(QChar ch) const
int nglyphs = 9;
engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
// ### can nglyphs != 1 happen at all? Not currently I think
- glyph_metrics_t gi = engine->boundingBox(glyphs.glyphs[0]);
- return qRound(gi.xoff - gi.x - gi.width);
+ qreal rb;
+ engine->getGlyphBearings(glyphs.glyphs[0], 0, &rb);
+ return qRound(rb);
}
/*!
@@ -1317,8 +1319,9 @@ qreal QFontMetricsF::leftBearing(QChar ch) const
int nglyphs = 9;
engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
// ### can nglyphs != 1 happen at all? Not currently I think
- glyph_metrics_t gi = engine->boundingBox(glyphs.glyphs[0]);
- return gi.x.toReal();
+ qreal lb;
+ engine->getGlyphBearings(glyphs.glyphs[0], &lb);
+ return lb;
}
/*!
@@ -1351,8 +1354,10 @@ qreal QFontMetricsF::rightBearing(QChar ch) const
int nglyphs = 9;
engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
// ### can nglyphs != 1 happen at all? Not currently I think
- glyph_metrics_t gi = engine->boundingBox(glyphs.glyphs[0]);
- return (gi.xoff - gi.x - gi.width).toReal();
+ qreal rb;
+ engine->getGlyphBearings(glyphs.glyphs[0], 0, &rb);
+ return rb;
+
}
/*!
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 204effa..3c0e85e 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -1688,9 +1688,9 @@ namespace {
if (currentPosition <= 0)
return;
- glyph_metrics_t gi = fontEngine->boundingBox(currentGlyph());
- if (gi.isValid())
- rightBearing = qMin(QFixed(), gi.xoff - gi.x - gi.width);
+ qreal rb;
+ fontEngine->getGlyphBearings(currentGlyph(), 0, &rb);
+ rightBearing = qMin(QFixed(), QFixed::fromReal(rb));
}
inline void resetRightBearing()