From a5614264d5a5d6d1cc0f2773f4d7cd70195a0546 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Thu, 30 Jan 2014 05:46:35 +0200 Subject: 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 Reviewed-by: Lars Knoll Reviewed-by: Simon Hausmann --- src/gui/painting/qpaintbuffer.cpp | 6 +- src/gui/painting/qpainter.cpp | 3 +- src/gui/text/qfont.cpp | 2 +- src/gui/text/qfontengine.cpp | 88 ++++++++-------------- src/gui/text/qfontengine_ft.cpp | 9 +-- src/gui/text/qfontengine_qpa.cpp | 3 +- src/gui/text/qfontmetrics.cpp | 8 +- src/gui/text/qharfbuzzng.cpp | 16 ++-- src/gui/text/qrawfont.cpp | 8 +- src/gui/text/qtextengine.cpp | 44 ++++++----- src/gui/text/qtextengine_p.h | 37 ++++----- src/gui/text/qtextlayout.cpp | 18 ++--- .../fontdatabases/mac/qfontengine_coretext.mm | 18 ++--- .../platforms/windows/qwindowsfontengine.cpp | 11 +-- .../windows/qwindowsfontenginedirectwrite.cpp | 8 +- .../qtextscriptengine/tst_qtextscriptengine.cpp | 7 +- 16 files changed, 110 insertions(+), 176 deletions(-) diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp index f855e9e32d..421d706230 100644 --- a/src/gui/painting/qpaintbuffer.cpp +++ b/src/gui/painting/qpaintbuffer.cpp @@ -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; diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 41a2e39fc9..fbb4c2eb56 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -5617,8 +5617,7 @@ void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, QFixedPoint *positio textItem.glyphs.numGlyphs = glyphCount; textItem.glyphs.glyphs = const_cast(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(); diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 49b5a9ba46..f2951611ff 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -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 diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 8698e5529b..7dfd9423e9 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -108,13 +108,10 @@ static void hb_getAdvances(HB_Font font, const HB_Glyph *glyphs, hb_uint32 numGl { QFontEngine *fe = (QFontEngine *)font->userData; - QVarLengthArray advances_y(numGlyphs); - QGlyphLayout qglyphs; qglyphs.numGlyphs = numGlyphs; qglyphs.glyphs = const_cast(glyphs); - qglyphs.advances_x = reinterpret_cast(advances); - qglyphs.advances_y = advances_y.data(); // not used + qglyphs.advances = reinterpret_cast(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 diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 0c32dfb460..630ba78477 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -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(); } } diff --git a/src/gui/text/qfontengine_qpa.cpp b/src/gui/text/qfontengine_qpa.cpp index 28b95bd509..46f9071f07 100644 --- a/src/gui/text/qfontengine_qpa.cpp +++ b/src/gui/text/qfontengine_qpa.cpp @@ -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; } } diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 1a66657cbd..08105834ea 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -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(); } /*! diff --git a/src/gui/text/qharfbuzzng.cpp b/src/gui/text/qharfbuzzng.cpp index b4ab5856df..c5bedecbfe 100644 --- a/src/gui/text/qharfbuzzng.cpp +++ b/src/gui/text/qharfbuzzng.cpp @@ -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 diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index b1b910422c..e26f7cdc93 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -568,10 +568,8 @@ bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *adv QGlyphLayout glyphs; glyphs.glyphs = const_cast(glyphIndexes); glyphs.numGlyphs = numGlyphs; - QVarLengthArray advances_x(numGlyphs); - QVarLengthArray advances_y(numGlyphs); - glyphs.advances_x = advances_x.data(); - glyphs.advances_y = advances_y.data(); + QVarLengthArray 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 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(g.glyphs); shaper_item.attributes = reinterpret_cast(g.attributes); - shaper_item.advances = reinterpret_cast(g.advances_x); + shaper_item.advances = reinterpret_cast(g.advances); shaper_item.offsets = reinterpret_cast(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; diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index f2e16cf546..fce2bd808d 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -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(address + offset); offset += totalGlyphs * sizeof(glyph_t); - advances_x = reinterpret_cast(address + offset); - offset += totalGlyphs * sizeof(QFixed); - advances_y = reinterpret_cast(address + offset); + advances = reinterpret_cast(address + offset); offset += totalGlyphs * sizeof(QFixed); justifications = reinterpret_cast(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(offsets + numGlyphs) == reinterpret_cast(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 Array; public: QVarLengthGlyphLayoutArray(int totalGlyphs) - : Array(spaceNeededForGlyphLayout(totalGlyphs) / sizeof(void *) + 1) + : Array((totalGlyphs * SpaceNeeded) / sizeof(void *) + 1) , QGlyphLayout(reinterpret_cast(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(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; diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 66341e186a..c6e5160edc 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -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 QTextLine::glyphRuns(int from, int length) const if (relativeFrom != (iterator.itemStart - si.position) && !rtl) { for (int i=itemGlyphsStart; iglyphsEnd; --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 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; diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 9b8f10f588..570e841d52 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -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; } diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index 6ff000e7d4..35346e5b45 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -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; diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp index 7c18ac44fa..f603dd5c53 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp @@ -366,13 +366,11 @@ void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEn glyphIndices.size(), glyphMetrics.data()); if (SUCCEEDED(hr)) { - for (int i=0; inumGlyphs; ++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__); diff --git a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp index eebac28323..74802c3217 100644 --- a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp +++ b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp @@ -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 } -- cgit v1.2.3