Get rid of QGlyphLayout::advances_y

...and thus consume 4 bytes less per glyph and increase the performance a bit.
It seems, the only CTFontGetAdvancesForGlyphs() returns both x and y
advances, though y advances are always equal to 0 for horizontal
orientation and x advances are always equal to 0 for vertical orientation.

Also, rename `advances_x` to `advances` for consistency
and declare QGlyphLayout's data size in a single place.

Change-Id: I56b20f893f8a6feb7aa870e3edbca99dd93ba2e2
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
bb10
Konstantin Ritt 2014-01-30 05:46:35 +02:00 committed by The Qt Project
parent dca65cd2bc
commit a5614264d5
16 changed files with 110 additions and 176 deletions

View File

@ -70,13 +70,11 @@ QTextItemIntCopy::QTextItemIntCopy(const QTextItem &item)
m_item.chars = chars;
m_item.logClusters = logClusters;
const int size = QGlyphLayout::spaceNeededForGlyphLayout(m_item.glyphs.numGlyphs);
char *glyphLayoutData = new char[size];
char *glyphLayoutData = new char[m_item.glyphs.numGlyphs * QGlyphLayout::SpaceNeeded];
QGlyphLayout glyphs(glyphLayoutData, m_item.glyphs.numGlyphs);
memcpy(glyphs.offsets, m_item.glyphs.offsets, m_item.glyphs.numGlyphs * sizeof(QFixedPoint));
memcpy(glyphs.glyphs, m_item.glyphs.glyphs, m_item.glyphs.numGlyphs * sizeof(glyph_t));
memcpy(glyphs.advances_x, m_item.glyphs.advances_x, m_item.glyphs.numGlyphs * sizeof(QFixed));
memcpy(glyphs.advances_y, m_item.glyphs.advances_y, m_item.glyphs.numGlyphs * sizeof(QFixed));
memcpy(glyphs.advances, m_item.glyphs.advances, m_item.glyphs.numGlyphs * sizeof(QFixed));
memcpy(glyphs.justifications, m_item.glyphs.justifications, m_item.glyphs.numGlyphs * sizeof(QGlyphJustification));
memcpy(glyphs.attributes, m_item.glyphs.attributes, m_item.glyphs.numGlyphs * sizeof(QGlyphAttributes));
m_item.glyphs = glyphs;

View File

@ -5617,8 +5617,7 @@ void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, QFixedPoint *positio
textItem.glyphs.numGlyphs = glyphCount;
textItem.glyphs.glyphs = const_cast<glyph_t *>(glyphArray);
textItem.glyphs.offsets = positions;
textItem.glyphs.advances_x = advances.data();
textItem.glyphs.advances_y = advances.data();
textItem.glyphs.advances = advances.data();
textItem.glyphs.justifications = glyphJustifications.data();
textItem.glyphs.attributes = glyphAttributes.data();

View File

@ -2534,7 +2534,7 @@ bool QFontInfo::fixedPitch() const
QGlyphLayoutArray<2> g;
int l = 2;
engine->stringToCMap(ch, 2, &g, &l, 0);
engine->fontDef.fixedPitch = g.advances_x[0] == g.advances_x[1];
engine->fontDef.fixedPitch = g.advances[0] == g.advances[1];
engine->fontDef.fixedPitchComputed = true;
}
#endif

View File

@ -108,13 +108,10 @@ static void hb_getAdvances(HB_Font font, const HB_Glyph *glyphs, hb_uint32 numGl
{
QFontEngine *fe = (QFontEngine *)font->userData;
QVarLengthArray<QFixed> advances_y(numGlyphs);
QGlyphLayout qglyphs;
qglyphs.numGlyphs = numGlyphs;
qglyphs.glyphs = const_cast<glyph_t *>(glyphs);
qglyphs.advances_x = reinterpret_cast<QFixed *>(advances);
qglyphs.advances_y = advances_y.data(); // not used
qglyphs.advances = reinterpret_cast<QFixed *>(advances);
fe->recalcAdvances(&qglyphs, (flags & HB_ShaperFlag_UseDesignMetrics) ? QFontEngine::DesignMetrics : QFontEngine::ShaperFlags(0));
}
@ -404,8 +401,7 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
while(i--) {
if (glyphs.attributes[i].dontPrint)
continue;
xpos += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
ypos += glyphs.advances_y[i];
xpos += glyphs.advances[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
totalKashidas += glyphs.justifications[i].nKashidas;
}
positions.resize(glyphs.numGlyphs+totalKashidas);
@ -417,8 +413,7 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
++i;
continue;
}
xpos -= glyphs.advances_x[i];
ypos -= glyphs.advances_y[i];
xpos -= glyphs.advances[i];
QFixed gpos_x = xpos + glyphs.offsets[i].x;
QFixed gpos_y = ypos + glyphs.offsets[i].y;
@ -438,8 +433,7 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
int nglyphs = 7;
stringToCMap(&ch, 1, &g, &nglyphs, 0);
for (uint k = 0; k < glyphs.justifications[i].nKashidas; ++k) {
xpos -= g.advances_x[0];
ypos -= g.advances_y[0];
xpos -= g.advances[0];
QFixed gpos_x = xpos + glyphs.offsets[i].x;
QFixed gpos_y = ypos + glyphs.offsets[i].y;
@ -469,8 +463,7 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
positions[current].x = xpos + glyphs.offsets[i].x;
positions[current].y = ypos + glyphs.offsets[i].y;
glyphs_out[current] = glyphs.glyphs[i];
xpos += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
ypos += glyphs.advances_y[i];
xpos += glyphs.advances[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
++current;
}
++i;
@ -485,8 +478,7 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
positions[current].x = QFixed::fromReal(gpos.x());
positions[current].y = QFixed::fromReal(gpos.y());
glyphs_out[current] = glyphs.glyphs[i];
xpos += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
ypos += glyphs.advances_y[i];
xpos += glyphs.advances[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
++current;
}
++i;
@ -649,8 +641,7 @@ void QFontEngine::addBitmapFontToPath(qreal x, qreal y, const QGlyphLayout &glyp
for (int i=0; i < glyphs.numGlyphs; ++i) {
glyph_metrics_t metrics = boundingBox(glyphs.glyphs[i]);
if (metrics.width.value() == 0 || metrics.height.value() == 0) {
advanceX += glyphs.advances_x[i];
advanceY += glyphs.advances_y[i];
advanceX += glyphs.advances[i];
continue;
}
const QImage alphaMask = alphaMapForGlyph(glyphs.glyphs[i]);
@ -685,8 +676,7 @@ void QFontEngine::addBitmapFontToPath(qreal x, qreal y, const QGlyphLayout &glyp
advanceX += offset.x;
advanceY += offset.y;
qt_addBitmapToPath((advanceX + metrics.x).toReal(), (advanceY + metrics.y).toReal(), bitmap_data, bitmap.bytesPerLine(), w, h, path);
advanceX += glyphs.advances_x[i];
advanceY += glyphs.advances_y[i];
advanceX += glyphs.advances[i];
}
}
@ -697,16 +687,12 @@ void QFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int n
qreal y = positions[0].y.toReal();
QVarLengthGlyphLayoutArray g(nGlyphs);
for (int i = 0; i < nGlyphs; ++i) {
for (int i = 0; i < nGlyphs - 1; ++i) {
g.glyphs[i] = glyphs[i];
if (i < nGlyphs - 1) {
g.advances_x[i] = positions[i+1].x - positions[i].x;
g.advances_y[i] = positions[i+1].y - positions[i].y;
} else {
g.advances_x[i] = QFixed::fromReal(maxCharWidth());
g.advances_y[i] = 0;
}
g.advances[i] = positions[i + 1].x - positions[i].x;
}
g.glyphs[nGlyphs - 1] = glyphs[nGlyphs - 1];
g.advances[nGlyphs - 1] = QFixed::fromReal(maxCharWidth());
addBitmapFontToPath(x, y, g, path, flags);
}
@ -966,10 +952,10 @@ void QFontEngine::doKerning(QGlyphLayout *glyphs, QFontEngine::ShaperFlags flags
if (flags & DesignMetrics) {
for(int i = 0; i < glyphs->numGlyphs - 1; ++i)
glyphs->advances_x[i] += kerning(glyphs->glyphs[i], glyphs->glyphs[i+1] , pairs, numPairs);
glyphs->advances[i] += kerning(glyphs->glyphs[i], glyphs->glyphs[i+1] , pairs, numPairs);
} else {
for(int i = 0; i < glyphs->numGlyphs - 1; ++i)
glyphs->advances_x[i] += qRound(kerning(glyphs->glyphs[i], glyphs->glyphs[i+1] , pairs, numPairs));
glyphs->advances[i] += qRound(kerning(glyphs->glyphs[i], glyphs->glyphs[i+1] , pairs, numPairs));
}
}
@ -1333,10 +1319,8 @@ bool QFontEngineBox::stringToCMap(const QChar *, int len, QGlyphLayout *glyphs,
void QFontEngineBox::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags) const
{
for (int i = 0; i < glyphs->numGlyphs; i++) {
glyphs->advances_x[i] = _size;
glyphs->advances_y[i] = 0;
}
for (int i = 0; i < glyphs->numGlyphs; i++)
glyphs->advances[i] = _size;
}
void QFontEngineBox::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
@ -1496,11 +1480,9 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len,
bool surrogate = (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate());
uint ucs4 = surrogate ? QChar::surrogateToUcs4(str[i], str[i+1]) : str[i].unicode();
if (glyphs->glyphs[glyph_pos] == 0 && str[i].category() != QChar::Separator_Line) {
QFixedPoint tmpAdvance;
if (!(flags & GlyphIndicesOnly)) {
tmpAdvance.x = glyphs->advances_x[glyph_pos];
tmpAdvance.y = glyphs->advances_y[glyph_pos];
}
QFixed tmpAdvance;
if (!(flags & GlyphIndicesOnly))
tmpAdvance = glyphs->advances[glyph_pos];
for (int x = 1, n = qMin(engines.size(), 256); x < n; ++x) {
if (engines.at(x) == 0 && !shouldLoadFontEngineForCharacter(x, ucs4))
continue;
@ -1515,7 +1497,7 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len,
continue;
if (!(flags & GlyphIndicesOnly))
glyphs->advances_x[glyph_pos] = glyphs->advances_y[glyph_pos] = 0;
glyphs->advances[glyph_pos] = QFixed();
int num = 2;
QGlyphLayout offs = glyphs->mid(glyph_pos, num);
engine->stringToCMap(str + i, surrogate ? 2 : 1, &offs, &num, flags);
@ -1528,10 +1510,8 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len,
}
// ensure we use metrics from the 1st font when we use the fallback image.
if (!(flags & GlyphIndicesOnly) && glyphs->glyphs[glyph_pos] == 0) {
glyphs->advances_x[glyph_pos] = tmpAdvance.x;
glyphs->advances_y[glyph_pos] = tmpAdvance.y;
}
if (!(flags & GlyphIndicesOnly) && glyphs->glyphs[glyph_pos] == 0)
glyphs->advances[glyph_pos] = tmpAdvance;
}
if (surrogate)
@ -1632,10 +1612,8 @@ void QFontEngineMulti::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &gl
int start = 0;
int end, i;
if (flags & QTextItem::RightToLeft) {
for (int gl = 0; gl < glyphs.numGlyphs; gl++) {
x += glyphs.advances_x[gl].toReal();
y += glyphs.advances_y[gl].toReal();
}
for (int gl = 0; gl < glyphs.numGlyphs; gl++)
x += glyphs.advances[gl].toReal();
}
for (end = 0; end < glyphs.numGlyphs; ++end) {
const int e = highByte(glyphs.glyphs[end]);
@ -1643,10 +1621,8 @@ void QFontEngineMulti::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &gl
continue;
if (flags & QTextItem::RightToLeft) {
for (i = start; i < end; ++i) {
x -= glyphs.advances_x[i].toReal();
y -= glyphs.advances_y[i].toReal();
}
for (i = start; i < end; ++i)
x -= glyphs.advances[i].toReal();
}
// set the high byte to zero
@ -1659,10 +1635,8 @@ void QFontEngineMulti::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &gl
glyphs.glyphs[i] = hi | glyphs.glyphs[i];
if (!(flags & QTextItem::RightToLeft)) {
for (i = start; i < end; ++i) {
x += glyphs.advances_x[i].toReal();
y += glyphs.advances_y[i].toReal();
}
for (i = start; i < end; ++i)
x += glyphs.advances[i].toReal();
}
// change engine
@ -1671,10 +1645,8 @@ void QFontEngineMulti::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &gl
}
if (flags & QTextItem::RightToLeft) {
for (i = start; i < end; ++i) {
x -= glyphs.advances_x[i].toReal();
y -= glyphs.advances_y[i].toReal();
}
for (i = start; i < end; ++i)
x -= glyphs.advances[i].toReal();
}
// set the high byte to zero

View File

@ -1598,24 +1598,23 @@ void QFontEngineFT::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlag
// Since we are passing Format_None to loadGlyph, use same default format logic as loadGlyph
GlyphFormat acceptableFormat = (defaultFormat != Format_None) ? defaultFormat : Format_Mono;
if (g && g->format == acceptableFormat) {
glyphs->advances_x[i] = design ? QFixed::fromFixed(g->linearAdvance) : QFixed(g->advance);
glyphs->advances[i] = design ? QFixed::fromFixed(g->linearAdvance) : QFixed(g->advance);
} else {
if (!face)
face = lockFace();
g = loadGlyph(cacheEnabled ? &defaultGlyphSet : 0, glyphs->glyphs[i], 0, Format_None, true);
glyphs->advances_x[i] = design ? QFixed::fromFixed(face->glyph->linearHoriAdvance >> 10)
: QFixed::fromFixed(face->glyph->metrics.horiAdvance);
glyphs->advances[i] = design ? QFixed::fromFixed(face->glyph->linearHoriAdvance >> 10)
: QFixed::fromFixed(face->glyph->metrics.horiAdvance);
if (!cacheEnabled)
delete g;
}
glyphs->advances_y[i] = 0;
}
if (face)
unlockFace();
if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
for (int i = 0; i < glyphs->numGlyphs; ++i)
glyphs->advances_x[i] = glyphs->advances_x[i].round();
glyphs->advances[i] = glyphs->advances[i].round();
}
}

View File

@ -399,8 +399,7 @@ void QFontEngineQPA::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFla
glyphs->glyphs[i] = 0;
continue;
}
glyphs->advances_x[i] = g->advance;
glyphs->advances_y[i] = 0;
glyphs->advances[i] = g->advance;
}
}

View File

@ -546,7 +546,7 @@ int QFontMetrics::width(const QString &text, int len, int flags) const
QFixed width;
for (int i = 0; i < numGlyphs; ++i)
width += glyphs.advances_x[i];
width += glyphs.advances[i];
return qRound(width);
}
@ -597,7 +597,7 @@ int QFontMetrics::width(QChar ch) const
QGlyphLayoutArray<8> glyphs;
int nglyphs = 7;
engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
return qRound(glyphs.advances_x[0]);
return qRound(glyphs.advances[0]);
}
/*! \obsolete
@ -642,7 +642,7 @@ int QFontMetrics::charWidth(const QString &text, int pos) const
QGlyphLayoutArray<8> glyphs;
int nglyphs = 7;
engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
width = qRound(glyphs.advances_x[0]);
width = qRound(glyphs.advances[0]);
}
return width;
}
@ -1434,7 +1434,7 @@ qreal QFontMetricsF::width(QChar ch) const
QGlyphLayoutArray<8> glyphs;
int nglyphs = 7;
engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
return glyphs.advances_x[0].toReal();
return glyphs.advances[0].toReal();
}
/*!

View File

@ -439,18 +439,16 @@ _hb_qt_font_get_glyph_h_advance(hb_font_t *font, void *font_data,
QFontEngine *fe = (QFontEngine *)font_data;
Q_ASSERT(fe);
QFixed advance_x;
QFixed advance_y;
QFixed advance;
QGlyphLayout g;
g.numGlyphs = 1;
g.glyphs = &glyph;
g.advances_x = &advance_x;
g.advances_y = &advance_y;
g.advances = &advance;
fe->recalcAdvances(&g, QFontEngine::ShaperFlags(hb_qt_font_get_use_design_metrics(font)));
return g.advances_x[0].value();
return g.advances[0].value();
}
static hb_position_t
@ -490,18 +488,16 @@ _hb_qt_font_get_glyph_h_kerning(hb_font_t *font, void *font_data,
Q_ASSERT(fe);
glyph_t glyphs[2] = { first_glyph, second_glyph };
QFixed advance_x;
QFixed advance_y;
QFixed advance;
QGlyphLayout g;
g.numGlyphs = 2;
g.glyphs = glyphs;
g.advances_x = &advance_x;
g.advances_y = &advance_y;
g.advances = &advance;
fe->doKerning(&g, QFontEngine::ShaperFlags(hb_qt_font_get_use_design_metrics(font)));
return g.advances_x[0].value();
return g.advances[0].value();
}
static hb_position_t

View File

@ -568,10 +568,8 @@ bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *adv
QGlyphLayout glyphs;
glyphs.glyphs = const_cast<glyph_t *>(glyphIndexes);
glyphs.numGlyphs = numGlyphs;
QVarLengthArray<QFixed> advances_x(numGlyphs);
QVarLengthArray<QFixed> advances_y(numGlyphs);
glyphs.advances_x = advances_x.data();
glyphs.advances_y = advances_y.data();
QVarLengthArray<QFixed> tmpAdvances(numGlyphs);
glyphs.advances = tmpAdvances.data();
bool design = layoutFlags & UseDesignMetrics;
@ -580,7 +578,7 @@ bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *adv
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());
advances[i] = QPointF(glyphs.advances[i].toReal(), 0.0);
return true;
}

View File

@ -1009,17 +1009,17 @@ void QTextEngine::shapeText(int item) const
for (int i = 1; i < si.num_glyphs; ++i) {
if (glyphs.attributes[i].clusterStart) {
if (letterSpacingIsAbsolute)
glyphs.advances_x[i-1] += letterSpacing;
glyphs.advances[i - 1] += letterSpacing;
else {
QFixed &advance = glyphs.advances_x[i-1];
QFixed &advance = glyphs.advances[i - 1];
advance += (letterSpacing - 100) * advance / 100;
}
}
}
if (letterSpacingIsAbsolute)
glyphs.advances_x[si.num_glyphs-1] += letterSpacing;
glyphs.advances[si.num_glyphs - 1] += letterSpacing;
else {
QFixed &advance = glyphs.advances_x[si.num_glyphs-1];
QFixed &advance = glyphs.advances[si.num_glyphs - 1];
advance += (letterSpacing - 100) * advance / 100;
}
}
@ -1031,13 +1031,13 @@ void QTextEngine::shapeText(int item) const
if (i + 1 == si.num_glyphs
||(glyphs.attributes[i+1].justification != QGlyphAttributes::Space
&& glyphs.attributes[i+1].justification != QGlyphAttributes::Arabic_Space))
glyphs.advances_x[i] += wordSpacing;
glyphs.advances[i] += wordSpacing;
}
}
}
for (int i = 0; i < si.num_glyphs; ++i)
si.width += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint;
si.width += glyphs.advances[i] * !glyphs.attributes[i].dontPrint;
}
static inline void moveGlyphData(const QGlyphLayout &destination, const QGlyphLayout &source, int num)
@ -1045,7 +1045,7 @@ static inline void moveGlyphData(const QGlyphLayout &destination, const QGlyphLa
if (num > 0 && destination.glyphs != source.glyphs) {
memmove(destination.glyphs, source.glyphs, num * sizeof(glyph_t));
memmove(destination.attributes, source.attributes, num * sizeof(QGlyphAttributes));
memmove(destination.advances_x, source.advances_x, num * sizeof(QFixed));
memmove(destination.advances, source.advances, num * sizeof(QFixed));
memmove(destination.offsets, source.offsets, num * sizeof(QFixedPoint));
}
}
@ -1163,8 +1163,7 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
g.glyphs[i] = infos[i].codepoint;
log_clusters[i] = infos[i].cluster;
g.advances_x[i] = QFixed::fromFixed(positions[i].x_advance);
g.advances_y[i] = QFixed::fromFixed(positions[i].y_advance);
g.advances[i] = QFixed::fromFixed(positions[i].x_advance);
g.offsets[i].x = QFixed::fromFixed(positions[i].x_offset);
g.offsets[i].y = QFixed::fromFixed(positions[i].y_offset);
@ -1286,7 +1285,7 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri
shaper_item.glyphs = reinterpret_cast<HB_Glyph *>(g.glyphs);
shaper_item.attributes = reinterpret_cast<HB_GlyphAttributes *>(g.attributes);
shaper_item.advances = reinterpret_cast<HB_Fixed *>(g.advances_x);
shaper_item.advances = reinterpret_cast<HB_Fixed *>(g.advances);
shaper_item.offsets = reinterpret_cast<HB_FixedPoint *>(g.offsets);
if (engineIdx != 0 && shaper_item.glyphIndicesPresent) {
@ -1703,7 +1702,7 @@ QFixed QTextEngine::width(int from, int len) const
// qDebug("char: start=%d end=%d / glyph: start = %d, end = %d", charFrom, charEnd, glyphStart, glyphEnd);
for (int i = glyphStart; i < glyphEnd; i++)
w += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint;
w += glyphs.advances[i] * !glyphs.attributes[i].dontPrint;
}
}
}
@ -1993,8 +1992,8 @@ static void set(QJustificationPoint *point, int type, const QGlyphLayout &glyph,
QGlyphLayoutArray<8> glyphs;
int nglyphs = 7;
fe->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
if (glyphs.glyphs[0] && glyphs.advances_x[0] != 0) {
point->kashidaWidth = glyphs.advances_x[0];
if (glyphs.glyphs[0] != 0 && glyphs.advances[0].value() != 0) {
point->kashidaWidth = glyphs.advances[0];
} else {
point->type = QGlyphAttributes::NoJustification;
point->kashidaWidth = 0;
@ -2236,7 +2235,7 @@ QTextEngine::LayoutData::LayoutData(const QString &str, void **stack_memory, int
int space_charAttributes = sizeof(QCharAttributes)*string.length()/sizeof(void*) + 1;
int space_logClusters = sizeof(unsigned short)*string.length()/sizeof(void*) + 1;
available_glyphs = ((int)allocated - space_charAttributes - space_logClusters)*(int)sizeof(void*)/(int)QGlyphLayout::spaceNeededForGlyphLayout(1);
available_glyphs = ((int)allocated - space_charAttributes - space_logClusters)*(int)sizeof(void*)/(int)QGlyphLayout::SpaceNeeded;
if (available_glyphs < str.length()) {
// need to allocate on the heap
@ -2278,7 +2277,7 @@ bool QTextEngine::LayoutData::reallocate(int totalGlyphs)
int space_charAttributes = sizeof(QCharAttributes)*string.length()/sizeof(void*) + 1;
int space_logClusters = sizeof(unsigned short)*string.length()/sizeof(void*) + 1;
int space_glyphs = QGlyphLayout::spaceNeededForGlyphLayout(totalGlyphs)/sizeof(void*) + 2;
int space_glyphs = (totalGlyphs * QGlyphLayout::SpaceNeeded) / sizeof(void *) + 2;
int newAllocated = space_charAttributes + space_glyphs + space_logClusters;
// These values can be negative if the length of string/glyphs causes overflow,
@ -2325,8 +2324,7 @@ void QGlyphLayout::grow(char *address, int totalGlyphs)
// move the existing data
memmove(newLayout.attributes, oldLayout.attributes, numGlyphs * sizeof(QGlyphAttributes));
memmove(newLayout.justifications, oldLayout.justifications, numGlyphs * sizeof(QGlyphJustification));
memmove(newLayout.advances_y, oldLayout.advances_y, numGlyphs * sizeof(QFixed));
memmove(newLayout.advances_x, oldLayout.advances_x, numGlyphs * sizeof(QFixed));
memmove(newLayout.advances, oldLayout.advances, numGlyphs * sizeof(QFixed));
memmove(newLayout.glyphs, oldLayout.glyphs, numGlyphs * sizeof(glyph_t));
}
@ -2650,7 +2648,7 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
}
if (ellipsisGlyph.glyphs[0]) {
ellipsisWidth = ellipsisGlyph.advances_x[0];
ellipsisWidth = ellipsisGlyph.advances[0];
ellipsisText = ellipsisChar;
} else {
QString dotDotDot(QLatin1String("..."));
@ -2661,7 +2659,7 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
// should never happen...
return layoutData->string;
for (int i = 0; i < nGlyphs; ++i)
ellipsisWidth += glyphs.advances_x[i];
ellipsisWidth += glyphs.advances[i];
ellipsisText = dotDotDot;
}
}
@ -2810,7 +2808,7 @@ void QTextEngine::splitItem(int item, int pos) const
QFixed w = 0;
const QGlyphLayout g = shapedGlyphs(&oldItem);
for(int j = 0; j < breakGlyph; ++j)
w += g.advances_x[j] * !g.attributes[j].dontPrint;
w += g.advances[j] * !g.attributes[j].dontPrint;
newItem.width = oldItem.width - w;
oldItem.width = w;
@ -2883,9 +2881,9 @@ QFixed QTextEngine::calculateTabWidth(int item, QFixed x) const
QGlyphLayout glyphs = this->shapedGlyphs(&item);
const int end = qMin(item.position + item.num_glyphs, tabSectionEnd) - item.position;
for (int i=0; i < end; i++)
length += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint;
length += glyphs.advances[i] * !glyphs.attributes[i].dontPrint;
if (end + item.position == tabSectionEnd && tabSpec.type == QTextOption::DelimiterTab) // remove half of matching char
length -= glyphs.advances_x[end] / 2 * !glyphs.attributes[end].dontPrint;
length -= glyphs.advances[end] / 2 * !glyphs.attributes[end].dontPrint;
}
switch (tabSpec.type) {
@ -3050,7 +3048,7 @@ QFixed QTextEngine::offsetInLigature(const QScriptItem *si, int pos, int max, in
break;
}
if (clusterLength)
return glyphs.advances_x[glyph_pos] * offsetInCluster / clusterLength;
return glyphs.advances[glyph_pos] * offsetInCluster / clusterLength;
}
return 0;

View File

@ -190,11 +190,15 @@ Q_DECLARE_TYPEINFO(QGlyphJustification, Q_PRIMITIVE_TYPE);
struct QGlyphLayout
{
enum {
SpaceNeeded = sizeof(glyph_t) + sizeof(QFixed) + sizeof(QFixedPoint)
+ sizeof(QGlyphAttributes) + sizeof(QGlyphJustification)
};
// init to 0 not needed, done when shaping
QFixedPoint *offsets; // 8 bytes per element
glyph_t *glyphs; // 4 bytes per element
QFixed *advances_x; // 4 bytes per element
QFixed *advances_y; // 4 bytes per element
QFixed *advances; // 4 bytes per element
QGlyphJustification *justifications; // 4 bytes per element
QGlyphAttributes *attributes; // 2 bytes per element
@ -208,9 +212,7 @@ struct QGlyphLayout
int offset = totalGlyphs * sizeof(QFixedPoint);
glyphs = reinterpret_cast<glyph_t *>(address + offset);
offset += totalGlyphs * sizeof(glyph_t);
advances_x = reinterpret_cast<QFixed *>(address + offset);
offset += totalGlyphs * sizeof(QFixed);
advances_y = reinterpret_cast<QFixed *>(address + offset);
advances = reinterpret_cast<QFixed *>(address + offset);
offset += totalGlyphs * sizeof(QFixed);
justifications = reinterpret_cast<QGlyphJustification *>(address + offset);
offset += totalGlyphs * sizeof(QGlyphJustification);
@ -221,8 +223,7 @@ struct QGlyphLayout
inline QGlyphLayout mid(int position, int n = -1) const {
QGlyphLayout copy = *this;
copy.glyphs += position;
copy.advances_x += position;
copy.advances_y += position;
copy.advances += position;
copy.offsets += position;
copy.justifications += position;
copy.attributes += position;
@ -233,27 +234,20 @@ struct QGlyphLayout
return copy;
}
static inline int spaceNeededForGlyphLayout(int totalGlyphs) {
return totalGlyphs * (sizeof(glyph_t) + sizeof(QGlyphAttributes)
+ sizeof(QFixed) + sizeof(QFixed) + sizeof(QFixedPoint)
+ sizeof(QGlyphJustification));
}
inline QFixed effectiveAdvance(int item) const
{ return (advances_x[item] + QFixed::fromFixed(justifications[item].space_18d6)) * !attributes[item].dontPrint; }
{ return (advances[item] + QFixed::fromFixed(justifications[item].space_18d6)) * !attributes[item].dontPrint; }
inline void clear(int first = 0, int last = -1) {
if (last == -1)
last = numGlyphs;
if (first == 0 && last == numGlyphs
&& reinterpret_cast<char *>(offsets + numGlyphs) == reinterpret_cast<char *>(glyphs)) {
memset(offsets, 0, spaceNeededForGlyphLayout(numGlyphs));
memset(offsets, 0, (numGlyphs * SpaceNeeded));
} else {
const int num = last - first;
memset(offsets + first, 0, num * sizeof(QFixedPoint));
memset(glyphs + first, 0, num * sizeof(glyph_t));
memset(advances_x + first, 0, num * sizeof(QFixed));
memset(advances_y + first, 0, num * sizeof(QFixed));
memset(advances + first, 0, num * sizeof(QFixed));
memset(justifications + first, 0, num * sizeof(QGlyphJustification));
memset(attributes + first, 0, num * sizeof(QGlyphAttributes));
}
@ -272,7 +266,7 @@ private:
typedef QVarLengthArray<void *> Array;
public:
QVarLengthGlyphLayoutArray(int totalGlyphs)
: Array(spaceNeededForGlyphLayout(totalGlyphs) / sizeof(void *) + 1)
: Array((totalGlyphs * SpaceNeeded) / sizeof(void *) + 1)
, QGlyphLayout(reinterpret_cast<char *>(Array::data()), totalGlyphs)
{
memset(Array::data(), 0, Array::size() * sizeof(void *));
@ -280,7 +274,7 @@ public:
void resize(int totalGlyphs)
{
Array::resize(spaceNeededForGlyphLayout(totalGlyphs) / sizeof(void *) + 1);
Array::resize((totalGlyphs * SpaceNeeded) / sizeof(void *) + 1);
*((QGlyphLayout *)this) = QGlyphLayout(reinterpret_cast<char *>(Array::data()), totalGlyphs);
memset(Array::data(), 0, Array::size() * sizeof(void *));
@ -297,10 +291,7 @@ public:
}
private:
void *buffer[(N * (sizeof(glyph_t) + sizeof(QGlyphAttributes)
+ sizeof(QFixed) + sizeof(QFixed) + sizeof(QFixedPoint)
+ sizeof(QGlyphJustification)))
/ sizeof(void *) + 1];
void *buffer[(N * SpaceNeeded) / sizeof(void *) + 1];
};
struct QScriptItem;

View File

@ -1693,7 +1693,7 @@ static inline void addNextCluster(int &pos, int end, QScriptLine &line, int &gly
} while (pos < end && logClusters[pos] == glyphPosition);
do { // calculate the textWidth for the rest of the current cluster.
if (!glyphs.attributes[glyphPosition].dontPrint)
line.textWidth += glyphs.advances_x[glyphPosition];
line.textWidth += glyphs.advances[glyphPosition];
++glyphPosition;
} while (glyphPosition < current.num_glyphs && !glyphs.attributes[glyphPosition].clusterStart);
@ -1871,9 +1871,9 @@ void QTextLine::layout_helper(int maxGlyphs)
// and thus become invisible again.
//
if (line.length)
lbh.softHyphenWidth = lbh.glyphs.advances_x[lbh.logClusters[lbh.currentPosition - 1]];
lbh.softHyphenWidth = lbh.glyphs.advances[lbh.logClusters[lbh.currentPosition - 1]];
else if (breakany)
lbh.tmpData.textWidth += lbh.glyphs.advances_x[lbh.logClusters[lbh.currentPosition - 1]];
lbh.tmpData.textWidth += lbh.glyphs.advances[lbh.logClusters[lbh.currentPosition - 1]];
}
// The actual width of the text needs to take the right bearing into account. The
@ -2249,14 +2249,12 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
if (relativeFrom != (iterator.itemStart - si.position) && !rtl) {
for (int i=itemGlyphsStart; i<glyphsStart; ++i) {
QFixed justification = QFixed::fromFixed(glyphLayout.justifications[i].space_18d6);
pos += QPointF((glyphLayout.advances_x[i] + justification).toReal(),
glyphLayout.advances_y[i].toReal());
pos.rx() += (glyphLayout.advances[i] + justification).toReal();
}
} else if (relativeTo != (iterator.itemEnd - si.position - 1) && rtl) {
for (int i=itemGlyphsEnd; i>glyphsEnd; --i) {
QFixed justification = QFixed::fromFixed(glyphLayout.justifications[i].space_18d6);
pos += QPointF((glyphLayout.advances_x[i] + justification).toReal(),
glyphLayout.advances_y[i].toReal());
pos.rx() += (glyphLayout.advances[i] + justification).toReal();
}
}
@ -2295,10 +2293,8 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
glyphRuns.append(glyphRunWithInfo(multiFontEngine->engine(which),
subLayout, pos, subFlags, x, width));
for (int i = 0; i < subLayout.numGlyphs; i++) {
pos += QPointF(subLayout.advances_x[i].toReal(),
subLayout.advances_y[i].toReal());
}
for (int i = 0; i < subLayout.numGlyphs; ++i)
pos.rx() += subLayout.advances[i].toReal();
if (rtl)
end = start;

View File

@ -63,15 +63,12 @@ static void loadAdvancesForGlyphs(CTFontRef ctfont,
for (int i = 0; i < len; ++i) {
if (glyphs->glyphs[i] & 0xff000000)
continue;
glyphs->advances_x[i] = QFixed::fromReal(advances[i].width);
glyphs->advances_y[i] = QFixed::fromReal(advances[i].height);
glyphs->advances[i] = QFixed::fromReal(advances[i].width);
}
if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
for (int i = 0; i < len; ++i) {
glyphs->advances_x[i] = glyphs->advances_x[i].round();
glyphs->advances_y[i] = glyphs->advances_y[i].round();
}
for (int i = 0; i < len; ++i)
glyphs->advances[i] = glyphs->advances[i].round();
}
}
@ -228,15 +225,12 @@ bool QCoreTextFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *
for (int i = 0; i < glyph_pos; ++i) {
if (glyphs->glyphs[i] & 0xff000000)
continue;
glyphs->advances_x[i] = QFixed::fromReal(advances[i].width);
glyphs->advances_y[i] = QFixed::fromReal(advances[i].height);
glyphs->advances[i] = QFixed::fromReal(advances[i].width);
}
if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
for (int i = 0; i < glyph_pos; ++i) {
glyphs->advances_x[i] = glyphs->advances_x[i].round();
glyphs->advances_y[i] = glyphs->advances_y[i].round();
}
for (int i = 0; i < glyph_pos; ++i)
glyphs->advances[i] = glyphs->advances[i].round();
}
return true;
}

View File

@ -431,8 +431,7 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape
calculateTTFGlyphWidth(hdc, glyph, width);
designAdvances[glyph] = QFixed(width) / designToDevice;
}
glyphs->advances_x[i] = designAdvances[glyph];
glyphs->advances_y[i] = 0;
glyphs->advances[i] = designAdvances[glyph];
}
if(oldFont)
DeleteObject(SelectObject(hdc, oldFont));
@ -440,8 +439,6 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape
for(int i = 0; i < glyphs->numGlyphs; i++) {
unsigned int glyph = glyphs->glyphs[i];
glyphs->advances_y[i] = 0;
if (glyph >= widthCacheSize) {
int newSize = (glyph + 256) >> 8 << 8;
widthCache = q_check_ptr((unsigned char *)realloc(widthCache,
@ -449,9 +446,9 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape
memset(widthCache + widthCacheSize, 0, newSize - widthCacheSize);
widthCacheSize = newSize;
}
glyphs->advances_x[i] = widthCache[glyph];
glyphs->advances[i] = widthCache[glyph];
// font-width cache failed
if (glyphs->advances_x[i] == 0) {
if (glyphs->advances[i].value() == 0) {
int width = 0;
if (!oldFont)
oldFont = SelectObject(hdc, hfont);
@ -470,7 +467,7 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape
} else {
calculateTTFGlyphWidth(hdc, glyph, width);
}
glyphs->advances_x[i] = width;
glyphs->advances[i] = width;
// if glyph's within cache range, store it for later
if (width > 0 && width < 0x100)
widthCache[glyph] = width;

View File

@ -366,13 +366,11 @@ void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEn
glyphIndices.size(),
glyphMetrics.data());
if (SUCCEEDED(hr)) {
for (int i=0; i<glyphs->numGlyphs; ++i) {
glyphs->advances_x[i] = DESIGN_TO_LOGICAL(glyphMetrics[i].advanceWidth);
glyphs->advances_y[i] = 0;
}
for (int i = 0; i < glyphs->numGlyphs; ++i)
glyphs->advances[i] = DESIGN_TO_LOGICAL(glyphMetrics[i].advanceWidth);
if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
for (int i = 0; i < glyphs->numGlyphs; ++i)
glyphs->advances_x[i] = glyphs->advances_x[i].round();
glyphs->advances[i] = glyphs->advances[i].round();
}
} else {
qErrnoWarning("%s: GetDesignGlyphMetrics failed", __FUNCTION__);

View File

@ -1067,7 +1067,7 @@ void tst_QTextScriptEngine::controlInSyllable_qtbug14204()
e->shape(0);
QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(2));
QVERIFY(e->layoutData->glyphLayout.advances_x[1] != 0);
QVERIFY(e->layoutData->glyphLayout.advances[1].toInt() != 0);
#endif
}
@ -1087,8 +1087,7 @@ void tst_QTextScriptEngine::combiningMarks_qtbug15675()
e->shape(0);
QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(4));
QEXPECT_FAIL("", "QTBUG-23064", Abort);
QVERIFY(e->layoutData->glyphLayout.advances_y[2] > 0);
QCOMPARE(e->layoutData->glyphLayout.advances[2].toInt(), 0);
#else
QFontDatabase db;
@ -1106,7 +1105,7 @@ void tst_QTextScriptEngine::combiningMarks_qtbug15675()
e->shape(0);
QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(3));
QVERIFY(e->layoutData->glyphLayout.advances_x[1] == 0);
QCOMPARE(e->layoutData->glyphLayout.advances[1].toInt(), 0);
#endif
}