diff options
-rw-r--r-- | src/gui/painting/qpainter.cpp | 29 | ||||
-rw-r--r-- | src/gui/text/qstatictext.cpp | 128 | ||||
-rw-r--r-- | src/gui/text/qstatictext.h | 5 | ||||
-rw-r--r-- | src/gui/text/qstatictext_p.h | 7 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 12 | ||||
-rw-r--r-- | src/gui/text/qtextengine_p.h | 2 |
6 files changed, 98 insertions, 85 deletions
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 8ff93d2..435ad9b 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -5721,33 +5721,22 @@ void QPainter::drawText(const QPointF &p, const QString &str) This function can be used to optimize drawing text if the text and its layout is updated seldomly. - - \note To mirror the behavior of QPainter::drawText() the y-position will be used as the baseline - of the font if a size not set on \a staticText. If a size is set for \a staticText, \a position - is the top left corner of the clipping rectangle of the text. */ void QPainter::drawStaticText(const QPointF &position, const QStaticText &staticText) { const QStaticTextPrivate *staticText_d = QStaticTextPrivate::get(&staticText); - QTextLayout *textLayout = staticText_d->textLayout; - - QSizeF size = staticText_d->size; - QRectF clipRect = size.isValid() ? QRectF(position, staticText_d->size) : QRectF(); - QPainterPath oldClipPath; - if (clipRect.isValid()) { - oldClipPath = clipPath(); - - QPainterPath clipPath; - clipPath.addRect(clipRect); + QFixed x = QFixed::fromReal(position.x()); + for (int i=0; i<staticText_d->items.size();++i) { + QTextItemInt *gf = staticText_d->items.at(i); + if (gf->num_chars == 0) { + x += gf->width; + continue; + } - setClipPath(clipPath, Qt::IntersectClip); + drawTextItem(QPointF(x.toReal(), position.y()), *gf); + x += gf->width; } - - textLayout->draw(this, position, QVector<QTextLayout::FormatRange>(), clipRect); - - if (clipRect.isValid()) - setClipPath(oldClipPath); } /*! diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index f953d71..90fde9d 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -41,6 +41,7 @@ #include "qstatictext.h" #include "qstatictext_p.h" +#include <private/qtextengine_p.h> QT_BEGIN_NAMESPACE @@ -110,13 +111,11 @@ QStaticText::QStaticText() \a font and bounded by the given \a maximumSize. If an invalid size is passed for \a maximumSize the text will be unbounded. */ -QStaticText::QStaticText(const QString &text, const QFont &font, const QSizeF &sz) +QStaticText::QStaticText(const QString &text, const QFont &font) : d_ptr(new QStaticTextPrivate) { - d_ptr->textLayout->setText(text); - d_ptr->textLayout->setFont(font); - d_ptr->size = sz; - + d_ptr->text = text; + d_ptr->font = font; d_ptr->init(); } @@ -163,9 +162,7 @@ QStaticText &QStaticText::operator=(const QStaticText &other) bool QStaticText::operator==(const QStaticText &other) const { return (d_ptr == other.d_ptr - || (d_ptr->textLayout->text() == other.d_ptr->textLayout->text() - && d_ptr->textLayout->font() == other.d_ptr->textLayout->font() - && d_ptr->size == other.d_ptr->size)); + || (d_ptr->text == other.d_ptr->text && d_ptr->font == other.d_ptr->font)); } /*! @@ -187,8 +184,7 @@ bool QStaticText::operator!=(const QStaticText &other) const void QStaticText::setText(const QString &text) { detach(); - - d_ptr->textLayout->setText(text); + d_ptr->text = text; d_ptr->init(); } @@ -199,7 +195,7 @@ void QStaticText::setText(const QString &text) */ QString QStaticText::text() const { - return d_ptr->textLayout->text(); + return d_ptr->text; } /*! @@ -212,8 +208,7 @@ QString QStaticText::text() const void QStaticText::setFont(const QFont &font) { detach(); - - d_ptr->textLayout->setFont(font); + d_ptr->font = font; d_ptr->init(); } @@ -224,33 +219,7 @@ void QStaticText::setFont(const QFont &font) */ QFont QStaticText::font() const { - return d_ptr->textLayout->font(); -} - -/*! - Sets the maximum size of the QStaticText to \a maximumSize. If a valid maximum size is set for - the QStaticText, it will be formatted to fit within its width, and clipped by its height. - - \note This function will cause the layout of the text to be recalculated. - - \sa maximumSize() -*/ -void QStaticText::setMaximumSize(const QSizeF &maximumSize) -{ - detach(); - - d_ptr->size = maximumSize; - d_ptr->init(); -} - -/*! - Returns the maximum size of the QStaticText. - - \sa setMaximumSize() -*/ -QSizeF QStaticText::maximumSize() const -{ - return d_ptr->size; + return d_ptr->font; } QString QStaticText::toString() const @@ -258,22 +227,24 @@ QString QStaticText::toString() const return text(); } -QStaticTextPrivate::QStaticTextPrivate() - : textLayout(new QTextLayout()) +QStaticTextPrivate::QStaticTextPrivate() : glyphLayoutMemory(0), logClusterMemory(0) { - ref = 1; + ref = 1; } -QStaticTextPrivate::QStaticTextPrivate(const QStaticTextPrivate &other) +QStaticTextPrivate::QStaticTextPrivate(const QStaticTextPrivate &other) { ref = 1; - textLayout = new QTextLayout(other.textLayout->text(), other.textLayout->font()); - size = other.size; + text = other.text; + font = other.font; + init(); } QStaticTextPrivate::~QStaticTextPrivate() { - delete textLayout; + delete glyphLayoutMemory; + delete logClusterMemory; + qDeleteAll(items); } QStaticTextPrivate *QStaticTextPrivate::get(const QStaticText *q) @@ -283,22 +254,61 @@ QStaticTextPrivate *QStaticTextPrivate::get(const QStaticText *q) void QStaticTextPrivate::init() { - Q_ASSERT(textLayout != 0); - textLayout->setCacheEnabled(true); + delete glyphLayoutMemory; + delete logClusterMemory; + qDeleteAll(items); + + QStackTextEngine engine = QStackTextEngine(text, font); + engine.itemize(); + + engine.option.setTextDirection(QApplication::layoutDirection()); + QScriptLine line; + line.length = text.length(); + engine.shapeLine(line); + + int nItems = engine.layoutData->items.size(); + QVarLengthArray<int> visualOrder(nItems); + QVarLengthArray<uchar> levels(nItems); + for (int i = 0; i < nItems; ++i) + levels[i] = engine.layoutData->items[i].analysis.bidiLevel; + QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data()); + + int numGlyphs = engine.layoutData->glyphLayout.numGlyphs; + glyphLayoutMemory = new char[QGlyphLayout::spaceNeededForGlyphLayout(numGlyphs)]; + logClusterMemory = new unsigned short[numGlyphs]; + + char *currentGlyphLayout = glyphLayoutMemory; + unsigned short *currentLogCluster = logClusterMemory; + for (int i = 0; i < nItems; ++i) { + int item = visualOrder[i]; + const QScriptItem &si = engine.layoutData->items.at(item); + + QFont f = engine.font(si); + if (si.analysis.flags >= QScriptAnalysis::TabOrObject) { + QTextItemInt *gf = new QTextItemInt(si, &f); + gf->width = si.width; + items.append(gf); + continue; + } - QFontMetrics fontMetrics(textLayout->font()); + QTextItemInt *gf = new QTextItemInt(si, &f); - textLayout->beginLayout(); - int h = size.isValid() ? 0 : -fontMetrics.ascent(); + QGlyphLayout l = engine.shapedGlyphs(&si); + gf->glyphs = l.clone(currentGlyphLayout); + currentGlyphLayout += QGlyphLayout::spaceNeededForGlyphLayout(l.numGlyphs); - QTextLine line; - qreal lineWidth = size.isValid() ? size.width() : fontMetrics.width(textLayout->text()); - while ((line = textLayout->createLine()).isValid()) { - line.setLineWidth(lineWidth); - line.setPosition(QPointF(0, h)); - h += line.height(); + gf->chars = text.unicode() + si.position; + gf->num_chars = engine.length(item); + gf->width = si.width; + + memmove(currentLogCluster, engine.logClusters(&si), sizeof(unsigned short) * l.numGlyphs); + gf->logClusters = currentLogCluster; + currentLogCluster += l.numGlyphs; + + items.append(gf); } - textLayout->endLayout(); + + items.squeeze(); } QT_END_NAMESPACE diff --git a/src/gui/text/qstatictext.h b/src/gui/text/qstatictext.h index 3d59d6a..bcafaa9 100644 --- a/src/gui/text/qstatictext.h +++ b/src/gui/text/qstatictext.h @@ -57,7 +57,7 @@ class Q_GUI_EXPORT QStaticText { public: QStaticText(); - QStaticText(const QString &text, const QFont &font = QFont(), const QSizeF &maximumSize = QSizeF()); + QStaticText(const QString &text, const QFont &font = QFont()); QStaticText(const QStaticText &other); ~QStaticText(); @@ -67,9 +67,6 @@ public: void setFont(const QFont &font); QFont font() const; - void setMaximumSize(const QSizeF &maximumSize); - QSizeF maximumSize() const; - QStaticText &operator=(const QStaticText &); bool operator==(const QStaticText &) const; bool operator!=(const QStaticText &) const; diff --git a/src/gui/text/qstatictext_p.h b/src/gui/text/qstatictext_p.h index 773971a..aaaf300 100644 --- a/src/gui/text/qstatictext_p.h +++ b/src/gui/text/qstatictext_p.h @@ -67,9 +67,12 @@ public: void init(); - QTextLayout *textLayout; - QSizeF size; QAtomicInt ref; + QVector<QTextItemInt *> items; + QString text; + QFont font; + char *glyphLayoutMemory; + unsigned short *logClusterMemory; static QStaticTextPrivate *get(const QStaticText *q); }; diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 02eae98..7f92279 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -2109,6 +2109,18 @@ void QTextEngine::LayoutData::reallocate(int totalGlyphs) allocated = newAllocated; } +QGlyphLayout QGlyphLayout::clone(char *address) const +{ + QGlyphLayout layout(address, numGlyphs); + memmove(layout.attributes, attributes, numGlyphs * sizeof(HB_GlyphAttributes)); + memmove(layout.justifications, justifications, numGlyphs * sizeof(QGlyphJustification)); + memmove(layout.advances_y, advances_y, numGlyphs * sizeof(QFixed)); + memmove(layout.advances_x, advances_x, numGlyphs * sizeof(QFixed)); + memmove(layout.glyphs, glyphs, numGlyphs * sizeof(HB_Glyph)); + + return layout; +} + // grow to the new size, copying the existing data to the new layout void QGlyphLayout::grow(char *address, int totalGlyphs) { diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index f36cbd2..2edbd98 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -262,6 +262,8 @@ struct QGlyphLayout } void grow(char *address, int totalGlyphs); + + QGlyphLayout clone(char *address) const; }; class QVarLengthGlyphLayoutArray : private QVarLengthArray<void *>, public QGlyphLayout |