summaryrefslogtreecommitdiffstats
path: root/src/gui/text/qtextlayout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/text/qtextlayout.cpp')
-rw-r--r--src/gui/text/qtextlayout.cpp85
1 files changed, 76 insertions, 9 deletions
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index ca6866d836..a3e194f835 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -344,6 +344,8 @@ QTextLayout::QTextLayout(const QString& text)
}
/*!
+ \since 5.13
+ \fn QTextLayout::QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice)
Constructs a text layout to lay out the given \a text with the specified
\a font.
@@ -351,11 +353,20 @@ QTextLayout::QTextLayout(const QString& text)
the paint device, \a paintdevice. If \a paintdevice is 0 the
calculations will be done in screen metrics.
*/
-QTextLayout::QTextLayout(const QString& text, const QFont &font, QPaintDevice *paintdevice)
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+/*!
+ \fn QTextLayout::QTextLayout(const QString &text, const QFont &font, QPaintDevice *paintdevice)
+ \obsolete
+ Identical to QTextLayout::QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice)
+*/
+
+QTextLayout::QTextLayout(const QString &text, const QFont &font, QPaintDevice *paintdevice)
+#else
+QTextLayout::QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice)
+#endif
{
- QFont f(font);
- if (paintdevice)
- f = QFont(font, paintdevice);
+ const QFont f(paintdevice ? QFont(font, paintdevice) : font);
d = new QTextEngine((text.isNull() ? (const QString&)QString::fromLatin1("") : text), f);
}
@@ -1127,8 +1138,6 @@ void QTextLayout::draw(QPainter *p, const QPointF &pos, const QVector<FormatRang
QPainterPath textDoneRegion;
for (int i = 0; i < selections.size(); ++i) {
FormatRange selection = selections.at(i);
- const QBrush bg = selection.format.background();
-
QPainterPath region;
region.setFillRule(Qt::WindingFill);
@@ -1823,6 +1832,9 @@ void QTextLine::layout_helper(int maxGlyphs)
lbh.logClusters = eng->layoutData->logClustersPtr;
lbh.previousGlyph = 0;
+ bool hasInlineObject = false;
+ QFixed maxInlineObjectHeight = 0;
+
while (newItem < eng->layoutData->items.size()) {
lbh.resetRightBearing();
lbh.softHyphenWidth = 0;
@@ -1851,8 +1863,11 @@ void QTextLine::layout_helper(int maxGlyphs)
lbh.tmpData.leading = qMax(lbh.tmpData.leading + lbh.tmpData.ascent,
current.leading + current.ascent) - qMax(lbh.tmpData.ascent,
current.ascent);
- lbh.tmpData.ascent = qMax(lbh.tmpData.ascent, current.ascent);
- lbh.tmpData.descent = qMax(lbh.tmpData.descent, current.descent);
+ if (current.analysis.flags != QScriptAnalysis::Object) {
+ // objects need some special treatment as they can special alignment or be floating
+ lbh.tmpData.ascent = qMax(lbh.tmpData.ascent, current.ascent);
+ lbh.tmpData.descent = qMax(lbh.tmpData.descent, current.descent);
+ }
if (current.analysis.flags == QScriptAnalysis::Tab && (alignment & (Qt::AlignLeft | Qt::AlignRight | Qt::AlignCenter | Qt::AlignJustify))) {
lbh.whiteSpaceOrObject = true;
@@ -1900,9 +1915,18 @@ void QTextLine::layout_helper(int maxGlyphs)
if (eng->block.docHandle()) {
QTextInlineObject inlineObject(item, eng);
- eng->docLayout()->positionInlineObject(inlineObject, eng->block.position() + current.position, inlineObject.format());
+ QTextFormat f = inlineObject.format();
+ eng->docLayout()->positionInlineObject(inlineObject, eng->block.position() + current.position, f);
+ QTextCharFormat::VerticalAlignment valign = f.toCharFormat().verticalAlignment();
+ if (valign != QTextCharFormat::AlignTop && valign != QTextCharFormat::AlignBottom) {
+ lbh.tmpData.ascent = qMax(lbh.tmpData.ascent, current.ascent);
+ lbh.tmpData.descent = qMax(lbh.tmpData.descent, current.descent);
+ }
}
+ hasInlineObject = true;
+ maxInlineObjectHeight = qMax(maxInlineObjectHeight, current.ascent + current.descent);
+
lbh.tmpData.textWidth += current.width;
newItem = item + 1;
@@ -2038,6 +2062,43 @@ found:
line += lbh.tmpData;
}
+ if (hasInlineObject && eng->block.docHandle()) {
+ // position top/bottom aligned inline objects
+ if (maxInlineObjectHeight > line.ascent + line.descent) {
+ // extend line height if required
+ QFixed toAdd = (maxInlineObjectHeight - line.ascent - line.descent)/2;
+ line.ascent += toAdd;
+ line.descent = maxInlineObjectHeight - line.ascent;
+ }
+ int startItem = eng->findItem(line.from);
+ int endItem = eng->findItem(line.from + line.length);
+ if (endItem < 0)
+ endItem = eng->layoutData->items.size();
+ for (int item = startItem; item < endItem; ++item) {
+ QScriptItem &current = eng->layoutData->items[item];
+ if (current.analysis.flags == QScriptAnalysis::Object) {
+ QTextInlineObject inlineObject(item, eng);
+ QTextCharFormat::VerticalAlignment align = inlineObject.format().toCharFormat().verticalAlignment();
+ QFixed height = current.ascent + current.descent;
+ switch (align) {
+ case QTextCharFormat::AlignTop:
+ current.ascent = line.ascent;
+ current.descent = height - line.ascent;
+ break;
+ case QTextCharFormat::AlignBottom:
+ current.descent = line.descent;
+ current.ascent = height - line.descent;
+ break;
+ default:
+ break;
+ }
+ Q_ASSERT(line.ascent >= current.ascent);
+ Q_ASSERT(line.descent >= current.descent);
+ }
+ }
+ }
+
+
LB_DEBUG("line length = %d, ascent=%f, descent=%f, textWidth=%f (spacew=%f)", line.length, line.ascent.toReal(),
line.descent.toReal(), line.textWidth.toReal(), lbh.spaceData.width.toReal());
LB_DEBUG(" : '%s'", eng->layoutData->string.mid(line.from, line.length).toUtf8().data());
@@ -2511,6 +2572,8 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR
QFixed itemY = y - si.ascent;
if (format.verticalAlignment() == QTextCharFormat::AlignTop) {
itemY = y - lineBase;
+ } else if (format.verticalAlignment() == QTextCharFormat::AlignBottom) {
+ itemY = y + line.descent - si.ascent - si.descent;
}
QRectF itemRect(iterator.x.toReal(), itemY.toReal(), iterator.itemWidth.toReal(), si.height().toReal());
@@ -2544,6 +2607,7 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR
Qt::IntersectClip);
else
x /= 2; // Centered
+ p->setFont(f);
p->drawText(QPointF(iterator.x.toReal() + x,
y.toReal()), visualTab);
}
@@ -2617,8 +2681,11 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR
if (c.style() != Qt::NoBrush)
p->setPen(c.color());
QChar visualSpace(si.analysis.flags == QScriptAnalysis::Space ? (ushort)0xb7 : (ushort)0xb0);
+ QFont oldFont = p->font();
+ p->setFont(eng->font(si));
p->drawText(QPointF(iterator.x.toReal(), itemBaseLine.toReal()), visualSpace);
p->setPen(pen);
+ p->setFont(oldFont);
}
}
eng->drawDecorations(p);