diff options
Diffstat (limited to 'src/gui/text/qtextlayout.cpp')
-rw-r--r-- | src/gui/text/qtextlayout.cpp | 85 |
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 ¤t = 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); |