summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/painting/qpainter.cpp29
-rw-r--r--src/gui/text/qstatictext.cpp128
-rw-r--r--src/gui/text/qstatictext.h5
-rw-r--r--src/gui/text/qstatictext_p.h7
-rw-r--r--src/gui/text/qtextengine.cpp12
-rw-r--r--src/gui/text/qtextengine_p.h2
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