Perform kerning in QRawFont::advancesForGlyphIndexes

Being able to calculate advances for series of glyphs include kerning
is important to be able get kerning on QGlyphRun.

Note this kerning is only truetype kerning, since opentype kerning is performed
during shaping.

Change-Id: I8d7458066431cbdce699647056fd0d7a76b20aa2
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
This commit is contained in:
Allan Sandfeld Jensen 2013-03-05 10:03:16 +01:00 committed by The Qt Project
parent 237fbcbea5
commit 0ef4a55014
2 changed files with 74 additions and 7 deletions

View File

@ -125,6 +125,20 @@ QT_BEGIN_NAMESPACE
each pixel.
*/
/*!
\enum QRawFont::LayoutFlag
\since 5.1
This enum tells the function advancesForGlyphIndexes() how to calculate the advances.
\value SeparateAdvances Will calculate the advance for each glyph separately.
\value KernedAdvances Will apply kerning between adjacent glyphs. Note that OpenType GPOS based
kerning is currently not supported.
\value UseDesignMetrics Use design metrics instead of hinted metrics adjusted to the resolution
of the paint device.
Can be OR-ed with any of the options above.
*/
/*!
Constructs an invalid QRawFont.
*/
@ -510,25 +524,42 @@ bool QRawFont::glyphIndexesForChars(const QChar *chars, int numChars, quint32 *g
}
/*!
\fn QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const
\fn QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes, LayoutFlags layoutFlags) const
\since 5.1
Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances
give the distance from the position of a given glyph to where the next glyph should be drawn
to make it appear as if the two glyphs are unspaced.
to make it appear as if the two glyphs are unspaced. How the advances are calculated is
controlled by \a layoutFlags.
\sa QTextLine::horizontalAdvance(), QFontMetricsF::width()
*/
/*!
\fn QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const
\overload
Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances
give the distance from the position of a given glyph to where the next glyph should be drawn
to make it appear as if the two glyphs are unspaced. The advance of each glyph is calculated
separately.
\sa QTextLine::horizontalAdvance(), QFontMetricsF::width()
*/
/*!
\since 5.1
Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances
give the distance from the position of a given glyph to where the next glyph should be drawn
to make it appear as if the two glyphs are unspaced. The glyph indexes are given with the
array \a glyphIndexes while the results are returned through \a advances, both of them must
have \a numGlyphs elements.
have \a numGlyphs elements. How the advances are calculated is controlled by \a layoutFlags.
\sa QTextLine::horizontalAdvance(), QFontMetricsF::width()
*/
bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const
bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs, LayoutFlags layoutFlags) const
{
Q_ASSERT(glyphIndexes && advances);
if (!d->isValid() || numGlyphs <= 0)
@ -542,7 +573,11 @@ bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *adv
glyphs.advances_x = advances_x.data();
glyphs.advances_y = advances_y.data();
d->fontEngine->recalcAdvances(&glyphs, 0);
bool design = layoutFlags & UseDesignMetrics;
d->fontEngine->recalcAdvances(&glyphs, design ? QFontEngine::DesignMetrics : QFontEngine::ShaperFlag(0));
if (layoutFlags & KernedAdvances)
d->fontEngine->doKerning(&glyphs, design ? QFontEngine::DesignMetrics : QFontEngine::ShaperFlag(0));
for (int i=0; i<numGlyphs; ++i)
advances[i] = QPointF(glyphs.advances_x[i].toReal(), glyphs.advances_y[i].toReal());
@ -550,6 +585,22 @@ bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *adv
return true;
}
/*!
\overload
Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances
give the distance from the position of a given glyph to where the next glyph should be drawn
to make it appear as if the two glyphs are unspaced. The glyph indexes are given with the
array \a glyphIndexes while the results are returned through \a advances, both of them must
have \a numGlyphs elements. The advance of each glyph is calculated separately
\sa QTextLine::horizontalAdvance(), QFontMetricsF::width()
*/
bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const
{
return QRawFont::advancesForGlyphIndexes(glyphIndexes, advances, numGlyphs, SeparateAdvances);
}
/*!
Returns the hinting preference used to construct this QRawFont.

View File

@ -65,6 +65,13 @@ public:
SubPixelAntialiasing
};
enum LayoutFlag {
SeparateAdvances = 0,
KernedAdvances = 1,
UseDesignMetrics = 2
};
Q_DECLARE_FLAGS(LayoutFlags, LayoutFlag)
QRawFont();
QRawFont(const QString &fileName,
qreal pixelSize,
@ -93,8 +100,10 @@ public:
QVector<quint32> glyphIndexesForString(const QString &text) const;
inline QVector<QPointF> advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const;
inline QVector<QPointF> advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes, LayoutFlags layoutFlags) const;
bool glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const;
bool advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const;
bool advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs, LayoutFlags layoutFlags) const;
QImage alphaMapForGlyph(quint32 glyphIndex,
AntialiasingType antialiasingType = SubPixelAntialiasing,
@ -145,14 +154,21 @@ private:
Q_DECLARE_SHARED(QRawFont)
inline QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const
Q_DECLARE_OPERATORS_FOR_FLAGS(QRawFont::LayoutFlags)
inline QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes, QRawFont::LayoutFlags layoutFlags) const
{
QVector<QPointF> advances(glyphIndexes.size());
if (advancesForGlyphIndexes(glyphIndexes.constData(), advances.data(), glyphIndexes.size()))
if (advancesForGlyphIndexes(glyphIndexes.constData(), advances.data(), glyphIndexes.size(), layoutFlags))
return advances;
return QVector<QPointF>();
}
inline QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const
{
return advancesForGlyphIndexes(glyphIndexes, QRawFont::SeparateAdvances);
}
QT_END_NAMESPACE
#endif // QT_NO_RAWFONT