summaryrefslogtreecommitdiffstats
path: root/src/gui/text/qtextdocumentlayout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/text/qtextdocumentlayout.cpp')
-rw-r--r--src/gui/text/qtextdocumentlayout.cpp77
1 files changed, 45 insertions, 32 deletions
diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp
index 98e4419e40..452f814231 100644
--- a/src/gui/text/qtextdocumentlayout.cpp
+++ b/src/gui/text/qtextdocumentlayout.cpp
@@ -7,7 +7,9 @@
#include "qtexttable.h"
#include "qtextlist.h"
#include "qtextengine_p.h"
+#if QT_CONFIG(cssparser)
#include "private/qcssutil_p.h"
+#endif
#include "private/qguiapplication_p.h"
#include "qabstracttextdocumentlayout_p.h"
@@ -23,6 +25,7 @@
#include <qbasictimer.h>
#include "private/qfunctions_p.h"
#include <qloggingcategory.h>
+#include <QtCore/qpointer.h>
#include <algorithm>
@@ -545,7 +548,7 @@ public:
QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, const QTextBlockFormat *previousBlockFormat);
void layoutFlow(QTextFrame::Iterator it, QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, QFixed width = 0);
- void floatMargins(const QFixed &y, const QTextLayoutStruct *layoutStruct, QFixed *left, QFixed *right) const;
+ void floatMargins(QFixed y, const QTextLayoutStruct *layoutStruct, QFixed *left, QFixed *right) const;
QFixed findY(QFixed yFrom, const QTextLayoutStruct *layoutStruct, QFixed requiredWidth) const;
QList<QCheckPoint> checkPoints;
@@ -794,7 +797,7 @@ QTextDocumentLayoutPrivate::hitTest(const QTextBlock &bl, const QFixedPoint &poi
textrect.translate(tl->position());
qCDebug(lcHit) << " checking block" << bl.position() << "point=" << point.toPointF() << " tlrect" << textrect;
*position = bl.position();
- if (point.y.toReal() < textrect.top()) {
+ if (point.y.toReal() < textrect.top() - bl.blockFormat().topMargin()) {
qCDebug(lcHit) << " before pos=" << *position;
return PointBefore;
} else if (point.y.toReal() > textrect.bottom()) {
@@ -1175,7 +1178,7 @@ void QTextDocumentLayoutPrivate::drawFrame(const QPointF &offset, QPainter *pain
it = frameIteratorForYPosition(QFixed::fromReal(context.clip.top()));
QList<QTextFrame *> floats;
- const int numFloats = fd->floats.count();
+ const int numFloats = fd->floats.size();
floats.reserve(numFloats);
for (int i = 0; i < numFloats; ++i)
floats.append(fd->floats.at(i));
@@ -1209,8 +1212,7 @@ static inline QTextFormat::Property borderPropertyForEdge(QCss::Edge edge)
case QCss::RightEdge:
return QTextFormat::TableCellRightBorder;
default:
- Q_UNREACHABLE();
- return QTextFormat::UserProperty;
+ Q_UNREACHABLE_RETURN(QTextFormat::UserProperty);
}
}
@@ -1226,8 +1228,7 @@ static inline QTextFormat::Property borderStylePropertyForEdge(QCss::Edge edge)
case QCss::RightEdge:
return QTextFormat::TableCellRightBorderStyle;
default:
- Q_UNREACHABLE();
- return QTextFormat::UserProperty;
+ Q_UNREACHABLE_RETURN(QTextFormat::UserProperty);
}
}
@@ -1243,8 +1244,7 @@ static inline QCss::Edge adjacentEdge(QCss::Edge edge)
case QCss::LeftEdge:
return QCss::RightEdge;
default:
- Q_UNREACHABLE();
- return QCss::NumEdges;
+ Q_UNREACHABLE_RETURN(QCss::NumEdges);
}
}
@@ -1323,8 +1323,7 @@ static inline bool sharesAxis(const QTextTableCell &cell, QCss::Edge edge,
return cell.column() + cell.columnSpan() ==
competingCell.column() + (competingCellEdge == QCss::LeftEdge ? 0 : competingCell.columnSpan());
default:
- Q_UNREACHABLE();
- return false;
+ Q_UNREACHABLE_RETURN(false);
}
}
@@ -1819,11 +1818,20 @@ void QTextDocumentLayoutPrivate::drawTableCell(const QRectF &cellRect, QPainter
if (r >= headerRowCount)
topMargin += td->headerHeight.toReal();
- if (!td->borderCollapse && td->border != 0) {
+ // If cell border configured, don't draw default border for cells. It will be taken care later by
+ // drawTableCellBorder().
+ bool cellBorderConfigured = (cell.format().hasProperty(QTextFormat::TableCellLeftBorder) ||
+ cell.format().hasProperty(QTextFormat::TableCellTopBorder) ||
+ cell.format().hasProperty(QTextFormat::TableCellRightBorder) ||
+ cell.format().hasProperty(QTextFormat::TableCellBottomBorder));
+
+ if (!td->borderCollapse && td->border != 0 && !cellBorderConfigured) {
const QBrush oldBrush = painter->brush();
const QPen oldPen = painter->pen();
- const qreal border = td->border.toReal();
+ // If border is configured for the table (and not explicitly for the cell), then
+ // always draw 1px border around the cell
+ const qreal border = 1;
QRectF borderRect(cellRect.left() - border, cellRect.top() - border, cellRect.width() + border, cellRect.height() + border);
@@ -1886,7 +1894,8 @@ void QTextDocumentLayoutPrivate::drawTableCell(const QRectF &cellRect, QPainter
}
// paint over the background - otherwise we would have to adjust the background paint cellRect for the border values
- drawTableCellBorder(cellRect, painter, table, td, cell);
+ if (cellBorderConfigured)
+ drawTableCellBorder(cellRect, painter, table, td, cell);
const QFixed verticalOffset = td->cellVerticalOffsets.at(c + r * table->columns());
@@ -1967,7 +1976,7 @@ void QTextDocumentLayoutPrivate::drawFlow(const QPointF &offset, QPainter *paint
previousFrame = c;
}
- for (int i = 0; i < floats.count(); ++i) {
+ for (int i = 0; i < floats.size(); ++i) {
QTextFrame *frame = floats.at(i);
if (!isFrameFromInlineObject(frame)
|| frame->frameFormat().position() == QTextFrameFormat::InFlow)
@@ -2072,7 +2081,7 @@ void QTextDocumentLayoutPrivate::drawBlock(const QPointF &offset, QPainter *pain
const qreal width = blockFormat.lengthProperty(QTextFormat::BlockTrailingHorizontalRulerWidth).value(r.width());
const auto color = blockFormat.hasProperty(QTextFormat::BackgroundBrush)
? qvariant_cast<QBrush>(blockFormat.property(QTextFormat::BackgroundBrush)).color()
- : context.palette.color(QPalette::Dark);
+ : context.palette.color(QPalette::Inactive, QPalette::WindowText);
painter->setPen(color);
qreal y = r.bottom();
if (bl.length() == 1)
@@ -2207,17 +2216,15 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p
}
case QTextListFormat::ListSquare:
if (!marker)
- painter->fillRect(r, brush);
+ painter->fillRect(r, painter->pen().brush());
break;
case QTextListFormat::ListCircle:
- if (!marker) {
- painter->setPen(QPen(brush, 0));
+ if (!marker)
painter->drawEllipse(r.translated(0.5, 0.5)); // pixel align for sharper rendering
- }
break;
case QTextListFormat::ListDisc:
if (!marker) {
- painter->setBrush(brush);
+ painter->setBrush(painter->pen().brush());
painter->setPen(Qt::NoPen);
painter->drawEllipse(r);
}
@@ -2368,7 +2375,7 @@ QRectF QTextDocumentLayoutPrivate::layoutTable(QTextTable *table, int layoutFrom
td->childFrameMap.clear();
{
const QList<QTextFrame *> children = table->childFrames();
- for (int i = 0; i < children.count(); ++i) {
+ for (int i = 0; i < children.size(); ++i) {
QTextFrame *frame = children.at(i);
QTextTableCell cell = table->cellAt(frame->firstPosition());
td->childFrameMap.insert(cell.row() + cell.column() * rows, frame);
@@ -2378,7 +2385,7 @@ QRectF QTextDocumentLayoutPrivate::layoutTable(QTextTable *table, int layoutFrom
QList<QTextLength> columnWidthConstraints = fmt.columnWidthConstraints();
if (columnWidthConstraints.size() != columns)
columnWidthConstraints.resize(columns);
- Q_ASSERT(columnWidthConstraints.count() == columns);
+ Q_ASSERT(columnWidthConstraints.size() == columns);
// borderCollapse will disable drawing the html4 style table cell borders
// and draw a 1px grid instead. This also sets a fixed cellspacing
@@ -2553,8 +2560,9 @@ recalc_minmax_widths:
const QFixed allottedPercentage = QFixed::fromReal(columnWidthConstraints.at(i).rawValue());
const QFixed percentWidth = totalPercentagedWidth * allottedPercentage / totalPercentage;
- if (percentWidth >= td->minWidths.at(i)) {
- td->widths[i] = qBound(td->minWidths.at(i), percentWidth, remainingWidth - remainingMinWidths);
+ QFixed maxWidth = remainingWidth - remainingMinWidths;
+ if (percentWidth >= td->minWidths.at(i) && maxWidth > td->minWidths.at(i)) {
+ td->widths[i] = qBound(td->minWidths.at(i), percentWidth, maxWidth);
} else {
td->widths[i] = td->minWidths.at(i);
}
@@ -2575,9 +2583,9 @@ recalc_minmax_widths:
QFixed lastRemainingWidth = remainingWidth;
while (remainingWidth > 0) {
- for (int k = 0; k < columnsWithProperMaxSize.count(); ++k) {
+ for (int k = 0; k < columnsWithProperMaxSize.size(); ++k) {
const int col = columnsWithProperMaxSize[k];
- const int colsLeft = columnsWithProperMaxSize.count() - k;
+ const int colsLeft = columnsWithProperMaxSize.size() - k;
const QFixed w = qMin(td->maxWidths.at(col) - td->widths.at(col), remainingWidth / colsLeft);
td->widths[col] += w;
remainingWidth -= w;
@@ -3112,7 +3120,7 @@ void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QTextLayout
QTextBlockFormat previousBlockFormat = previousIt.currentBlock().blockFormat();
QFixed maximumBlockWidth = 0;
- while (!it.atEnd()) {
+ while (!it.atEnd() && layoutStruct->absoluteY() < QFIXED_MAX) {
QTextFrame *c = it.currentFrame();
int docPos;
@@ -3349,7 +3357,7 @@ void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QTextLayout
// and not per cell and layoutCell already takes care of doing the same as we do here
if (!qobject_cast<QTextTable *>(layoutStruct->frame)) {
QList<QTextFrame *> children = layoutStruct->frame->childFrames();
- for (int i = 0; i < children.count(); ++i) {
+ for (int i = 0; i < children.size(); ++i) {
QTextFrameData *fd = data(children.at(i));
if (!fd->layoutDirty && children.at(i)->frameFormat().position() != QTextFrameFormat::InFlow)
layoutStruct->y = qMax(layoutStruct->y, fd->position.y + fd->size.height);
@@ -3362,7 +3370,7 @@ void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QTextLayout
if (!fd->floats.isEmpty())
contentHasAlignment = true;
- if (it.atEnd()) {
+ if (it.atEnd() || layoutStruct->absoluteY() >= QFIXED_MAX) {
//qDebug("layout done!");
currentLazyLayoutPosition = -1;
QCheckPoint cp;
@@ -3548,6 +3556,11 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi
while (layoutStruct->pageHeight > 0 && layoutStruct->absoluteY() + lineBreakHeight > layoutStruct->pageBottom &&
layoutStruct->contentHeight() >= lineBreakHeight) {
+ if (layoutStruct->pageHeight == QFIXED_MAX) {
+ layoutStruct->y = QFIXED_MAX - layoutStruct->frameY;
+ break;
+ }
+
layoutStruct->newPage();
floatMargins(layoutStruct->y, layoutStruct, &left, &right);
@@ -3631,7 +3644,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi
}
}
-void QTextDocumentLayoutPrivate::floatMargins(const QFixed &y, const QTextLayoutStruct *layoutStruct,
+void QTextDocumentLayoutPrivate::floatMargins(QFixed y, const QTextLayoutStruct *layoutStruct,
QFixed *left, QFixed *right) const
{
// qDebug() << "floatMargins y=" << y;
@@ -3850,7 +3863,7 @@ int QTextDocumentLayout::hitTest(const QPointF &point, Qt::HitTestAccuracy accur
// ensure we stay within document bounds
int lastPos = f->lastPosition();
if (l && !l->preeditAreaText().isEmpty())
- lastPos += l->preeditAreaText().length();
+ lastPos += l->preeditAreaText().size();
if (position > lastPos)
position = lastPos;
else if (position < 0)