Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/gui/text/qtextdocumentlayout.cpp |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /**************************************************************************** | - | ||||||||||||||||||||||||
2 | ** | - | ||||||||||||||||||||||||
3 | ** Copyright (C) 2016 The Qt Company Ltd. | - | ||||||||||||||||||||||||
4 | ** Contact: https://www.qt.io/licensing/ | - | ||||||||||||||||||||||||
5 | ** | - | ||||||||||||||||||||||||
6 | ** This file is part of the QtGui module of the Qt Toolkit. | - | ||||||||||||||||||||||||
7 | ** | - | ||||||||||||||||||||||||
8 | ** $QT_BEGIN_LICENSE:LGPL$ | - | ||||||||||||||||||||||||
9 | ** Commercial License Usage | - | ||||||||||||||||||||||||
10 | ** Licensees holding valid commercial Qt licenses may use this file in | - | ||||||||||||||||||||||||
11 | ** accordance with the commercial license agreement provided with the | - | ||||||||||||||||||||||||
12 | ** Software or, alternatively, in accordance with the terms contained in | - | ||||||||||||||||||||||||
13 | ** a written agreement between you and The Qt Company. For licensing terms | - | ||||||||||||||||||||||||
14 | ** and conditions see https://www.qt.io/terms-conditions. For further | - | ||||||||||||||||||||||||
15 | ** information use the contact form at https://www.qt.io/contact-us. | - | ||||||||||||||||||||||||
16 | ** | - | ||||||||||||||||||||||||
17 | ** GNU Lesser General Public License Usage | - | ||||||||||||||||||||||||
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | - | ||||||||||||||||||||||||
19 | ** General Public License version 3 as published by the Free Software | - | ||||||||||||||||||||||||
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the | - | ||||||||||||||||||||||||
21 | ** packaging of this file. Please review the following information to | - | ||||||||||||||||||||||||
22 | ** ensure the GNU Lesser General Public License version 3 requirements | - | ||||||||||||||||||||||||
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. | - | ||||||||||||||||||||||||
24 | ** | - | ||||||||||||||||||||||||
25 | ** GNU General Public License Usage | - | ||||||||||||||||||||||||
26 | ** Alternatively, this file may be used under the terms of the GNU | - | ||||||||||||||||||||||||
27 | ** General Public License version 2.0 or (at your option) the GNU General | - | ||||||||||||||||||||||||
28 | ** Public license version 3 or any later version approved by the KDE Free | - | ||||||||||||||||||||||||
29 | ** Qt Foundation. The licenses are as published by the Free Software | - | ||||||||||||||||||||||||
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 | - | ||||||||||||||||||||||||
31 | ** included in the packaging of this file. Please review the following | - | ||||||||||||||||||||||||
32 | ** information to ensure the GNU General Public License requirements will | - | ||||||||||||||||||||||||
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and | - | ||||||||||||||||||||||||
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. | - | ||||||||||||||||||||||||
35 | ** | - | ||||||||||||||||||||||||
36 | ** $QT_END_LICENSE$ | - | ||||||||||||||||||||||||
37 | ** | - | ||||||||||||||||||||||||
38 | ****************************************************************************/ | - | ||||||||||||||||||||||||
39 | - | |||||||||||||||||||||||||
40 | #include "qtextdocumentlayout_p.h" | - | ||||||||||||||||||||||||
41 | #include "qtextdocument_p.h" | - | ||||||||||||||||||||||||
42 | #include "qtextimagehandler_p.h" | - | ||||||||||||||||||||||||
43 | #include "qtexttable.h" | - | ||||||||||||||||||||||||
44 | #include "qtextlist.h" | - | ||||||||||||||||||||||||
45 | #include "qtextengine_p.h" | - | ||||||||||||||||||||||||
46 | #include "private/qcssutil_p.h" | - | ||||||||||||||||||||||||
47 | #include "private/qguiapplication_p.h" | - | ||||||||||||||||||||||||
48 | - | |||||||||||||||||||||||||
49 | #include "qabstracttextdocumentlayout_p.h" | - | ||||||||||||||||||||||||
50 | #include "qcssparser_p.h" | - | ||||||||||||||||||||||||
51 | - | |||||||||||||||||||||||||
52 | #include <qpainter.h> | - | ||||||||||||||||||||||||
53 | #include <qmath.h> | - | ||||||||||||||||||||||||
54 | #include <qrect.h> | - | ||||||||||||||||||||||||
55 | #include <qpalette.h> | - | ||||||||||||||||||||||||
56 | #include <qdebug.h> | - | ||||||||||||||||||||||||
57 | #include <qvarlengtharray.h> | - | ||||||||||||||||||||||||
58 | #include <limits.h> | - | ||||||||||||||||||||||||
59 | #include <qbasictimer.h> | - | ||||||||||||||||||||||||
60 | #include "private/qfunctions_p.h" | - | ||||||||||||||||||||||||
61 | - | |||||||||||||||||||||||||
62 | #include <algorithm> | - | ||||||||||||||||||||||||
63 | - | |||||||||||||||||||||||||
64 | // #define LAYOUT_DEBUG | - | ||||||||||||||||||||||||
65 | - | |||||||||||||||||||||||||
66 | #ifdef LAYOUT_DEBUG | - | ||||||||||||||||||||||||
67 | #define LDEBUG qDebug() | - | ||||||||||||||||||||||||
68 | #define INC_INDENT debug_indent += " " | - | ||||||||||||||||||||||||
69 | #define DEC_INDENT debug_indent = debug_indent.left(debug_indent.length()-2) | - | ||||||||||||||||||||||||
70 | #else | - | ||||||||||||||||||||||||
71 | #define LDEBUG if(0) qDebug() | - | ||||||||||||||||||||||||
72 | #define INC_INDENT do {} while(0) | - | ||||||||||||||||||||||||
73 | #define DEC_INDENT do {} while(0) | - | ||||||||||||||||||||||||
74 | #endif | - | ||||||||||||||||||||||||
75 | - | |||||||||||||||||||||||||
76 | QT_BEGIN_NAMESPACE | - | ||||||||||||||||||||||||
77 | - | |||||||||||||||||||||||||
78 | // ################ should probably add frameFormatChange notification! | - | ||||||||||||||||||||||||
79 | - | |||||||||||||||||||||||||
80 | struct QTextLayoutStruct; | - | ||||||||||||||||||||||||
81 | - | |||||||||||||||||||||||||
82 | class QTextFrameData : public QTextFrameLayoutData | - | ||||||||||||||||||||||||
83 | { | - | ||||||||||||||||||||||||
84 | public: | - | ||||||||||||||||||||||||
85 | QTextFrameData(); | - | ||||||||||||||||||||||||
86 | - | |||||||||||||||||||||||||
87 | // relative to parent frame | - | ||||||||||||||||||||||||
88 | QFixedPoint position; | - | ||||||||||||||||||||||||
89 | QFixedSize size; | - | ||||||||||||||||||||||||
90 | - | |||||||||||||||||||||||||
91 | // contents starts at (margin+border/margin+border) | - | ||||||||||||||||||||||||
92 | QFixed topMargin; | - | ||||||||||||||||||||||||
93 | QFixed bottomMargin; | - | ||||||||||||||||||||||||
94 | QFixed leftMargin; | - | ||||||||||||||||||||||||
95 | QFixed rightMargin; | - | ||||||||||||||||||||||||
96 | QFixed border; | - | ||||||||||||||||||||||||
97 | QFixed padding; | - | ||||||||||||||||||||||||
98 | // contents width includes padding (as we need to treat this on a per cell basis for tables) | - | ||||||||||||||||||||||||
99 | QFixed contentsWidth; | - | ||||||||||||||||||||||||
100 | QFixed contentsHeight; | - | ||||||||||||||||||||||||
101 | QFixed oldContentsWidth; | - | ||||||||||||||||||||||||
102 | - | |||||||||||||||||||||||||
103 | // accumulated margins | - | ||||||||||||||||||||||||
104 | QFixed effectiveTopMargin; | - | ||||||||||||||||||||||||
105 | QFixed effectiveBottomMargin; | - | ||||||||||||||||||||||||
106 | - | |||||||||||||||||||||||||
107 | QFixed minimumWidth; | - | ||||||||||||||||||||||||
108 | QFixed maximumWidth; | - | ||||||||||||||||||||||||
109 | - | |||||||||||||||||||||||||
110 | QTextLayoutStruct *currentLayoutStruct; | - | ||||||||||||||||||||||||
111 | - | |||||||||||||||||||||||||
112 | bool sizeDirty; | - | ||||||||||||||||||||||||
113 | bool layoutDirty; | - | ||||||||||||||||||||||||
114 | - | |||||||||||||||||||||||||
115 | QVector<QPointer<QTextFrame> > floats; | - | ||||||||||||||||||||||||
116 | }; | - | ||||||||||||||||||||||||
117 | - | |||||||||||||||||||||||||
118 | QTextFrameData::QTextFrameData() | - | ||||||||||||||||||||||||
119 | : maximumWidth(QFIXED_MAX), | - | ||||||||||||||||||||||||
120 | currentLayoutStruct(0), sizeDirty(true), layoutDirty(true) | - | ||||||||||||||||||||||||
121 | { | - | ||||||||||||||||||||||||
122 | } never executed: end of block | 0 | ||||||||||||||||||||||||
123 | - | |||||||||||||||||||||||||
124 | struct QTextLayoutStruct { | - | ||||||||||||||||||||||||
125 | QTextLayoutStruct() : maximumWidth(QFIXED_MAX), fullLayout(false) | - | ||||||||||||||||||||||||
126 | {} never executed: end of block | 0 | ||||||||||||||||||||||||
127 | QTextFrame *frame; | - | ||||||||||||||||||||||||
128 | QFixed x_left; | - | ||||||||||||||||||||||||
129 | QFixed x_right; | - | ||||||||||||||||||||||||
130 | QFixed frameY; // absolute y position of the current frame | - | ||||||||||||||||||||||||
131 | QFixed y; // always relative to the current frame | - | ||||||||||||||||||||||||
132 | QFixed contentsWidth; | - | ||||||||||||||||||||||||
133 | QFixed minimumWidth; | - | ||||||||||||||||||||||||
134 | QFixed maximumWidth; | - | ||||||||||||||||||||||||
135 | bool fullLayout; | - | ||||||||||||||||||||||||
136 | QList<QTextFrame *> pendingFloats; | - | ||||||||||||||||||||||||
137 | QFixed pageHeight; | - | ||||||||||||||||||||||||
138 | QFixed pageBottom; | - | ||||||||||||||||||||||||
139 | QFixed pageTopMargin; | - | ||||||||||||||||||||||||
140 | QFixed pageBottomMargin; | - | ||||||||||||||||||||||||
141 | QRectF updateRect; | - | ||||||||||||||||||||||||
142 | QRectF updateRectForFloats; | - | ||||||||||||||||||||||||
143 | - | |||||||||||||||||||||||||
144 | inline void addUpdateRectForFloat(const QRectF &rect) { | - | ||||||||||||||||||||||||
145 | if (updateRectForFloats.isValid())
| 0 | ||||||||||||||||||||||||
146 | updateRectForFloats |= rect; never executed: updateRectForFloats |= rect; | 0 | ||||||||||||||||||||||||
147 | else | - | ||||||||||||||||||||||||
148 | updateRectForFloats = rect; never executed: updateRectForFloats = rect; | 0 | ||||||||||||||||||||||||
149 | } | - | ||||||||||||||||||||||||
150 | - | |||||||||||||||||||||||||
151 | inline QFixed absoluteY() const | - | ||||||||||||||||||||||||
152 | { return frameY + y; } never executed: return frameY + y; | 0 | ||||||||||||||||||||||||
153 | - | |||||||||||||||||||||||||
154 | inline int currentPage() const | - | ||||||||||||||||||||||||
155 | { return pageHeight == 0 ? 0 : (absoluteY() / pageHeight).truncate(); } never executed: return pageHeight == 0 ? 0 : (absoluteY() / pageHeight).truncate(); | 0 | ||||||||||||||||||||||||
156 | - | |||||||||||||||||||||||||
157 | inline void newPage() | - | ||||||||||||||||||||||||
158 | { if (pageHeight == QFIXED_MAX) return; pageBottom += pageHeight; y = pageBottom - pageHeight + pageBottomMargin + pageTopMargin - frameY; } never executed: return; never executed: end of block
| 0 | ||||||||||||||||||||||||
159 | }; | - | ||||||||||||||||||||||||
160 | - | |||||||||||||||||||||||||
161 | class QTextTableData : public QTextFrameData | - | ||||||||||||||||||||||||
162 | { | - | ||||||||||||||||||||||||
163 | public: | - | ||||||||||||||||||||||||
164 | QFixed cellSpacing, cellPadding; | - | ||||||||||||||||||||||||
165 | qreal deviceScale; | - | ||||||||||||||||||||||||
166 | QVector<QFixed> minWidths; | - | ||||||||||||||||||||||||
167 | QVector<QFixed> maxWidths; | - | ||||||||||||||||||||||||
168 | QVector<QFixed> widths; | - | ||||||||||||||||||||||||
169 | QVector<QFixed> heights; | - | ||||||||||||||||||||||||
170 | QVector<QFixed> columnPositions; | - | ||||||||||||||||||||||||
171 | QVector<QFixed> rowPositions; | - | ||||||||||||||||||||||||
172 | - | |||||||||||||||||||||||||
173 | QVector<QFixed> cellVerticalOffsets; | - | ||||||||||||||||||||||||
174 | - | |||||||||||||||||||||||||
175 | QFixed headerHeight; | - | ||||||||||||||||||||||||
176 | - | |||||||||||||||||||||||||
177 | // maps from cell index (row + col * rowCount) to child frames belonging to | - | ||||||||||||||||||||||||
178 | // the specific cell | - | ||||||||||||||||||||||||
179 | QMultiHash<int, QTextFrame *> childFrameMap; | - | ||||||||||||||||||||||||
180 | - | |||||||||||||||||||||||||
181 | inline QFixed cellWidth(int column, int colspan) const | - | ||||||||||||||||||||||||
182 | { return columnPositions.at(column + colspan - 1) + widths.at(column + colspan - 1) never executed: return columnPositions.at(column + colspan - 1) + widths.at(column + colspan - 1) - columnPositions.at(column); | 0 | ||||||||||||||||||||||||
183 | - columnPositions.at(column); } never executed: return columnPositions.at(column + colspan - 1) + widths.at(column + colspan - 1) - columnPositions.at(column); | 0 | ||||||||||||||||||||||||
184 | - | |||||||||||||||||||||||||
185 | inline void calcRowPosition(int row) | - | ||||||||||||||||||||||||
186 | { | - | ||||||||||||||||||||||||
187 | if (row > 0)
| 0 | ||||||||||||||||||||||||
188 | rowPositions[row] = rowPositions.at(row - 1) + heights.at(row - 1) + border + cellSpacing + border; never executed: rowPositions[row] = rowPositions.at(row - 1) + heights.at(row - 1) + border + cellSpacing + border; | 0 | ||||||||||||||||||||||||
189 | } never executed: end of block | 0 | ||||||||||||||||||||||||
190 | - | |||||||||||||||||||||||||
191 | QRectF cellRect(const QTextTableCell &cell) const; | - | ||||||||||||||||||||||||
192 | - | |||||||||||||||||||||||||
193 | inline QFixed paddingProperty(const QTextFormat &format, QTextFormat::Property property) const | - | ||||||||||||||||||||||||
194 | { | - | ||||||||||||||||||||||||
195 | QVariant v = format.property(property); | - | ||||||||||||||||||||||||
196 | if (v.isNull()) {
| 0 | ||||||||||||||||||||||||
197 | return cellPadding; never executed: return cellPadding; | 0 | ||||||||||||||||||||||||
198 | } else { | - | ||||||||||||||||||||||||
199 | Q_ASSERT(v.userType() == QVariant::Double || v.userType() == QMetaType::Float); | - | ||||||||||||||||||||||||
200 | return QFixed::fromReal(v.toReal() * deviceScale); never executed: return QFixed::fromReal(v.toReal() * deviceScale); | 0 | ||||||||||||||||||||||||
201 | } | - | ||||||||||||||||||||||||
202 | } | - | ||||||||||||||||||||||||
203 | - | |||||||||||||||||||||||||
204 | inline QFixed topPadding(const QTextFormat &format) const | - | ||||||||||||||||||||||||
205 | { | - | ||||||||||||||||||||||||
206 | return paddingProperty(format, QTextFormat::TableCellTopPadding); never executed: return paddingProperty(format, QTextFormat::TableCellTopPadding); | 0 | ||||||||||||||||||||||||
207 | } | - | ||||||||||||||||||||||||
208 | - | |||||||||||||||||||||||||
209 | inline QFixed bottomPadding(const QTextFormat &format) const | - | ||||||||||||||||||||||||
210 | { | - | ||||||||||||||||||||||||
211 | return paddingProperty(format, QTextFormat::TableCellBottomPadding); never executed: return paddingProperty(format, QTextFormat::TableCellBottomPadding); | 0 | ||||||||||||||||||||||||
212 | } | - | ||||||||||||||||||||||||
213 | - | |||||||||||||||||||||||||
214 | inline QFixed leftPadding(const QTextFormat &format) const | - | ||||||||||||||||||||||||
215 | { | - | ||||||||||||||||||||||||
216 | return paddingProperty(format, QTextFormat::TableCellLeftPadding); never executed: return paddingProperty(format, QTextFormat::TableCellLeftPadding); | 0 | ||||||||||||||||||||||||
217 | } | - | ||||||||||||||||||||||||
218 | - | |||||||||||||||||||||||||
219 | inline QFixed rightPadding(const QTextFormat &format) const | - | ||||||||||||||||||||||||
220 | { | - | ||||||||||||||||||||||||
221 | return paddingProperty(format, QTextFormat::TableCellRightPadding); never executed: return paddingProperty(format, QTextFormat::TableCellRightPadding); | 0 | ||||||||||||||||||||||||
222 | } | - | ||||||||||||||||||||||||
223 | - | |||||||||||||||||||||||||
224 | inline QFixedPoint cellPosition(const QTextTableCell &cell) const | - | ||||||||||||||||||||||||
225 | { | - | ||||||||||||||||||||||||
226 | const QTextFormat fmt = cell.format(); | - | ||||||||||||||||||||||||
227 | return cellPosition(cell.row(), cell.column()) + QFixedPoint(leftPadding(fmt), topPadding(fmt)); never executed: return cellPosition(cell.row(), cell.column()) + QFixedPoint(leftPadding(fmt), topPadding(fmt)); | 0 | ||||||||||||||||||||||||
228 | } | - | ||||||||||||||||||||||||
229 | - | |||||||||||||||||||||||||
230 | void updateTableSize(); | - | ||||||||||||||||||||||||
231 | - | |||||||||||||||||||||||||
232 | private: | - | ||||||||||||||||||||||||
233 | inline QFixedPoint cellPosition(int row, int col) const | - | ||||||||||||||||||||||||
234 | { return QFixedPoint(columnPositions.at(col), rowPositions.at(row) + cellVerticalOffsets.at(col + row * widths.size())); } never executed: return QFixedPoint(columnPositions.at(col), rowPositions.at(row) + cellVerticalOffsets.at(col + row * widths.size())); | 0 | ||||||||||||||||||||||||
235 | }; | - | ||||||||||||||||||||||||
236 | - | |||||||||||||||||||||||||
237 | static QTextFrameData *createData(QTextFrame *f) | - | ||||||||||||||||||||||||
238 | { | - | ||||||||||||||||||||||||
239 | QTextFrameData *data; | - | ||||||||||||||||||||||||
240 | if (qobject_cast<QTextTable *>(f))
| 0 | ||||||||||||||||||||||||
241 | data = new QTextTableData; never executed: data = new QTextTableData; | 0 | ||||||||||||||||||||||||
242 | else | - | ||||||||||||||||||||||||
243 | data = new QTextFrameData; never executed: data = new QTextFrameData; | 0 | ||||||||||||||||||||||||
244 | f->setLayoutData(data); | - | ||||||||||||||||||||||||
245 | return data; never executed: return data; | 0 | ||||||||||||||||||||||||
246 | } | - | ||||||||||||||||||||||||
247 | - | |||||||||||||||||||||||||
248 | static inline QTextFrameData *data(QTextFrame *f) | - | ||||||||||||||||||||||||
249 | { | - | ||||||||||||||||||||||||
250 | QTextFrameData *data = static_cast<QTextFrameData *>(f->layoutData()); | - | ||||||||||||||||||||||||
251 | if (!data)
| 0 | ||||||||||||||||||||||||
252 | data = createData(f); never executed: data = createData(f); | 0 | ||||||||||||||||||||||||
253 | return data; never executed: return data; | 0 | ||||||||||||||||||||||||
254 | } | - | ||||||||||||||||||||||||
255 | - | |||||||||||||||||||||||||
256 | static bool isFrameFromInlineObject(QTextFrame *f) | - | ||||||||||||||||||||||||
257 | { | - | ||||||||||||||||||||||||
258 | return f->firstPosition() > f->lastPosition(); never executed: return f->firstPosition() > f->lastPosition(); | 0 | ||||||||||||||||||||||||
259 | } | - | ||||||||||||||||||||||||
260 | - | |||||||||||||||||||||||||
261 | void QTextTableData::updateTableSize() | - | ||||||||||||||||||||||||
262 | { | - | ||||||||||||||||||||||||
263 | const QFixed effectiveTopMargin = this->topMargin + border + padding; | - | ||||||||||||||||||||||||
264 | const QFixed effectiveBottomMargin = this->bottomMargin + border + padding; | - | ||||||||||||||||||||||||
265 | const QFixed effectiveLeftMargin = this->leftMargin + border + padding; | - | ||||||||||||||||||||||||
266 | const QFixed effectiveRightMargin = this->rightMargin + border + padding; | - | ||||||||||||||||||||||||
267 | size.height = contentsHeight == -1
| 0 | ||||||||||||||||||||||||
268 | ? rowPositions.constLast() + heights.constLast() + padding + border + cellSpacing + effectiveBottomMargin | - | ||||||||||||||||||||||||
269 | : effectiveTopMargin + contentsHeight + effectiveBottomMargin; | - | ||||||||||||||||||||||||
270 | size.width = effectiveLeftMargin + contentsWidth + effectiveRightMargin; | - | ||||||||||||||||||||||||
271 | } never executed: end of block | 0 | ||||||||||||||||||||||||
272 | - | |||||||||||||||||||||||||
273 | QRectF QTextTableData::cellRect(const QTextTableCell &cell) const | - | ||||||||||||||||||||||||
274 | { | - | ||||||||||||||||||||||||
275 | const int row = cell.row(); | - | ||||||||||||||||||||||||
276 | const int rowSpan = cell.rowSpan(); | - | ||||||||||||||||||||||||
277 | const int column = cell.column(); | - | ||||||||||||||||||||||||
278 | const int colSpan = cell.columnSpan(); | - | ||||||||||||||||||||||||
279 | - | |||||||||||||||||||||||||
280 | return QRectF(columnPositions.at(column).toReal(), never executed: return QRectF(columnPositions.at(column).toReal(), rowPositions.at(row).toReal(), (columnPositions.at(column + colSpan - 1) + widths.at(column + colSpan - 1) - columnPositions.at(column)).toReal(), (rowPositions.at(row + rowSpan - 1) + heights.at(row + rowSpan - 1) - rowPositions.at(row)).toReal()); | 0 | ||||||||||||||||||||||||
281 | rowPositions.at(row).toReal(), never executed: return QRectF(columnPositions.at(column).toReal(), rowPositions.at(row).toReal(), (columnPositions.at(column + colSpan - 1) + widths.at(column + colSpan - 1) - columnPositions.at(column)).toReal(), (rowPositions.at(row + rowSpan - 1) + heights.at(row + rowSpan - 1) - rowPositions.at(row)).toReal()); | 0 | ||||||||||||||||||||||||
282 | (columnPositions.at(column + colSpan - 1) + widths.at(column + colSpan - 1) - columnPositions.at(column)).toReal(), never executed: return QRectF(columnPositions.at(column).toReal(), rowPositions.at(row).toReal(), (columnPositions.at(column + colSpan - 1) + widths.at(column + colSpan - 1) - columnPositions.at(column)).toReal(), (rowPositions.at(row + rowSpan - 1) + heights.at(row + rowSpan - 1) - rowPositions.at(row)).toReal()); | 0 | ||||||||||||||||||||||||
283 | (rowPositions.at(row + rowSpan - 1) + heights.at(row + rowSpan - 1) - rowPositions.at(row)).toReal()); never executed: return QRectF(columnPositions.at(column).toReal(), rowPositions.at(row).toReal(), (columnPositions.at(column + colSpan - 1) + widths.at(column + colSpan - 1) - columnPositions.at(column)).toReal(), (rowPositions.at(row + rowSpan - 1) + heights.at(row + rowSpan - 1) - rowPositions.at(row)).toReal()); | 0 | ||||||||||||||||||||||||
284 | } | - | ||||||||||||||||||||||||
285 | - | |||||||||||||||||||||||||
286 | static inline bool isEmptyBlockBeforeTable(const QTextBlock &block, const QTextBlockFormat &format, const QTextFrame::Iterator &nextIt) | - | ||||||||||||||||||||||||
287 | { | - | ||||||||||||||||||||||||
288 | return !nextIt.atEnd() never executed: return !nextIt.atEnd() && qobject_cast<QTextTable *>(nextIt.currentFrame()) && block.isValid() && block.length() == 1 && !format.hasProperty(QTextFormat::BlockTrailingHorizontalRulerWidth) && !format.hasProperty(QTextFormat::BackgroundBrush) && nextIt.currentFrame()->firstPosition() == block.position() + 1 ; | 0 | ||||||||||||||||||||||||
289 | && qobject_cast<QTextTable *>(nextIt.currentFrame()) never executed: return !nextIt.atEnd() && qobject_cast<QTextTable *>(nextIt.currentFrame()) && block.isValid() && block.length() == 1 && !format.hasProperty(QTextFormat::BlockTrailingHorizontalRulerWidth) && !format.hasProperty(QTextFormat::BackgroundBrush) && nextIt.currentFrame()->firstPosition() == block.position() + 1 ; | 0 | ||||||||||||||||||||||||
290 | && block.isValid() never executed: return !nextIt.atEnd() && qobject_cast<QTextTable *>(nextIt.currentFrame()) && block.isValid() && block.length() == 1 && !format.hasProperty(QTextFormat::BlockTrailingHorizontalRulerWidth) && !format.hasProperty(QTextFormat::BackgroundBrush) && nextIt.currentFrame()->firstPosition() == block.position() + 1 ; | 0 | ||||||||||||||||||||||||
291 | && block.length() == 1 never executed: return !nextIt.atEnd() && qobject_cast<QTextTable *>(nextIt.currentFrame()) && block.isValid() && block.length() == 1 && !format.hasProperty(QTextFormat::BlockTrailingHorizontalRulerWidth) && !format.hasProperty(QTextFormat::BackgroundBrush) && nextIt.currentFrame()->firstPosition() == block.position() + 1 ; | 0 | ||||||||||||||||||||||||
292 | && !format.hasProperty(QTextFormat::BlockTrailingHorizontalRulerWidth) never executed: return !nextIt.atEnd() && qobject_cast<QTextTable *>(nextIt.currentFrame()) && block.isValid() && block.length() == 1 && !format.hasProperty(QTextFormat::BlockTrailingHorizontalRulerWidth) && !format.hasProperty(QTextFormat::BackgroundBrush) && nextIt.currentFrame()->firstPosition() == block.position() + 1 ; | 0 | ||||||||||||||||||||||||
293 | && !format.hasProperty(QTextFormat::BackgroundBrush) never executed: return !nextIt.atEnd() && qobject_cast<QTextTable *>(nextIt.currentFrame()) && block.isValid() && block.length() == 1 && !format.hasProperty(QTextFormat::BlockTrailingHorizontalRulerWidth) && !format.hasProperty(QTextFormat::BackgroundBrush) && nextIt.currentFrame()->firstPosition() == block.position() + 1 ; | 0 | ||||||||||||||||||||||||
294 | && nextIt.currentFrame()->firstPosition() == block.position() + 1 never executed: return !nextIt.atEnd() && qobject_cast<QTextTable *>(nextIt.currentFrame()) && block.isValid() && block.length() == 1 && !format.hasProperty(QTextFormat::BlockTrailingHorizontalRulerWidth) && !format.hasProperty(QTextFormat::BackgroundBrush) && nextIt.currentFrame()->firstPosition() == block.position() + 1 ; | 0 | ||||||||||||||||||||||||
295 | ; never executed: return !nextIt.atEnd() && qobject_cast<QTextTable *>(nextIt.currentFrame()) && block.isValid() && block.length() == 1 && !format.hasProperty(QTextFormat::BlockTrailingHorizontalRulerWidth) && !format.hasProperty(QTextFormat::BackgroundBrush) && nextIt.currentFrame()->firstPosition() == block.position() + 1 ; | 0 | ||||||||||||||||||||||||
296 | } | - | ||||||||||||||||||||||||
297 | - | |||||||||||||||||||||||||
298 | static inline bool isEmptyBlockBeforeTable(QTextFrame::Iterator it) | - | ||||||||||||||||||||||||
299 | { | - | ||||||||||||||||||||||||
300 | QTextFrame::Iterator next = it; ++next; | - | ||||||||||||||||||||||||
301 | if (it.currentFrame())
| 0 | ||||||||||||||||||||||||
302 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||
303 | QTextBlock block = it.currentBlock(); | - | ||||||||||||||||||||||||
304 | return isEmptyBlockBeforeTable(block, block.blockFormat(), next); never executed: return isEmptyBlockBeforeTable(block, block.blockFormat(), next); | 0 | ||||||||||||||||||||||||
305 | } | - | ||||||||||||||||||||||||
306 | - | |||||||||||||||||||||||||
307 | static inline bool isEmptyBlockAfterTable(const QTextBlock &block, const QTextFrame *previousFrame) | - | ||||||||||||||||||||||||
308 | { | - | ||||||||||||||||||||||||
309 | return qobject_cast<const QTextTable *>(previousFrame) never executed: return qobject_cast<const QTextTable *>(previousFrame) && block.isValid() && block.length() == 1 && previousFrame->lastPosition() == block.position() - 1 ; | 0 | ||||||||||||||||||||||||
310 | && block.isValid() never executed: return qobject_cast<const QTextTable *>(previousFrame) && block.isValid() && block.length() == 1 && previousFrame->lastPosition() == block.position() - 1 ; | 0 | ||||||||||||||||||||||||
311 | && block.length() == 1 never executed: return qobject_cast<const QTextTable *>(previousFrame) && block.isValid() && block.length() == 1 && previousFrame->lastPosition() == block.position() - 1 ; | 0 | ||||||||||||||||||||||||
312 | && previousFrame->lastPosition() == block.position() - 1 never executed: return qobject_cast<const QTextTable *>(previousFrame) && block.isValid() && block.length() == 1 && previousFrame->lastPosition() == block.position() - 1 ; | 0 | ||||||||||||||||||||||||
313 | ; never executed: return qobject_cast<const QTextTable *>(previousFrame) && block.isValid() && block.length() == 1 && previousFrame->lastPosition() == block.position() - 1 ; | 0 | ||||||||||||||||||||||||
314 | } | - | ||||||||||||||||||||||||
315 | - | |||||||||||||||||||||||||
316 | static inline bool isLineSeparatorBlockAfterTable(const QTextBlock &block, const QTextFrame *previousFrame) | - | ||||||||||||||||||||||||
317 | { | - | ||||||||||||||||||||||||
318 | return qobject_cast<const QTextTable *>(previousFrame) never executed: return qobject_cast<const QTextTable *>(previousFrame) && block.isValid() && block.length() > 1 && block.text().at(0) == QChar::LineSeparator && previousFrame->lastPosition() == block.position() - 1 ; | 0 | ||||||||||||||||||||||||
319 | && block.isValid() never executed: return qobject_cast<const QTextTable *>(previousFrame) && block.isValid() && block.length() > 1 && block.text().at(0) == QChar::LineSeparator && previousFrame->lastPosition() == block.position() - 1 ; | 0 | ||||||||||||||||||||||||
320 | && block.length() > 1 never executed: return qobject_cast<const QTextTable *>(previousFrame) && block.isValid() && block.length() > 1 && block.text().at(0) == QChar::LineSeparator && previousFrame->lastPosition() == block.position() - 1 ; | 0 | ||||||||||||||||||||||||
321 | && block.text().at(0) == QChar::LineSeparator never executed: return qobject_cast<const QTextTable *>(previousFrame) && block.isValid() && block.length() > 1 && block.text().at(0) == QChar::LineSeparator && previousFrame->lastPosition() == block.position() - 1 ; | 0 | ||||||||||||||||||||||||
322 | && previousFrame->lastPosition() == block.position() - 1 never executed: return qobject_cast<const QTextTable *>(previousFrame) && block.isValid() && block.length() > 1 && block.text().at(0) == QChar::LineSeparator && previousFrame->lastPosition() == block.position() - 1 ; | 0 | ||||||||||||||||||||||||
323 | ; never executed: return qobject_cast<const QTextTable *>(previousFrame) && block.isValid() && block.length() > 1 && block.text().at(0) == QChar::LineSeparator && previousFrame->lastPosition() == block.position() - 1 ; | 0 | ||||||||||||||||||||||||
324 | } | - | ||||||||||||||||||||||||
325 | - | |||||||||||||||||||||||||
326 | /* | - | ||||||||||||||||||||||||
327 | - | |||||||||||||||||||||||||
328 | Optimization strategies: | - | ||||||||||||||||||||||||
329 | - | |||||||||||||||||||||||||
330 | HTML layout: | - | ||||||||||||||||||||||||
331 | - | |||||||||||||||||||||||||
332 | * Distinguish between normal and special flow. For normal flow the condition: | - | ||||||||||||||||||||||||
333 | y1 > y2 holds for all blocks with b1.key() > b2.key(). | - | ||||||||||||||||||||||||
334 | * Special flow is: floats, table cells | - | ||||||||||||||||||||||||
335 | - | |||||||||||||||||||||||||
336 | * Normal flow within table cells. Tables (not cells) are part of the normal flow. | - | ||||||||||||||||||||||||
337 | - | |||||||||||||||||||||||||
338 | - | |||||||||||||||||||||||||
339 | * If blocks grows/shrinks in height and extends over whole page width at the end, move following blocks. | - | ||||||||||||||||||||||||
340 | * If height doesn't change, no need to do anything | - | ||||||||||||||||||||||||
341 | - | |||||||||||||||||||||||||
342 | Table cells: | - | ||||||||||||||||||||||||
343 | - | |||||||||||||||||||||||||
344 | * If minWidth of cell changes, recalculate table width, relayout if needed. | - | ||||||||||||||||||||||||
345 | * What about maxWidth when doing auto layout? | - | ||||||||||||||||||||||||
346 | - | |||||||||||||||||||||||||
347 | Floats: | - | ||||||||||||||||||||||||
348 | * need fixed or proportional width, otherwise don't float! | - | ||||||||||||||||||||||||
349 | * On width/height change relayout surrounding paragraphs. | - | ||||||||||||||||||||||||
350 | - | |||||||||||||||||||||||||
351 | Document width change: | - | ||||||||||||||||||||||||
352 | * full relayout needed | - | ||||||||||||||||||||||||
353 | - | |||||||||||||||||||||||||
354 | - | |||||||||||||||||||||||||
355 | Float handling: | - | ||||||||||||||||||||||||
356 | - | |||||||||||||||||||||||||
357 | * Floats are specified by a special format object. | - | ||||||||||||||||||||||||
358 | * currently only floating images are implemented. | - | ||||||||||||||||||||||||
359 | - | |||||||||||||||||||||||||
360 | */ | - | ||||||||||||||||||||||||
361 | - | |||||||||||||||||||||||||
362 | /* | - | ||||||||||||||||||||||||
363 | - | |||||||||||||||||||||||||
364 | On the table layouting: | - | ||||||||||||||||||||||||
365 | - | |||||||||||||||||||||||||
366 | +---[ table border ]------------------------- | - | ||||||||||||||||||||||||
367 | | [ cell spacing ] | - | ||||||||||||||||||||||||
368 | | +------[ cell border ]-----+ +-------- | - | ||||||||||||||||||||||||
369 | | | | | | - | ||||||||||||||||||||||||
370 | | | | - | ||||||||||||||||||||||||
371 | | | | - | ||||||||||||||||||||||||
372 | | | | - | ||||||||||||||||||||||||
373 | | | - | ||||||||||||||||||||||||
374 | - | |||||||||||||||||||||||||
375 | rowPositions[i] and columnPositions[i] point at the cell content | - | ||||||||||||||||||||||||
376 | position. So for example the left border is drawn at | - | ||||||||||||||||||||||||
377 | x = columnPositions[i] - fd->border and similar for y. | - | ||||||||||||||||||||||||
378 | - | |||||||||||||||||||||||||
379 | */ | - | ||||||||||||||||||||||||
380 | - | |||||||||||||||||||||||||
381 | struct QCheckPoint | - | ||||||||||||||||||||||||
382 | { | - | ||||||||||||||||||||||||
383 | QFixed y; | - | ||||||||||||||||||||||||
384 | QFixed frameY; // absolute y position of the current frame | - | ||||||||||||||||||||||||
385 | int positionInFrame; | - | ||||||||||||||||||||||||
386 | QFixed minimumWidth; | - | ||||||||||||||||||||||||
387 | QFixed maximumWidth; | - | ||||||||||||||||||||||||
388 | QFixed contentsWidth; | - | ||||||||||||||||||||||||
389 | }; | - | ||||||||||||||||||||||||
390 | Q_DECLARE_TYPEINFO(QCheckPoint, Q_PRIMITIVE_TYPE); | - | ||||||||||||||||||||||||
391 | - | |||||||||||||||||||||||||
392 | static bool operator<(const QCheckPoint &checkPoint, QFixed y) | - | ||||||||||||||||||||||||
393 | { | - | ||||||||||||||||||||||||
394 | return checkPoint.y < y; never executed: return checkPoint.y < y; | 0 | ||||||||||||||||||||||||
395 | } | - | ||||||||||||||||||||||||
396 | - | |||||||||||||||||||||||||
397 | static bool operator<(const QCheckPoint &checkPoint, int pos) | - | ||||||||||||||||||||||||
398 | { | - | ||||||||||||||||||||||||
399 | return checkPoint.positionInFrame < pos; never executed: return checkPoint.positionInFrame < pos; | 0 | ||||||||||||||||||||||||
400 | } | - | ||||||||||||||||||||||||
401 | - | |||||||||||||||||||||||||
402 | #if defined(Q_CC_MSVC) && _MSC_VER < 1600 | - | ||||||||||||||||||||||||
403 | //The STL implementation of MSVC 2008 requires the definitions | - | ||||||||||||||||||||||||
404 | - | |||||||||||||||||||||||||
405 | static bool operator<(const QCheckPoint &checkPoint1, const QCheckPoint &checkPoint2) | - | ||||||||||||||||||||||||
406 | { | - | ||||||||||||||||||||||||
407 | return checkPoint1.y < checkPoint2.y; | - | ||||||||||||||||||||||||
408 | } | - | ||||||||||||||||||||||||
409 | - | |||||||||||||||||||||||||
410 | static bool operator<(QFixed y, const QCheckPoint &checkPoint) | - | ||||||||||||||||||||||||
411 | { | - | ||||||||||||||||||||||||
412 | return y < checkPoint.y; | - | ||||||||||||||||||||||||
413 | } | - | ||||||||||||||||||||||||
414 | - | |||||||||||||||||||||||||
415 | static bool operator<(int pos, const QCheckPoint &checkPoint) | - | ||||||||||||||||||||||||
416 | { | - | ||||||||||||||||||||||||
417 | return pos < checkPoint.positionInFrame; | - | ||||||||||||||||||||||||
418 | } | - | ||||||||||||||||||||||||
419 | - | |||||||||||||||||||||||||
420 | #endif | - | ||||||||||||||||||||||||
421 | - | |||||||||||||||||||||||||
422 | static void fillBackground(QPainter *p, const QRectF &rect, QBrush brush, const QPointF &origin, QRectF gradientRect = QRectF()) | - | ||||||||||||||||||||||||
423 | { | - | ||||||||||||||||||||||||
424 | p->save(); | - | ||||||||||||||||||||||||
425 | if (brush.style() >= Qt::LinearGradientPattern && brush.style() <= Qt::ConicalGradientPattern) {
| 0 | ||||||||||||||||||||||||
426 | if (!gradientRect.isNull()) {
| 0 | ||||||||||||||||||||||||
427 | QTransform m; | - | ||||||||||||||||||||||||
428 | m.translate(gradientRect.left(), gradientRect.top()); | - | ||||||||||||||||||||||||
429 | m.scale(gradientRect.width(), gradientRect.height()); | - | ||||||||||||||||||||||||
430 | brush.setTransform(m); | - | ||||||||||||||||||||||||
431 | const_cast<QGradient *>(brush.gradient())->setCoordinateMode(QGradient::LogicalMode); | - | ||||||||||||||||||||||||
432 | } never executed: end of block | 0 | ||||||||||||||||||||||||
433 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
434 | p->setBrushOrigin(origin); | - | ||||||||||||||||||||||||
435 | } never executed: end of block | 0 | ||||||||||||||||||||||||
436 | p->fillRect(rect, brush); | - | ||||||||||||||||||||||||
437 | p->restore(); | - | ||||||||||||||||||||||||
438 | } never executed: end of block | 0 | ||||||||||||||||||||||||
439 | - | |||||||||||||||||||||||||
440 | class QTextDocumentLayoutPrivate : public QAbstractTextDocumentLayoutPrivate | - | ||||||||||||||||||||||||
441 | { | - | ||||||||||||||||||||||||
442 | Q_DECLARE_PUBLIC(QTextDocumentLayout) | - | ||||||||||||||||||||||||
443 | public: | - | ||||||||||||||||||||||||
444 | QTextDocumentLayoutPrivate(); | - | ||||||||||||||||||||||||
445 | - | |||||||||||||||||||||||||
446 | QTextOption::WrapMode wordWrapMode; | - | ||||||||||||||||||||||||
447 | #ifdef LAYOUT_DEBUG | - | ||||||||||||||||||||||||
448 | mutable QString debug_indent; | - | ||||||||||||||||||||||||
449 | #endif | - | ||||||||||||||||||||||||
450 | - | |||||||||||||||||||||||||
451 | int fixedColumnWidth; | - | ||||||||||||||||||||||||
452 | int cursorWidth; | - | ||||||||||||||||||||||||
453 | - | |||||||||||||||||||||||||
454 | QSizeF lastReportedSize; | - | ||||||||||||||||||||||||
455 | QRectF viewportRect; | - | ||||||||||||||||||||||||
456 | QRectF clipRect; | - | ||||||||||||||||||||||||
457 | - | |||||||||||||||||||||||||
458 | mutable int currentLazyLayoutPosition; | - | ||||||||||||||||||||||||
459 | mutable int lazyLayoutStepSize; | - | ||||||||||||||||||||||||
460 | QBasicTimer layoutTimer; | - | ||||||||||||||||||||||||
461 | mutable QBasicTimer sizeChangedTimer; | - | ||||||||||||||||||||||||
462 | uint showLayoutProgress : 1; | - | ||||||||||||||||||||||||
463 | uint insideDocumentChange : 1; | - | ||||||||||||||||||||||||
464 | - | |||||||||||||||||||||||||
465 | int lastPageCount; | - | ||||||||||||||||||||||||
466 | qreal idealWidth; | - | ||||||||||||||||||||||||
467 | bool contentHasAlignment; | - | ||||||||||||||||||||||||
468 | - | |||||||||||||||||||||||||
469 | QFixed blockIndent(const QTextBlockFormat &blockFormat) const; | - | ||||||||||||||||||||||||
470 | - | |||||||||||||||||||||||||
471 | void drawFrame(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context, | - | ||||||||||||||||||||||||
472 | QTextFrame *f) const; | - | ||||||||||||||||||||||||
473 | void drawFlow(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context, | - | ||||||||||||||||||||||||
474 | QTextFrame::Iterator it, const QList<QTextFrame *> &floats, QTextBlock *cursorBlockNeedingRepaint) const; | - | ||||||||||||||||||||||||
475 | void drawBlock(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context, | - | ||||||||||||||||||||||||
476 | const QTextBlock &bl, bool inRootFrame) const; | - | ||||||||||||||||||||||||
477 | void drawListItem(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context, | - | ||||||||||||||||||||||||
478 | const QTextBlock &bl, const QTextCharFormat *selectionFormat) const; | - | ||||||||||||||||||||||||
479 | void drawTableCell(const QRectF &cellRect, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &cell_context, | - | ||||||||||||||||||||||||
480 | QTextTable *table, QTextTableData *td, int r, int c, | - | ||||||||||||||||||||||||
481 | QTextBlock *cursorBlockNeedingRepaint, QPointF *cursorBlockOffset) const; | - | ||||||||||||||||||||||||
482 | void drawBorder(QPainter *painter, const QRectF &rect, qreal topMargin, qreal bottomMargin, qreal border, | - | ||||||||||||||||||||||||
483 | const QBrush &brush, QTextFrameFormat::BorderStyle style) const; | - | ||||||||||||||||||||||||
484 | void drawFrameDecoration(QPainter *painter, QTextFrame *frame, QTextFrameData *fd, const QRectF &clip, const QRectF &rect) const; | - | ||||||||||||||||||||||||
485 | - | |||||||||||||||||||||||||
486 | enum HitPoint { | - | ||||||||||||||||||||||||
487 | PointBefore, | - | ||||||||||||||||||||||||
488 | PointAfter, | - | ||||||||||||||||||||||||
489 | PointInside, | - | ||||||||||||||||||||||||
490 | PointExact | - | ||||||||||||||||||||||||
491 | }; | - | ||||||||||||||||||||||||
492 | HitPoint hitTest(QTextFrame *frame, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; | - | ||||||||||||||||||||||||
493 | HitPoint hitTest(QTextFrame::Iterator it, HitPoint hit, const QFixedPoint &p, | - | ||||||||||||||||||||||||
494 | int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; | - | ||||||||||||||||||||||||
495 | HitPoint hitTest(QTextTable *table, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; | - | ||||||||||||||||||||||||
496 | HitPoint hitTest(const QTextBlock &bl, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; | - | ||||||||||||||||||||||||
497 | - | |||||||||||||||||||||||||
498 | QTextLayoutStruct layoutCell(QTextTable *t, const QTextTableCell &cell, QFixed width, | - | ||||||||||||||||||||||||
499 | int layoutFrom, int layoutTo, QTextTableData *tableData, QFixed absoluteTableY, | - | ||||||||||||||||||||||||
500 | bool withPageBreaks); | - | ||||||||||||||||||||||||
501 | void setCellPosition(QTextTable *t, const QTextTableCell &cell, const QPointF &pos); | - | ||||||||||||||||||||||||
502 | QRectF layoutTable(QTextTable *t, int layoutFrom, int layoutTo, QFixed parentY); | - | ||||||||||||||||||||||||
503 | - | |||||||||||||||||||||||||
504 | void positionFloat(QTextFrame *frame, QTextLine *currentLine = 0); | - | ||||||||||||||||||||||||
505 | - | |||||||||||||||||||||||||
506 | // calls the next one | - | ||||||||||||||||||||||||
507 | QRectF layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed parentY = 0); | - | ||||||||||||||||||||||||
508 | QRectF layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed frameWidth, QFixed frameHeight, QFixed parentY = 0); | - | ||||||||||||||||||||||||
509 | - | |||||||||||||||||||||||||
510 | void layoutBlock(const QTextBlock &bl, int blockPosition, const QTextBlockFormat &blockFormat, | - | ||||||||||||||||||||||||
511 | QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, const QTextBlockFormat *previousBlockFormat); | - | ||||||||||||||||||||||||
512 | void layoutFlow(QTextFrame::Iterator it, QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, QFixed width = 0); | - | ||||||||||||||||||||||||
513 | - | |||||||||||||||||||||||||
514 | void floatMargins(const QFixed &y, const QTextLayoutStruct *layoutStruct, QFixed *left, QFixed *right) const; | - | ||||||||||||||||||||||||
515 | QFixed findY(QFixed yFrom, const QTextLayoutStruct *layoutStruct, QFixed requiredWidth) const; | - | ||||||||||||||||||||||||
516 | - | |||||||||||||||||||||||||
517 | QVector<QCheckPoint> checkPoints; | - | ||||||||||||||||||||||||
518 | - | |||||||||||||||||||||||||
519 | QTextFrame::Iterator frameIteratorForYPosition(QFixed y) const; | - | ||||||||||||||||||||||||
520 | QTextFrame::Iterator frameIteratorForTextPosition(int position) const; | - | ||||||||||||||||||||||||
521 | - | |||||||||||||||||||||||||
522 | void ensureLayouted(QFixed y) const; | - | ||||||||||||||||||||||||
523 | void ensureLayoutedByPosition(int position) const; | - | ||||||||||||||||||||||||
524 | inline void ensureLayoutFinished() const | - | ||||||||||||||||||||||||
525 | { ensureLayoutedByPosition(INT_MAX); } never executed: end of block | 0 | ||||||||||||||||||||||||
526 | void layoutStep() const; | - | ||||||||||||||||||||||||
527 | - | |||||||||||||||||||||||||
528 | QRectF frameBoundingRectInternal(QTextFrame *frame) const; | - | ||||||||||||||||||||||||
529 | - | |||||||||||||||||||||||||
530 | qreal scaleToDevice(qreal value) const; | - | ||||||||||||||||||||||||
531 | QFixed scaleToDevice(QFixed value) const; | - | ||||||||||||||||||||||||
532 | }; | - | ||||||||||||||||||||||||
533 | - | |||||||||||||||||||||||||
534 | QTextDocumentLayoutPrivate::QTextDocumentLayoutPrivate() | - | ||||||||||||||||||||||||
535 | : fixedColumnWidth(-1), | - | ||||||||||||||||||||||||
536 | cursorWidth(1), | - | ||||||||||||||||||||||||
537 | currentLazyLayoutPosition(-1), | - | ||||||||||||||||||||||||
538 | lazyLayoutStepSize(1000), | - | ||||||||||||||||||||||||
539 | lastPageCount(-1) | - | ||||||||||||||||||||||||
540 | { | - | ||||||||||||||||||||||||
541 | showLayoutProgress = true; | - | ||||||||||||||||||||||||
542 | insideDocumentChange = false; | - | ||||||||||||||||||||||||
543 | idealWidth = 0; | - | ||||||||||||||||||||||||
544 | contentHasAlignment = false; | - | ||||||||||||||||||||||||
545 | } never executed: end of block | 0 | ||||||||||||||||||||||||
546 | - | |||||||||||||||||||||||||
547 | QTextFrame::Iterator QTextDocumentLayoutPrivate::frameIteratorForYPosition(QFixed y) const | - | ||||||||||||||||||||||||
548 | { | - | ||||||||||||||||||||||||
549 | QTextFrame *rootFrame = document->rootFrame(); | - | ||||||||||||||||||||||||
550 | - | |||||||||||||||||||||||||
551 | if (checkPoints.isEmpty()
| 0 | ||||||||||||||||||||||||
552 | || y < 0 || y > data(rootFrame)->size.height)
| 0 | ||||||||||||||||||||||||
553 | return rootFrame->begin(); never executed: return rootFrame->begin(); | 0 | ||||||||||||||||||||||||
554 | - | |||||||||||||||||||||||||
555 | QVector<QCheckPoint>::ConstIterator checkPoint = std::lower_bound(checkPoints.begin(), checkPoints.end(), y); | - | ||||||||||||||||||||||||
556 | if (checkPoint == checkPoints.end())
| 0 | ||||||||||||||||||||||||
557 | return rootFrame->begin(); never executed: return rootFrame->begin(); | 0 | ||||||||||||||||||||||||
558 | - | |||||||||||||||||||||||||
559 | if (checkPoint != checkPoints.begin())
| 0 | ||||||||||||||||||||||||
560 | --checkPoint; never executed: --checkPoint; | 0 | ||||||||||||||||||||||||
561 | - | |||||||||||||||||||||||||
562 | const int position = rootFrame->firstPosition() + checkPoint->positionInFrame; | - | ||||||||||||||||||||||||
563 | return frameIteratorForTextPosition(position); never executed: return frameIteratorForTextPosition(position); | 0 | ||||||||||||||||||||||||
564 | } | - | ||||||||||||||||||||||||
565 | - | |||||||||||||||||||||||||
566 | QTextFrame::Iterator QTextDocumentLayoutPrivate::frameIteratorForTextPosition(int position) const | - | ||||||||||||||||||||||||
567 | { | - | ||||||||||||||||||||||||
568 | QTextFrame *rootFrame = docPrivate->rootFrame(); | - | ||||||||||||||||||||||||
569 | - | |||||||||||||||||||||||||
570 | const QTextDocumentPrivate::BlockMap &map = docPrivate->blockMap(); | - | ||||||||||||||||||||||||
571 | const int begin = map.findNode(rootFrame->firstPosition()); | - | ||||||||||||||||||||||||
572 | const int end = map.findNode(rootFrame->lastPosition()+1); | - | ||||||||||||||||||||||||
573 | - | |||||||||||||||||||||||||
574 | const int block = map.findNode(position); | - | ||||||||||||||||||||||||
575 | const int blockPos = map.position(block); | - | ||||||||||||||||||||||||
576 | - | |||||||||||||||||||||||||
577 | QTextFrame::iterator it(rootFrame, block, begin, end); | - | ||||||||||||||||||||||||
578 | - | |||||||||||||||||||||||||
579 | QTextFrame *containingFrame = docPrivate->frameAt(blockPos); | - | ||||||||||||||||||||||||
580 | if (containingFrame != rootFrame) {
| 0 | ||||||||||||||||||||||||
581 | while (containingFrame->parentFrame() != rootFrame) {
| 0 | ||||||||||||||||||||||||
582 | containingFrame = containingFrame->parentFrame(); | - | ||||||||||||||||||||||||
583 | Q_ASSERT(containingFrame); | - | ||||||||||||||||||||||||
584 | } never executed: end of block | 0 | ||||||||||||||||||||||||
585 | - | |||||||||||||||||||||||||
586 | it.cf = containingFrame; | - | ||||||||||||||||||||||||
587 | it.cb = 0; | - | ||||||||||||||||||||||||
588 | } never executed: end of block | 0 | ||||||||||||||||||||||||
589 | - | |||||||||||||||||||||||||
590 | return it; never executed: return it; | 0 | ||||||||||||||||||||||||
591 | } | - | ||||||||||||||||||||||||
592 | - | |||||||||||||||||||||||||
593 | QTextDocumentLayoutPrivate::HitPoint | - | ||||||||||||||||||||||||
594 | QTextDocumentLayoutPrivate::hitTest(QTextFrame *frame, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const | - | ||||||||||||||||||||||||
595 | { | - | ||||||||||||||||||||||||
596 | QTextFrameData *fd = data(frame); | - | ||||||||||||||||||||||||
597 | // ######### | - | ||||||||||||||||||||||||
598 | if (fd->layoutDirty)
| 0 | ||||||||||||||||||||||||
599 | return PointAfter; never executed: return PointAfter; | 0 | ||||||||||||||||||||||||
600 | Q_ASSERT(!fd->layoutDirty); | - | ||||||||||||||||||||||||
601 | Q_ASSERT(!fd->sizeDirty); | - | ||||||||||||||||||||||||
602 | const QFixedPoint relativePoint(point.x - fd->position.x, point.y - fd->position.y); | - | ||||||||||||||||||||||||
603 | - | |||||||||||||||||||||||||
604 | QTextFrame *rootFrame = docPrivate->rootFrame(); | - | ||||||||||||||||||||||||
605 | - | |||||||||||||||||||||||||
606 | // LDEBUG << "checking frame" << frame->firstPosition() << "point=" << point | - | ||||||||||||||||||||||||
607 | // << "position" << fd->position << "size" << fd->size; | - | ||||||||||||||||||||||||
608 | if (frame != rootFrame) {
| 0 | ||||||||||||||||||||||||
609 | if (relativePoint.y < 0 || relativePoint.x < 0) {
| 0 | ||||||||||||||||||||||||
610 | *position = frame->firstPosition() - 1; | - | ||||||||||||||||||||||||
611 | // LDEBUG << "before pos=" << *position; | - | ||||||||||||||||||||||||
612 | return PointBefore; never executed: return PointBefore; | 0 | ||||||||||||||||||||||||
613 | } else if (relativePoint.y > fd->size.height || relativePoint.x > fd->size.width) {
| 0 | ||||||||||||||||||||||||
614 | *position = frame->lastPosition() + 1; | - | ||||||||||||||||||||||||
615 | // LDEBUG << "after pos=" << *position; | - | ||||||||||||||||||||||||
616 | return PointAfter; never executed: return PointAfter; | 0 | ||||||||||||||||||||||||
617 | } | - | ||||||||||||||||||||||||
618 | } never executed: end of block | 0 | ||||||||||||||||||||||||
619 | - | |||||||||||||||||||||||||
620 | if (isFrameFromInlineObject(frame)) {
| 0 | ||||||||||||||||||||||||
621 | *position = frame->firstPosition() - 1; | - | ||||||||||||||||||||||||
622 | return PointExact; never executed: return PointExact; | 0 | ||||||||||||||||||||||||
623 | } | - | ||||||||||||||||||||||||
624 | - | |||||||||||||||||||||||||
625 | if (QTextTable *table = qobject_cast<QTextTable *>(frame)) {
| 0 | ||||||||||||||||||||||||
626 | const int rows = table->rows(); | - | ||||||||||||||||||||||||
627 | const int columns = table->columns(); | - | ||||||||||||||||||||||||
628 | QTextTableData *td = static_cast<QTextTableData *>(data(table)); | - | ||||||||||||||||||||||||
629 | - | |||||||||||||||||||||||||
630 | if (!td->childFrameMap.isEmpty()) {
| 0 | ||||||||||||||||||||||||
631 | for (int r = 0; r < rows; ++r) {
| 0 | ||||||||||||||||||||||||
632 | for (int c = 0; c < columns; ++c) {
| 0 | ||||||||||||||||||||||||
633 | QTextTableCell cell = table->cellAt(r, c); | - | ||||||||||||||||||||||||
634 | if (cell.row() != r || cell.column() != c)
| 0 | ||||||||||||||||||||||||
635 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
636 | - | |||||||||||||||||||||||||
637 | QRectF cellRect = td->cellRect(cell); | - | ||||||||||||||||||||||||
638 | const QFixedPoint cellPos = QFixedPoint::fromPointF(cellRect.topLeft()); | - | ||||||||||||||||||||||||
639 | const QFixedPoint pointInCell = relativePoint - cellPos; | - | ||||||||||||||||||||||||
640 | - | |||||||||||||||||||||||||
641 | const QList<QTextFrame *> childFrames = td->childFrameMap.values(r + c * rows); | - | ||||||||||||||||||||||||
642 | for (int i = 0; i < childFrames.size(); ++i) {
| 0 | ||||||||||||||||||||||||
643 | QTextFrame *child = childFrames.at(i); | - | ||||||||||||||||||||||||
644 | if (isFrameFromInlineObject(child)
| 0 | ||||||||||||||||||||||||
645 | && child->frameFormat().position() != QTextFrameFormat::InFlow
| 0 | ||||||||||||||||||||||||
646 | && hitTest(child, pointInCell, position, l, accuracy) == PointExact)
| 0 | ||||||||||||||||||||||||
647 | { | - | ||||||||||||||||||||||||
648 | return PointExact; never executed: return PointExact; | 0 | ||||||||||||||||||||||||
649 | } | - | ||||||||||||||||||||||||
650 | } never executed: end of block | 0 | ||||||||||||||||||||||||
651 | } never executed: end of block | 0 | ||||||||||||||||||||||||
652 | } never executed: end of block | 0 | ||||||||||||||||||||||||
653 | } never executed: end of block | 0 | ||||||||||||||||||||||||
654 | - | |||||||||||||||||||||||||
655 | return hitTest(table, relativePoint, position, l, accuracy); never executed: return hitTest(table, relativePoint, position, l, accuracy); | 0 | ||||||||||||||||||||||||
656 | } | - | ||||||||||||||||||||||||
657 | - | |||||||||||||||||||||||||
658 | const QList<QTextFrame *> childFrames = frame->childFrames(); | - | ||||||||||||||||||||||||
659 | for (int i = 0; i < childFrames.size(); ++i) {
| 0 | ||||||||||||||||||||||||
660 | QTextFrame *child = childFrames.at(i); | - | ||||||||||||||||||||||||
661 | if (isFrameFromInlineObject(child)
| 0 | ||||||||||||||||||||||||
662 | && child->frameFormat().position() != QTextFrameFormat::InFlow
| 0 | ||||||||||||||||||||||||
663 | && hitTest(child, relativePoint, position, l, accuracy) == PointExact)
| 0 | ||||||||||||||||||||||||
664 | { | - | ||||||||||||||||||||||||
665 | return PointExact; never executed: return PointExact; | 0 | ||||||||||||||||||||||||
666 | } | - | ||||||||||||||||||||||||
667 | } never executed: end of block | 0 | ||||||||||||||||||||||||
668 | - | |||||||||||||||||||||||||
669 | QTextFrame::Iterator it = frame->begin(); | - | ||||||||||||||||||||||||
670 | - | |||||||||||||||||||||||||
671 | if (frame == rootFrame) {
| 0 | ||||||||||||||||||||||||
672 | it = frameIteratorForYPosition(relativePoint.y); | - | ||||||||||||||||||||||||
673 | - | |||||||||||||||||||||||||
674 | Q_ASSERT(it.parentFrame() == frame); | - | ||||||||||||||||||||||||
675 | } never executed: end of block | 0 | ||||||||||||||||||||||||
676 | - | |||||||||||||||||||||||||
677 | if (it.currentFrame())
| 0 | ||||||||||||||||||||||||
678 | *position = it.currentFrame()->firstPosition(); never executed: *position = it.currentFrame()->firstPosition(); | 0 | ||||||||||||||||||||||||
679 | else | - | ||||||||||||||||||||||||
680 | *position = it.currentBlock().position(); never executed: *position = it.currentBlock().position(); | 0 | ||||||||||||||||||||||||
681 | - | |||||||||||||||||||||||||
682 | return hitTest(it, PointBefore, relativePoint, position, l, accuracy); never executed: return hitTest(it, PointBefore, relativePoint, position, l, accuracy); | 0 | ||||||||||||||||||||||||
683 | } | - | ||||||||||||||||||||||||
684 | - | |||||||||||||||||||||||||
685 | QTextDocumentLayoutPrivate::HitPoint | - | ||||||||||||||||||||||||
686 | QTextDocumentLayoutPrivate::hitTest(QTextFrame::Iterator it, HitPoint hit, const QFixedPoint &p, | - | ||||||||||||||||||||||||
687 | int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const | - | ||||||||||||||||||||||||
688 | { | - | ||||||||||||||||||||||||
689 | INC_INDENT; | - | ||||||||||||||||||||||||
690 | - | |||||||||||||||||||||||||
691 | for (; !it.atEnd(); ++it) {
| 0 | ||||||||||||||||||||||||
692 | QTextFrame *c = it.currentFrame(); | - | ||||||||||||||||||||||||
693 | HitPoint hp; | - | ||||||||||||||||||||||||
694 | int pos = -1; | - | ||||||||||||||||||||||||
695 | if (c) {
| 0 | ||||||||||||||||||||||||
696 | hp = hitTest(c, p, &pos, l, accuracy); | - | ||||||||||||||||||||||||
697 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
698 | hp = hitTest(it.currentBlock(), p, &pos, l, accuracy); | - | ||||||||||||||||||||||||
699 | } never executed: end of block | 0 | ||||||||||||||||||||||||
700 | if (hp >= PointInside) {
| 0 | ||||||||||||||||||||||||
701 | if (isEmptyBlockBeforeTable(it))
| 0 | ||||||||||||||||||||||||
702 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
703 | hit = hp; | - | ||||||||||||||||||||||||
704 | *position = pos; | - | ||||||||||||||||||||||||
705 | break; never executed: break; | 0 | ||||||||||||||||||||||||
706 | } | - | ||||||||||||||||||||||||
707 | if (hp == PointBefore && pos < *position) {
| 0 | ||||||||||||||||||||||||
708 | *position = pos; | - | ||||||||||||||||||||||||
709 | hit = hp; | - | ||||||||||||||||||||||||
710 | } else if (hp == PointAfter && pos > *position) { never executed: end of block
| 0 | ||||||||||||||||||||||||
711 | *position = pos; | - | ||||||||||||||||||||||||
712 | hit = hp; | - | ||||||||||||||||||||||||
713 | } never executed: end of block | 0 | ||||||||||||||||||||||||
714 | } never executed: end of block | 0 | ||||||||||||||||||||||||
715 | - | |||||||||||||||||||||||||
716 | DEC_INDENT; | - | ||||||||||||||||||||||||
717 | // LDEBUG << "inside=" << hit << " pos=" << *position; | - | ||||||||||||||||||||||||
718 | return hit; never executed: return hit; | 0 | ||||||||||||||||||||||||
719 | } | - | ||||||||||||||||||||||||
720 | - | |||||||||||||||||||||||||
721 | QTextDocumentLayoutPrivate::HitPoint | - | ||||||||||||||||||||||||
722 | QTextDocumentLayoutPrivate::hitTest(QTextTable *table, const QFixedPoint &point, | - | ||||||||||||||||||||||||
723 | int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const | - | ||||||||||||||||||||||||
724 | { | - | ||||||||||||||||||||||||
725 | QTextTableData *td = static_cast<QTextTableData *>(data(table)); | - | ||||||||||||||||||||||||
726 | - | |||||||||||||||||||||||||
727 | QVector<QFixed>::ConstIterator rowIt = std::lower_bound(td->rowPositions.constBegin(), td->rowPositions.constEnd(), point.y); | - | ||||||||||||||||||||||||
728 | if (rowIt == td->rowPositions.constEnd()) {
| 0 | ||||||||||||||||||||||||
729 | rowIt = td->rowPositions.constEnd() - 1; | - | ||||||||||||||||||||||||
730 | } else if (rowIt != td->rowPositions.constBegin()) { never executed: end of block
| 0 | ||||||||||||||||||||||||
731 | --rowIt; | - | ||||||||||||||||||||||||
732 | } never executed: end of block | 0 | ||||||||||||||||||||||||
733 | - | |||||||||||||||||||||||||
734 | QVector<QFixed>::ConstIterator colIt = std::lower_bound(td->columnPositions.constBegin(), td->columnPositions.constEnd(), point.x); | - | ||||||||||||||||||||||||
735 | if (colIt == td->columnPositions.constEnd()) {
| 0 | ||||||||||||||||||||||||
736 | colIt = td->columnPositions.constEnd() - 1; | - | ||||||||||||||||||||||||
737 | } else if (colIt != td->columnPositions.constBegin()) { never executed: end of block
| 0 | ||||||||||||||||||||||||
738 | --colIt; | - | ||||||||||||||||||||||||
739 | } never executed: end of block | 0 | ||||||||||||||||||||||||
740 | - | |||||||||||||||||||||||||
741 | QTextTableCell cell = table->cellAt(rowIt - td->rowPositions.constBegin(), | - | ||||||||||||||||||||||||
742 | colIt - td->columnPositions.constBegin()); | - | ||||||||||||||||||||||||
743 | if (!cell.isValid())
| 0 | ||||||||||||||||||||||||
744 | return PointBefore; never executed: return PointBefore; | 0 | ||||||||||||||||||||||||
745 | - | |||||||||||||||||||||||||
746 | *position = cell.firstPosition(); | - | ||||||||||||||||||||||||
747 | - | |||||||||||||||||||||||||
748 | HitPoint hp = hitTest(cell.begin(), PointInside, point - td->cellPosition(cell), position, l, accuracy); | - | ||||||||||||||||||||||||
749 | - | |||||||||||||||||||||||||
750 | if (hp == PointExact)
| 0 | ||||||||||||||||||||||||
751 | return hp; never executed: return hp; | 0 | ||||||||||||||||||||||||
752 | if (hp == PointAfter)
| 0 | ||||||||||||||||||||||||
753 | *position = cell.lastPosition(); never executed: *position = cell.lastPosition(); | 0 | ||||||||||||||||||||||||
754 | return PointInside; never executed: return PointInside; | 0 | ||||||||||||||||||||||||
755 | } | - | ||||||||||||||||||||||||
756 | - | |||||||||||||||||||||||||
757 | QTextDocumentLayoutPrivate::HitPoint | - | ||||||||||||||||||||||||
758 | QTextDocumentLayoutPrivate::hitTest(const QTextBlock &bl, const QFixedPoint &point, int *position, QTextLayout **l, | - | ||||||||||||||||||||||||
759 | Qt::HitTestAccuracy accuracy) const | - | ||||||||||||||||||||||||
760 | { | - | ||||||||||||||||||||||||
761 | QTextLayout *tl = bl.layout(); | - | ||||||||||||||||||||||||
762 | QRectF textrect = tl->boundingRect(); | - | ||||||||||||||||||||||||
763 | textrect.translate(tl->position()); | - | ||||||||||||||||||||||||
764 | // LDEBUG << " checking block" << bl.position() << "point=" << point | - | ||||||||||||||||||||||||
765 | // << " tlrect" << textrect; | - | ||||||||||||||||||||||||
766 | *position = bl.position(); | - | ||||||||||||||||||||||||
767 | if (point.y.toReal() < textrect.top()) {
| 0 | ||||||||||||||||||||||||
768 | // LDEBUG << " before pos=" << *position; | - | ||||||||||||||||||||||||
769 | return PointBefore; never executed: return PointBefore; | 0 | ||||||||||||||||||||||||
770 | } else if (point.y.toReal() > textrect.bottom()) {
| 0 | ||||||||||||||||||||||||
771 | *position += bl.length(); | - | ||||||||||||||||||||||||
772 | // LDEBUG << " after pos=" << *position; | - | ||||||||||||||||||||||||
773 | return PointAfter; never executed: return PointAfter; | 0 | ||||||||||||||||||||||||
774 | } | - | ||||||||||||||||||||||||
775 | - | |||||||||||||||||||||||||
776 | QPointF pos = point.toPointF() - tl->position(); | - | ||||||||||||||||||||||||
777 | - | |||||||||||||||||||||||||
778 | // ### rtl? | - | ||||||||||||||||||||||||
779 | - | |||||||||||||||||||||||||
780 | HitPoint hit = PointInside; | - | ||||||||||||||||||||||||
781 | *l = tl; | - | ||||||||||||||||||||||||
782 | int off = 0; | - | ||||||||||||||||||||||||
783 | for (int i = 0; i < tl->lineCount(); ++i) {
| 0 | ||||||||||||||||||||||||
784 | QTextLine line = tl->lineAt(i); | - | ||||||||||||||||||||||||
785 | const QRectF lr = line.naturalTextRect(); | - | ||||||||||||||||||||||||
786 | if (lr.top() > pos.y()) {
| 0 | ||||||||||||||||||||||||
787 | off = qMin(off, line.textStart()); | - | ||||||||||||||||||||||||
788 | } else if (lr.bottom() <= pos.y()) { never executed: end of block
| 0 | ||||||||||||||||||||||||
789 | off = qMax(off, line.textStart() + line.textLength()); | - | ||||||||||||||||||||||||
790 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
791 | if (lr.left() <= pos.x() && lr.right() >= pos.x())
| 0 | ||||||||||||||||||||||||
792 | hit = PointExact; never executed: hit = PointExact; | 0 | ||||||||||||||||||||||||
793 | // when trying to hit an anchor we want it to hit not only in the left | - | ||||||||||||||||||||||||
794 | // half | - | ||||||||||||||||||||||||
795 | if (accuracy == Qt::ExactHit)
| 0 | ||||||||||||||||||||||||
796 | off = line.xToCursor(pos.x(), QTextLine::CursorOnCharacter); never executed: off = line.xToCursor(pos.x(), QTextLine::CursorOnCharacter); | 0 | ||||||||||||||||||||||||
797 | else | - | ||||||||||||||||||||||||
798 | off = line.xToCursor(pos.x(), QTextLine::CursorBetweenCharacters); never executed: off = line.xToCursor(pos.x(), QTextLine::CursorBetweenCharacters); | 0 | ||||||||||||||||||||||||
799 | break; never executed: break; | 0 | ||||||||||||||||||||||||
800 | } | - | ||||||||||||||||||||||||
801 | } | - | ||||||||||||||||||||||||
802 | *position += off; | - | ||||||||||||||||||||||||
803 | - | |||||||||||||||||||||||||
804 | // LDEBUG << " inside=" << hit << " pos=" << *position; | - | ||||||||||||||||||||||||
805 | return hit; never executed: return hit; | 0 | ||||||||||||||||||||||||
806 | } | - | ||||||||||||||||||||||||
807 | - | |||||||||||||||||||||||||
808 | // ### could be moved to QTextBlock | - | ||||||||||||||||||||||||
809 | QFixed QTextDocumentLayoutPrivate::blockIndent(const QTextBlockFormat &blockFormat) const | - | ||||||||||||||||||||||||
810 | { | - | ||||||||||||||||||||||||
811 | qreal indent = blockFormat.indent(); | - | ||||||||||||||||||||||||
812 | - | |||||||||||||||||||||||||
813 | QTextObject *object = document->objectForFormat(blockFormat); | - | ||||||||||||||||||||||||
814 | if (object)
| 0 | ||||||||||||||||||||||||
815 | indent += object->format().toListFormat().indent(); never executed: indent += object->format().toListFormat().indent(); | 0 | ||||||||||||||||||||||||
816 | - | |||||||||||||||||||||||||
817 | if (qIsNull(indent))
| 0 | ||||||||||||||||||||||||
818 | return 0; never executed: return 0; | 0 | ||||||||||||||||||||||||
819 | - | |||||||||||||||||||||||||
820 | qreal scale = 1; | - | ||||||||||||||||||||||||
821 | if (paintDevice) {
| 0 | ||||||||||||||||||||||||
822 | scale = qreal(paintDevice->logicalDpiY()) / qreal(qt_defaultDpi()); | - | ||||||||||||||||||||||||
823 | } never executed: end of block | 0 | ||||||||||||||||||||||||
824 | - | |||||||||||||||||||||||||
825 | return QFixed::fromReal(indent * scale * document->indentWidth()); never executed: return QFixed::fromReal(indent * scale * document->indentWidth()); | 0 | ||||||||||||||||||||||||
826 | } | - | ||||||||||||||||||||||||
827 | - | |||||||||||||||||||||||||
828 | void QTextDocumentLayoutPrivate::drawBorder(QPainter *painter, const QRectF &rect, qreal topMargin, qreal bottomMargin, | - | ||||||||||||||||||||||||
829 | qreal border, const QBrush &brush, QTextFrameFormat::BorderStyle style) const | - | ||||||||||||||||||||||||
830 | { | - | ||||||||||||||||||||||||
831 | const qreal pageHeight = document->pageSize().height(); | - | ||||||||||||||||||||||||
832 | const int topPage = pageHeight > 0 ? static_cast<int>(rect.top() / pageHeight) : 0;
| 0 | ||||||||||||||||||||||||
833 | const int bottomPage = pageHeight > 0 ? static_cast<int>((rect.bottom() + border) / pageHeight) : 0;
| 0 | ||||||||||||||||||||||||
834 | - | |||||||||||||||||||||||||
835 | #ifndef QT_NO_CSSPARSER | - | ||||||||||||||||||||||||
836 | QCss::BorderStyle cssStyle = static_cast<QCss::BorderStyle>(style + 1); | - | ||||||||||||||||||||||||
837 | #endif //QT_NO_CSSPARSER | - | ||||||||||||||||||||||||
838 | - | |||||||||||||||||||||||||
839 | bool turn_off_antialiasing = !(painter->renderHints() & QPainter::Antialiasing); | - | ||||||||||||||||||||||||
840 | painter->setRenderHint(QPainter::Antialiasing); | - | ||||||||||||||||||||||||
841 | - | |||||||||||||||||||||||||
842 | for (int i = topPage; i <= bottomPage; ++i) {
| 0 | ||||||||||||||||||||||||
843 | QRectF clipped = rect.toRect(); | - | ||||||||||||||||||||||||
844 | - | |||||||||||||||||||||||||
845 | if (topPage != bottomPage) {
| 0 | ||||||||||||||||||||||||
846 | clipped.setTop(qMax(clipped.top(), i * pageHeight + topMargin - border)); | - | ||||||||||||||||||||||||
847 | clipped.setBottom(qMin(clipped.bottom(), (i + 1) * pageHeight - bottomMargin)); | - | ||||||||||||||||||||||||
848 | - | |||||||||||||||||||||||||
849 | if (clipped.bottom() <= clipped.top())
| 0 | ||||||||||||||||||||||||
850 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
851 | } never executed: end of block | 0 | ||||||||||||||||||||||||
852 | #ifndef QT_NO_CSSPARSER | - | ||||||||||||||||||||||||
853 | qDrawEdge(painter, clipped.left(), clipped.top(), clipped.left() + border, clipped.bottom() + border, 0, 0, QCss::LeftEdge, cssStyle, brush); | - | ||||||||||||||||||||||||
854 | qDrawEdge(painter, clipped.left() + border, clipped.top(), clipped.right() + border, clipped.top() + border, 0, 0, QCss::TopEdge, cssStyle, brush); | - | ||||||||||||||||||||||||
855 | qDrawEdge(painter, clipped.right(), clipped.top() + border, clipped.right() + border, clipped.bottom(), 0, 0, QCss::RightEdge, cssStyle, brush); | - | ||||||||||||||||||||||||
856 | qDrawEdge(painter, clipped.left() + border, clipped.bottom(), clipped.right() + border, clipped.bottom() + border, 0, 0, QCss::BottomEdge, cssStyle, brush); | - | ||||||||||||||||||||||||
857 | #else | - | ||||||||||||||||||||||||
858 | painter->save(); | - | ||||||||||||||||||||||||
859 | painter->setPen(Qt::NoPen); | - | ||||||||||||||||||||||||
860 | painter->setBrush(brush); | - | ||||||||||||||||||||||||
861 | painter->drawRect(QRectF(clipped.left(), clipped.top(), clipped.left() + border, clipped.bottom() + border)); | - | ||||||||||||||||||||||||
862 | painter->drawRect(QRectF(clipped.left() + border, clipped.top(), clipped.right() + border, clipped.top() + border)); | - | ||||||||||||||||||||||||
863 | painter->drawRect(QRectF(clipped.right(), clipped.top() + border, clipped.right() + border, clipped.bottom())); | - | ||||||||||||||||||||||||
864 | painter->drawRect(QRectF(clipped.left() + border, clipped.bottom(), clipped.right() + border, clipped.bottom() + border)); | - | ||||||||||||||||||||||||
865 | painter->restore(); | - | ||||||||||||||||||||||||
866 | #endif //QT_NO_CSSPARSER | - | ||||||||||||||||||||||||
867 | } never executed: end of block | 0 | ||||||||||||||||||||||||
868 | if (turn_off_antialiasing)
| 0 | ||||||||||||||||||||||||
869 | painter->setRenderHint(QPainter::Antialiasing, false); never executed: painter->setRenderHint(QPainter::Antialiasing, false); | 0 | ||||||||||||||||||||||||
870 | } never executed: end of block | 0 | ||||||||||||||||||||||||
871 | - | |||||||||||||||||||||||||
872 | void QTextDocumentLayoutPrivate::drawFrameDecoration(QPainter *painter, QTextFrame *frame, QTextFrameData *fd, const QRectF &clip, const QRectF &rect) const | - | ||||||||||||||||||||||||
873 | { | - | ||||||||||||||||||||||||
874 | - | |||||||||||||||||||||||||
875 | const QBrush bg = frame->frameFormat().background(); | - | ||||||||||||||||||||||||
876 | if (bg != Qt::NoBrush) {
| 0 | ||||||||||||||||||||||||
877 | QRectF bgRect = rect; | - | ||||||||||||||||||||||||
878 | bgRect.adjust((fd->leftMargin + fd->border).toReal(), | - | ||||||||||||||||||||||||
879 | (fd->topMargin + fd->border).toReal(), | - | ||||||||||||||||||||||||
880 | - (fd->rightMargin + fd->border).toReal(), | - | ||||||||||||||||||||||||
881 | - (fd->bottomMargin + fd->border).toReal()); | - | ||||||||||||||||||||||||
882 | - | |||||||||||||||||||||||||
883 | QRectF gradientRect; // invalid makes it default to bgRect | - | ||||||||||||||||||||||||
884 | QPointF origin = bgRect.topLeft(); | - | ||||||||||||||||||||||||
885 | if (!frame->parentFrame()) {
| 0 | ||||||||||||||||||||||||
886 | bgRect = clip; | - | ||||||||||||||||||||||||
887 | gradientRect.setWidth(painter->device()->width()); | - | ||||||||||||||||||||||||
888 | gradientRect.setHeight(painter->device()->height()); | - | ||||||||||||||||||||||||
889 | } never executed: end of block | 0 | ||||||||||||||||||||||||
890 | fillBackground(painter, bgRect, bg, origin, gradientRect); | - | ||||||||||||||||||||||||
891 | } never executed: end of block | 0 | ||||||||||||||||||||||||
892 | if (fd->border != 0) {
| 0 | ||||||||||||||||||||||||
893 | painter->save(); | - | ||||||||||||||||||||||||
894 | painter->setBrush(Qt::lightGray); | - | ||||||||||||||||||||||||
895 | painter->setPen(Qt::NoPen); | - | ||||||||||||||||||||||||
896 | - | |||||||||||||||||||||||||
897 | const qreal leftEdge = rect.left() + fd->leftMargin.toReal(); | - | ||||||||||||||||||||||||
898 | const qreal border = fd->border.toReal(); | - | ||||||||||||||||||||||||
899 | const qreal topMargin = fd->topMargin.toReal(); | - | ||||||||||||||||||||||||
900 | const qreal leftMargin = fd->leftMargin.toReal(); | - | ||||||||||||||||||||||||
901 | const qreal bottomMargin = fd->bottomMargin.toReal(); | - | ||||||||||||||||||||||||
902 | const qreal rightMargin = fd->rightMargin.toReal(); | - | ||||||||||||||||||||||||
903 | const qreal w = rect.width() - 2 * border - leftMargin - rightMargin; | - | ||||||||||||||||||||||||
904 | const qreal h = rect.height() - 2 * border - topMargin - bottomMargin; | - | ||||||||||||||||||||||||
905 | - | |||||||||||||||||||||||||
906 | drawBorder(painter, QRectF(leftEdge, rect.top() + topMargin, w + border, h + border), | - | ||||||||||||||||||||||||
907 | fd->effectiveTopMargin.toReal(), fd->effectiveBottomMargin.toReal(), | - | ||||||||||||||||||||||||
908 | border, frame->frameFormat().borderBrush(), frame->frameFormat().borderStyle()); | - | ||||||||||||||||||||||||
909 | - | |||||||||||||||||||||||||
910 | painter->restore(); | - | ||||||||||||||||||||||||
911 | } never executed: end of block | 0 | ||||||||||||||||||||||||
912 | } never executed: end of block | 0 | ||||||||||||||||||||||||
913 | - | |||||||||||||||||||||||||
914 | static void adjustContextSelectionsForCell(QAbstractTextDocumentLayout::PaintContext &cell_context, | - | ||||||||||||||||||||||||
915 | const QTextTableCell &cell, | - | ||||||||||||||||||||||||
916 | int r, int c, | - | ||||||||||||||||||||||||
917 | const int *selectedTableCells) | - | ||||||||||||||||||||||||
918 | { | - | ||||||||||||||||||||||||
919 | for (int i = 0; i < cell_context.selections.size(); ++i) {
| 0 | ||||||||||||||||||||||||
920 | int row_start = selectedTableCells[i * 4]; | - | ||||||||||||||||||||||||
921 | int col_start = selectedTableCells[i * 4 + 1]; | - | ||||||||||||||||||||||||
922 | int num_rows = selectedTableCells[i * 4 + 2]; | - | ||||||||||||||||||||||||
923 | int num_cols = selectedTableCells[i * 4 + 3]; | - | ||||||||||||||||||||||||
924 | - | |||||||||||||||||||||||||
925 | if (row_start != -1) {
| 0 | ||||||||||||||||||||||||
926 | if (r >= row_start && r < row_start + num_rows
| 0 | ||||||||||||||||||||||||
927 | && c >= col_start && c < col_start + num_cols)
| 0 | ||||||||||||||||||||||||
928 | { | - | ||||||||||||||||||||||||
929 | int firstPosition = cell.firstPosition(); | - | ||||||||||||||||||||||||
930 | int lastPosition = cell.lastPosition(); | - | ||||||||||||||||||||||||
931 | - | |||||||||||||||||||||||||
932 | // make sure empty cells are still selected | - | ||||||||||||||||||||||||
933 | if (firstPosition == lastPosition)
| 0 | ||||||||||||||||||||||||
934 | ++lastPosition; never executed: ++lastPosition; | 0 | ||||||||||||||||||||||||
935 | - | |||||||||||||||||||||||||
936 | cell_context.selections[i].cursor.setPosition(firstPosition); | - | ||||||||||||||||||||||||
937 | cell_context.selections[i].cursor.setPosition(lastPosition, QTextCursor::KeepAnchor); | - | ||||||||||||||||||||||||
938 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
939 | cell_context.selections[i].cursor.clearSelection(); | - | ||||||||||||||||||||||||
940 | } never executed: end of block | 0 | ||||||||||||||||||||||||
941 | } | - | ||||||||||||||||||||||||
942 | - | |||||||||||||||||||||||||
943 | // FullWidthSelection is not useful for tables | - | ||||||||||||||||||||||||
944 | cell_context.selections[i].format.clearProperty(QTextFormat::FullWidthSelection); | - | ||||||||||||||||||||||||
945 | } never executed: end of block | 0 | ||||||||||||||||||||||||
946 | } never executed: end of block | 0 | ||||||||||||||||||||||||
947 | - | |||||||||||||||||||||||||
948 | void QTextDocumentLayoutPrivate::drawFrame(const QPointF &offset, QPainter *painter, | - | ||||||||||||||||||||||||
949 | const QAbstractTextDocumentLayout::PaintContext &context, | - | ||||||||||||||||||||||||
950 | QTextFrame *frame) const | - | ||||||||||||||||||||||||
951 | { | - | ||||||||||||||||||||||||
952 | QTextFrameData *fd = data(frame); | - | ||||||||||||||||||||||||
953 | // ####### | - | ||||||||||||||||||||||||
954 | if (fd->layoutDirty)
| 0 | ||||||||||||||||||||||||
955 | return; never executed: return; | 0 | ||||||||||||||||||||||||
956 | Q_ASSERT(!fd->sizeDirty); | - | ||||||||||||||||||||||||
957 | Q_ASSERT(!fd->layoutDirty); | - | ||||||||||||||||||||||||
958 | - | |||||||||||||||||||||||||
959 | const QPointF off = offset + fd->position.toPointF(); | - | ||||||||||||||||||||||||
960 | if (context.clip.isValid()
| 0 | ||||||||||||||||||||||||
961 | && (off.y() > context.clip.bottom() || off.y() + fd->size.height.toReal() < context.clip.top()
| 0 | ||||||||||||||||||||||||
962 | || off.x() > context.clip.right() || off.x() + fd->size.width.toReal() < context.clip.left()))
| 0 | ||||||||||||||||||||||||
963 | return; never executed: return; | 0 | ||||||||||||||||||||||||
964 | - | |||||||||||||||||||||||||
965 | // LDEBUG << debug_indent << "drawFrame" << frame->firstPosition() << "--" << frame->lastPosition() << "at" << offset; | - | ||||||||||||||||||||||||
966 | // INC_INDENT; | - | ||||||||||||||||||||||||
967 | - | |||||||||||||||||||||||||
968 | // if the cursor is /on/ a table border we may need to repaint it | - | ||||||||||||||||||||||||
969 | // afterwards, as we usually draw the decoration first | - | ||||||||||||||||||||||||
970 | QTextBlock cursorBlockNeedingRepaint; | - | ||||||||||||||||||||||||
971 | QPointF offsetOfRepaintedCursorBlock = off; | - | ||||||||||||||||||||||||
972 | - | |||||||||||||||||||||||||
973 | QTextTable *table = qobject_cast<QTextTable *>(frame); | - | ||||||||||||||||||||||||
974 | const QRectF frameRect(off, fd->size.toSizeF()); | - | ||||||||||||||||||||||||
975 | - | |||||||||||||||||||||||||
976 | if (table) {
| 0 | ||||||||||||||||||||||||
977 | const int rows = table->rows(); | - | ||||||||||||||||||||||||
978 | const int columns = table->columns(); | - | ||||||||||||||||||||||||
979 | QTextTableData *td = static_cast<QTextTableData *>(data(table)); | - | ||||||||||||||||||||||||
980 | - | |||||||||||||||||||||||||
981 | QVarLengthArray<int> selectedTableCells(context.selections.size() * 4); | - | ||||||||||||||||||||||||
982 | for (int i = 0; i < context.selections.size(); ++i) {
| 0 | ||||||||||||||||||||||||
983 | const QAbstractTextDocumentLayout::Selection &s = context.selections.at(i); | - | ||||||||||||||||||||||||
984 | int row_start = -1, col_start = -1, num_rows = -1, num_cols = -1; | - | ||||||||||||||||||||||||
985 | - | |||||||||||||||||||||||||
986 | if (s.cursor.currentTable() == table)
| 0 | ||||||||||||||||||||||||
987 | s.cursor.selectedTableCells(&row_start, &num_rows, &col_start, &num_cols); never executed: s.cursor.selectedTableCells(&row_start, &num_rows, &col_start, &num_cols); | 0 | ||||||||||||||||||||||||
988 | - | |||||||||||||||||||||||||
989 | selectedTableCells[i * 4] = row_start; | - | ||||||||||||||||||||||||
990 | selectedTableCells[i * 4 + 1] = col_start; | - | ||||||||||||||||||||||||
991 | selectedTableCells[i * 4 + 2] = num_rows; | - | ||||||||||||||||||||||||
992 | selectedTableCells[i * 4 + 3] = num_cols; | - | ||||||||||||||||||||||||
993 | } never executed: end of block | 0 | ||||||||||||||||||||||||
994 | - | |||||||||||||||||||||||||
995 | QFixed pageHeight = QFixed::fromReal(document->pageSize().height()); | - | ||||||||||||||||||||||||
996 | if (pageHeight <= 0)
| 0 | ||||||||||||||||||||||||
997 | pageHeight = QFIXED_MAX; never executed: pageHeight = (2147483647/256); | 0 | ||||||||||||||||||||||||
998 | - | |||||||||||||||||||||||||
999 | const int tableStartPage = (td->position.y / pageHeight).truncate(); | - | ||||||||||||||||||||||||
1000 | const int tableEndPage = ((td->position.y + td->size.height) / pageHeight).truncate(); | - | ||||||||||||||||||||||||
1001 | - | |||||||||||||||||||||||||
1002 | qreal border = td->border.toReal(); | - | ||||||||||||||||||||||||
1003 | drawFrameDecoration(painter, frame, fd, context.clip, frameRect); | - | ||||||||||||||||||||||||
1004 | - | |||||||||||||||||||||||||
1005 | // draw the table headers | - | ||||||||||||||||||||||||
1006 | const int headerRowCount = qMin(table->format().headerRowCount(), rows - 1); | - | ||||||||||||||||||||||||
1007 | int page = tableStartPage + 1; | - | ||||||||||||||||||||||||
1008 | while (page <= tableEndPage) {
| 0 | ||||||||||||||||||||||||
1009 | const QFixed pageTop = page * pageHeight + td->effectiveTopMargin + td->cellSpacing + td->border; | - | ||||||||||||||||||||||||
1010 | const qreal headerOffset = (pageTop - td->rowPositions.at(0)).toReal(); | - | ||||||||||||||||||||||||
1011 | for (int r = 0; r < headerRowCount; ++r) {
| 0 | ||||||||||||||||||||||||
1012 | for (int c = 0; c < columns; ++c) {
| 0 | ||||||||||||||||||||||||
1013 | QTextTableCell cell = table->cellAt(r, c); | - | ||||||||||||||||||||||||
1014 | QAbstractTextDocumentLayout::PaintContext cell_context = context; | - | ||||||||||||||||||||||||
1015 | adjustContextSelectionsForCell(cell_context, cell, r, c, selectedTableCells.data()); | - | ||||||||||||||||||||||||
1016 | QRectF cellRect = td->cellRect(cell); | - | ||||||||||||||||||||||||
1017 | - | |||||||||||||||||||||||||
1018 | cellRect.translate(off.x(), headerOffset); | - | ||||||||||||||||||||||||
1019 | // we need to account for the cell border in the clipping test | - | ||||||||||||||||||||||||
1020 | int leftAdjust = qMin(qreal(0), 1 - border); | - | ||||||||||||||||||||||||
1021 | if (cell_context.clip.isValid() && !cellRect.adjusted(leftAdjust, leftAdjust, border, border).intersects(cell_context.clip))
| 0 | ||||||||||||||||||||||||
1022 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1023 | - | |||||||||||||||||||||||||
1024 | drawTableCell(cellRect, painter, cell_context, table, td, r, c, &cursorBlockNeedingRepaint, | - | ||||||||||||||||||||||||
1025 | &offsetOfRepaintedCursorBlock); | - | ||||||||||||||||||||||||
1026 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1027 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1028 | ++page; | - | ||||||||||||||||||||||||
1029 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1030 | - | |||||||||||||||||||||||||
1031 | int firstRow = 0; | - | ||||||||||||||||||||||||
1032 | int lastRow = rows; | - | ||||||||||||||||||||||||
1033 | - | |||||||||||||||||||||||||
1034 | if (context.clip.isValid()) {
| 0 | ||||||||||||||||||||||||
1035 | QVector<QFixed>::ConstIterator rowIt = std::lower_bound(td->rowPositions.constBegin(), td->rowPositions.constEnd(), QFixed::fromReal(context.clip.top() - off.y())); | - | ||||||||||||||||||||||||
1036 | if (rowIt != td->rowPositions.constEnd() && rowIt != td->rowPositions.constBegin()) {
| 0 | ||||||||||||||||||||||||
1037 | --rowIt; | - | ||||||||||||||||||||||||
1038 | firstRow = rowIt - td->rowPositions.constBegin(); | - | ||||||||||||||||||||||||
1039 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1040 | - | |||||||||||||||||||||||||
1041 | rowIt = std::upper_bound(td->rowPositions.constBegin(), td->rowPositions.constEnd(), QFixed::fromReal(context.clip.bottom() - off.y())); | - | ||||||||||||||||||||||||
1042 | if (rowIt != td->rowPositions.constEnd()) {
| 0 | ||||||||||||||||||||||||
1043 | ++rowIt; | - | ||||||||||||||||||||||||
1044 | lastRow = rowIt - td->rowPositions.constBegin(); | - | ||||||||||||||||||||||||
1045 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1046 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1047 | - | |||||||||||||||||||||||||
1048 | for (int c = 0; c < columns; ++c) {
| 0 | ||||||||||||||||||||||||
1049 | QTextTableCell cell = table->cellAt(firstRow, c); | - | ||||||||||||||||||||||||
1050 | firstRow = qMin(firstRow, cell.row()); | - | ||||||||||||||||||||||||
1051 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1052 | - | |||||||||||||||||||||||||
1053 | for (int r = firstRow; r < lastRow; ++r) {
| 0 | ||||||||||||||||||||||||
1054 | for (int c = 0; c < columns; ++c) {
| 0 | ||||||||||||||||||||||||
1055 | QTextTableCell cell = table->cellAt(r, c); | - | ||||||||||||||||||||||||
1056 | QAbstractTextDocumentLayout::PaintContext cell_context = context; | - | ||||||||||||||||||||||||
1057 | adjustContextSelectionsForCell(cell_context, cell, r, c, selectedTableCells.data()); | - | ||||||||||||||||||||||||
1058 | QRectF cellRect = td->cellRect(cell); | - | ||||||||||||||||||||||||
1059 | - | |||||||||||||||||||||||||
1060 | cellRect.translate(off); | - | ||||||||||||||||||||||||
1061 | // we need to account for the cell border in the clipping test | - | ||||||||||||||||||||||||
1062 | int leftAdjust = qMin(qreal(0), 1 - border); | - | ||||||||||||||||||||||||
1063 | if (cell_context.clip.isValid() && !cellRect.adjusted(leftAdjust, leftAdjust, border, border).intersects(cell_context.clip))
| 0 | ||||||||||||||||||||||||
1064 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1065 | - | |||||||||||||||||||||||||
1066 | drawTableCell(cellRect, painter, cell_context, table, td, r, c, &cursorBlockNeedingRepaint, | - | ||||||||||||||||||||||||
1067 | &offsetOfRepaintedCursorBlock); | - | ||||||||||||||||||||||||
1068 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1069 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1070 | - | |||||||||||||||||||||||||
1071 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
1072 | drawFrameDecoration(painter, frame, fd, context.clip, frameRect); | - | ||||||||||||||||||||||||
1073 | - | |||||||||||||||||||||||||
1074 | QTextFrame::Iterator it = frame->begin(); | - | ||||||||||||||||||||||||
1075 | - | |||||||||||||||||||||||||
1076 | if (frame == docPrivate->rootFrame())
| 0 | ||||||||||||||||||||||||
1077 | it = frameIteratorForYPosition(QFixed::fromReal(context.clip.top())); never executed: it = frameIteratorForYPosition(QFixed::fromReal(context.clip.top())); | 0 | ||||||||||||||||||||||||
1078 | - | |||||||||||||||||||||||||
1079 | QList<QTextFrame *> floats; | - | ||||||||||||||||||||||||
1080 | const int numFloats = fd->floats.count(); | - | ||||||||||||||||||||||||
1081 | floats.reserve(numFloats); | - | ||||||||||||||||||||||||
1082 | for (int i = 0; i < numFloats; ++i)
| 0 | ||||||||||||||||||||||||
1083 | floats.append(fd->floats.at(i)); never executed: floats.append(fd->floats.at(i)); | 0 | ||||||||||||||||||||||||
1084 | - | |||||||||||||||||||||||||
1085 | drawFlow(off, painter, context, it, floats, &cursorBlockNeedingRepaint); | - | ||||||||||||||||||||||||
1086 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1087 | - | |||||||||||||||||||||||||
1088 | if (cursorBlockNeedingRepaint.isValid()) {
| 0 | ||||||||||||||||||||||||
1089 | const QPen oldPen = painter->pen(); | - | ||||||||||||||||||||||||
1090 | painter->setPen(context.palette.color(QPalette::Text)); | - | ||||||||||||||||||||||||
1091 | const int cursorPos = context.cursorPosition - cursorBlockNeedingRepaint.position(); | - | ||||||||||||||||||||||||
1092 | cursorBlockNeedingRepaint.layout()->drawCursor(painter, offsetOfRepaintedCursorBlock, | - | ||||||||||||||||||||||||
1093 | cursorPos, cursorWidth); | - | ||||||||||||||||||||||||
1094 | painter->setPen(oldPen); | - | ||||||||||||||||||||||||
1095 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1096 | - | |||||||||||||||||||||||||
1097 | // DEC_INDENT; | - | ||||||||||||||||||||||||
1098 | - | |||||||||||||||||||||||||
1099 | return; never executed: return; | 0 | ||||||||||||||||||||||||
1100 | } | - | ||||||||||||||||||||||||
1101 | - | |||||||||||||||||||||||||
1102 | void QTextDocumentLayoutPrivate::drawTableCell(const QRectF &cellRect, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &cell_context, | - | ||||||||||||||||||||||||
1103 | QTextTable *table, QTextTableData *td, int r, int c, | - | ||||||||||||||||||||||||
1104 | QTextBlock *cursorBlockNeedingRepaint, QPointF *cursorBlockOffset) const | - | ||||||||||||||||||||||||
1105 | { | - | ||||||||||||||||||||||||
1106 | QTextTableCell cell = table->cellAt(r, c); | - | ||||||||||||||||||||||||
1107 | int rspan = cell.rowSpan(); | - | ||||||||||||||||||||||||
1108 | int cspan = cell.columnSpan(); | - | ||||||||||||||||||||||||
1109 | if (rspan != 1) {
| 0 | ||||||||||||||||||||||||
1110 | int cr = cell.row(); | - | ||||||||||||||||||||||||
1111 | if (cr != r)
| 0 | ||||||||||||||||||||||||
1112 | return; never executed: return; | 0 | ||||||||||||||||||||||||
1113 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1114 | if (cspan != 1) {
| 0 | ||||||||||||||||||||||||
1115 | int cc = cell.column(); | - | ||||||||||||||||||||||||
1116 | if (cc != c)
| 0 | ||||||||||||||||||||||||
1117 | return; never executed: return; | 0 | ||||||||||||||||||||||||
1118 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1119 | - | |||||||||||||||||||||||||
1120 | QTextFormat fmt = cell.format(); | - | ||||||||||||||||||||||||
1121 | const QFixed leftPadding = td->leftPadding(fmt); | - | ||||||||||||||||||||||||
1122 | const QFixed topPadding = td->topPadding(fmt); | - | ||||||||||||||||||||||||
1123 | - | |||||||||||||||||||||||||
1124 | qreal topMargin = (td->effectiveTopMargin + td->cellSpacing + td->border).toReal(); | - | ||||||||||||||||||||||||
1125 | qreal bottomMargin = (td->effectiveBottomMargin + td->cellSpacing + td->border).toReal(); | - | ||||||||||||||||||||||||
1126 | - | |||||||||||||||||||||||||
1127 | const int headerRowCount = qMin(table->format().headerRowCount(), table->rows() - 1); | - | ||||||||||||||||||||||||
1128 | if (r >= headerRowCount)
| 0 | ||||||||||||||||||||||||
1129 | topMargin += td->headerHeight.toReal(); never executed: topMargin += td->headerHeight.toReal(); | 0 | ||||||||||||||||||||||||
1130 | - | |||||||||||||||||||||||||
1131 | if (td->border != 0) {
| 0 | ||||||||||||||||||||||||
1132 | const QBrush oldBrush = painter->brush(); | - | ||||||||||||||||||||||||
1133 | const QPen oldPen = painter->pen(); | - | ||||||||||||||||||||||||
1134 | - | |||||||||||||||||||||||||
1135 | const qreal border = td->border.toReal(); | - | ||||||||||||||||||||||||
1136 | - | |||||||||||||||||||||||||
1137 | QRectF borderRect(cellRect.left() - border, cellRect.top() - border, cellRect.width() + border, cellRect.height() + border); | - | ||||||||||||||||||||||||
1138 | - | |||||||||||||||||||||||||
1139 | // invert the border style for cells | - | ||||||||||||||||||||||||
1140 | QTextFrameFormat::BorderStyle cellBorder = table->format().borderStyle(); | - | ||||||||||||||||||||||||
1141 | switch (cellBorder) { | - | ||||||||||||||||||||||||
1142 | case QTextFrameFormat::BorderStyle_Inset: never executed: case QTextFrameFormat::BorderStyle_Inset: | 0 | ||||||||||||||||||||||||
1143 | cellBorder = QTextFrameFormat::BorderStyle_Outset; | - | ||||||||||||||||||||||||
1144 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1145 | case QTextFrameFormat::BorderStyle_Outset: never executed: case QTextFrameFormat::BorderStyle_Outset: | 0 | ||||||||||||||||||||||||
1146 | cellBorder = QTextFrameFormat::BorderStyle_Inset; | - | ||||||||||||||||||||||||
1147 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1148 | case QTextFrameFormat::BorderStyle_Groove: never executed: case QTextFrameFormat::BorderStyle_Groove: | 0 | ||||||||||||||||||||||||
1149 | cellBorder = QTextFrameFormat::BorderStyle_Ridge; | - | ||||||||||||||||||||||||
1150 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1151 | case QTextFrameFormat::BorderStyle_Ridge: never executed: case QTextFrameFormat::BorderStyle_Ridge: | 0 | ||||||||||||||||||||||||
1152 | cellBorder = QTextFrameFormat::BorderStyle_Groove; | - | ||||||||||||||||||||||||
1153 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1154 | default: never executed: default: | 0 | ||||||||||||||||||||||||
1155 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1156 | } | - | ||||||||||||||||||||||||
1157 | - | |||||||||||||||||||||||||
1158 | drawBorder(painter, borderRect, topMargin, bottomMargin, | - | ||||||||||||||||||||||||
1159 | border, table->format().borderBrush(), cellBorder); | - | ||||||||||||||||||||||||
1160 | - | |||||||||||||||||||||||||
1161 | painter->setBrush(oldBrush); | - | ||||||||||||||||||||||||
1162 | painter->setPen(oldPen); | - | ||||||||||||||||||||||||
1163 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1164 | - | |||||||||||||||||||||||||
1165 | const QBrush bg = cell.format().background(); | - | ||||||||||||||||||||||||
1166 | const QPointF brushOrigin = painter->brushOrigin(); | - | ||||||||||||||||||||||||
1167 | if (bg.style() != Qt::NoBrush) {
| 0 | ||||||||||||||||||||||||
1168 | const qreal pageHeight = document->pageSize().height(); | - | ||||||||||||||||||||||||
1169 | const int topPage = pageHeight > 0 ? static_cast<int>(cellRect.top() / pageHeight) : 0;
| 0 | ||||||||||||||||||||||||
1170 | const int bottomPage = pageHeight > 0 ? static_cast<int>((cellRect.bottom()) / pageHeight) : 0;
| 0 | ||||||||||||||||||||||||
1171 | - | |||||||||||||||||||||||||
1172 | if (topPage == bottomPage)
| 0 | ||||||||||||||||||||||||
1173 | fillBackground(painter, cellRect, bg, cellRect.topLeft()); never executed: fillBackground(painter, cellRect, bg, cellRect.topLeft()); | 0 | ||||||||||||||||||||||||
1174 | else { | - | ||||||||||||||||||||||||
1175 | for (int i = topPage; i <= bottomPage; ++i) {
| 0 | ||||||||||||||||||||||||
1176 | QRectF clipped = cellRect.toRect(); | - | ||||||||||||||||||||||||
1177 | - | |||||||||||||||||||||||||
1178 | if (topPage != bottomPage) {
| 0 | ||||||||||||||||||||||||
1179 | const qreal top = qMax(i * pageHeight + topMargin, cell_context.clip.top()); | - | ||||||||||||||||||||||||
1180 | const qreal bottom = qMin((i + 1) * pageHeight - bottomMargin, cell_context.clip.bottom()); | - | ||||||||||||||||||||||||
1181 | - | |||||||||||||||||||||||||
1182 | clipped.setTop(qMax(clipped.top(), top)); | - | ||||||||||||||||||||||||
1183 | clipped.setBottom(qMin(clipped.bottom(), bottom)); | - | ||||||||||||||||||||||||
1184 | - | |||||||||||||||||||||||||
1185 | if (clipped.bottom() <= clipped.top())
| 0 | ||||||||||||||||||||||||
1186 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1187 | - | |||||||||||||||||||||||||
1188 | fillBackground(painter, clipped, bg, cellRect.topLeft()); | - | ||||||||||||||||||||||||
1189 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1190 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1191 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1192 | - | |||||||||||||||||||||||||
1193 | if (bg.style() > Qt::SolidPattern)
| 0 | ||||||||||||||||||||||||
1194 | painter->setBrushOrigin(cellRect.topLeft()); never executed: painter->setBrushOrigin(cellRect.topLeft()); | 0 | ||||||||||||||||||||||||
1195 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1196 | - | |||||||||||||||||||||||||
1197 | const QFixed verticalOffset = td->cellVerticalOffsets.at(c + r * table->columns()); | - | ||||||||||||||||||||||||
1198 | - | |||||||||||||||||||||||||
1199 | const QPointF cellPos = QPointF(cellRect.left() + leftPadding.toReal(), | - | ||||||||||||||||||||||||
1200 | cellRect.top() + (topPadding + verticalOffset).toReal()); | - | ||||||||||||||||||||||||
1201 | - | |||||||||||||||||||||||||
1202 | QTextBlock repaintBlock; | - | ||||||||||||||||||||||||
1203 | drawFlow(cellPos, painter, cell_context, cell.begin(), | - | ||||||||||||||||||||||||
1204 | td->childFrameMap.values(r + c * table->rows()), | - | ||||||||||||||||||||||||
1205 | &repaintBlock); | - | ||||||||||||||||||||||||
1206 | if (repaintBlock.isValid()) {
| 0 | ||||||||||||||||||||||||
1207 | *cursorBlockNeedingRepaint = repaintBlock; | - | ||||||||||||||||||||||||
1208 | *cursorBlockOffset = cellPos; | - | ||||||||||||||||||||||||
1209 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1210 | - | |||||||||||||||||||||||||
1211 | if (bg.style() > Qt::SolidPattern)
| 0 | ||||||||||||||||||||||||
1212 | painter->setBrushOrigin(brushOrigin); never executed: painter->setBrushOrigin(brushOrigin); | 0 | ||||||||||||||||||||||||
1213 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1214 | - | |||||||||||||||||||||||||
1215 | void QTextDocumentLayoutPrivate::drawFlow(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context, | - | ||||||||||||||||||||||||
1216 | QTextFrame::Iterator it, const QList<QTextFrame *> &floats, QTextBlock *cursorBlockNeedingRepaint) const | - | ||||||||||||||||||||||||
1217 | { | - | ||||||||||||||||||||||||
1218 | Q_Q(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
1219 | const bool inRootFrame = (!it.atEnd() && it.parentFrame() && it.parentFrame()->parentFrame() == 0);
| 0 | ||||||||||||||||||||||||
1220 | - | |||||||||||||||||||||||||
1221 | QVector<QCheckPoint>::ConstIterator lastVisibleCheckPoint = checkPoints.end(); | - | ||||||||||||||||||||||||
1222 | if (inRootFrame && context.clip.isValid()) {
| 0 | ||||||||||||||||||||||||
1223 | lastVisibleCheckPoint = std::lower_bound(checkPoints.begin(), checkPoints.end(), QFixed::fromReal(context.clip.bottom())); | - | ||||||||||||||||||||||||
1224 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1225 | - | |||||||||||||||||||||||||
1226 | QTextBlock previousBlock; | - | ||||||||||||||||||||||||
1227 | QTextFrame *previousFrame = 0; | - | ||||||||||||||||||||||||
1228 | - | |||||||||||||||||||||||||
1229 | for (; !it.atEnd(); ++it) {
| 0 | ||||||||||||||||||||||||
1230 | QTextFrame *c = it.currentFrame(); | - | ||||||||||||||||||||||||
1231 | - | |||||||||||||||||||||||||
1232 | if (inRootFrame && !checkPoints.isEmpty()) {
| 0 | ||||||||||||||||||||||||
1233 | int currentPosInDoc; | - | ||||||||||||||||||||||||
1234 | if (c)
| 0 | ||||||||||||||||||||||||
1235 | currentPosInDoc = c->firstPosition(); never executed: currentPosInDoc = c->firstPosition(); | 0 | ||||||||||||||||||||||||
1236 | else | - | ||||||||||||||||||||||||
1237 | currentPosInDoc = it.currentBlock().position(); never executed: currentPosInDoc = it.currentBlock().position(); | 0 | ||||||||||||||||||||||||
1238 | - | |||||||||||||||||||||||||
1239 | // if we're past what is already laid out then we're better off | - | ||||||||||||||||||||||||
1240 | // not trying to draw things that may not be positioned correctly yet | - | ||||||||||||||||||||||||
1241 | if (currentPosInDoc >= checkPoints.constLast().positionInFrame)
| 0 | ||||||||||||||||||||||||
1242 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1243 | - | |||||||||||||||||||||||||
1244 | if (lastVisibleCheckPoint != checkPoints.end()
| 0 | ||||||||||||||||||||||||
1245 | && context.clip.isValid()
| 0 | ||||||||||||||||||||||||
1246 | && currentPosInDoc >= lastVisibleCheckPoint->positionInFrame
| 0 | ||||||||||||||||||||||||
1247 | ) | - | ||||||||||||||||||||||||
1248 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1249 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1250 | - | |||||||||||||||||||||||||
1251 | if (c)
| 0 | ||||||||||||||||||||||||
1252 | drawFrame(offset, painter, context, c); never executed: drawFrame(offset, painter, context, c); | 0 | ||||||||||||||||||||||||
1253 | else { | - | ||||||||||||||||||||||||
1254 | QAbstractTextDocumentLayout::PaintContext pc = context; | - | ||||||||||||||||||||||||
1255 | if (isEmptyBlockAfterTable(it.currentBlock(), previousFrame))
| 0 | ||||||||||||||||||||||||
1256 | pc.selections.clear(); never executed: pc.selections.clear(); | 0 | ||||||||||||||||||||||||
1257 | drawBlock(offset, painter, pc, it.currentBlock(), inRootFrame); | - | ||||||||||||||||||||||||
1258 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1259 | - | |||||||||||||||||||||||||
1260 | // when entering a table and the previous block is empty | - | ||||||||||||||||||||||||
1261 | // then layoutFlow 'hides' the block that just causes a | - | ||||||||||||||||||||||||
1262 | // new line by positioning it /on/ the table border. as we | - | ||||||||||||||||||||||||
1263 | // draw that block before the table itself the decoration | - | ||||||||||||||||||||||||
1264 | // 'overpaints' the cursor and we need to paint it afterwards | - | ||||||||||||||||||||||||
1265 | // again | - | ||||||||||||||||||||||||
1266 | if (isEmptyBlockBeforeTable(previousBlock, previousBlock.blockFormat(), it)
| 0 | ||||||||||||||||||||||||
1267 | && previousBlock.contains(context.cursorPosition)
| 0 | ||||||||||||||||||||||||
1268 | ) { | - | ||||||||||||||||||||||||
1269 | *cursorBlockNeedingRepaint = previousBlock; | - | ||||||||||||||||||||||||
1270 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1271 | - | |||||||||||||||||||||||||
1272 | previousBlock = it.currentBlock(); | - | ||||||||||||||||||||||||
1273 | previousFrame = c; | - | ||||||||||||||||||||||||
1274 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1275 | - | |||||||||||||||||||||||||
1276 | for (int i = 0; i < floats.count(); ++i) {
| 0 | ||||||||||||||||||||||||
1277 | QTextFrame *frame = floats.at(i); | - | ||||||||||||||||||||||||
1278 | if (!isFrameFromInlineObject(frame)
| 0 | ||||||||||||||||||||||||
1279 | || frame->frameFormat().position() == QTextFrameFormat::InFlow)
| 0 | ||||||||||||||||||||||||
1280 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1281 | - | |||||||||||||||||||||||||
1282 | const int pos = frame->firstPosition() - 1; | - | ||||||||||||||||||||||||
1283 | QTextCharFormat format = const_cast<QTextDocumentLayout *>(q)->format(pos); | - | ||||||||||||||||||||||||
1284 | QTextObjectInterface *handler = q->handlerForObject(format.objectType()); | - | ||||||||||||||||||||||||
1285 | if (handler) {
| 0 | ||||||||||||||||||||||||
1286 | QRectF rect = frameBoundingRectInternal(frame); | - | ||||||||||||||||||||||||
1287 | handler->drawObject(painter, rect, document, pos, format); | - | ||||||||||||||||||||||||
1288 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1289 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1290 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1291 | - | |||||||||||||||||||||||||
1292 | void QTextDocumentLayoutPrivate::drawBlock(const QPointF &offset, QPainter *painter, | - | ||||||||||||||||||||||||
1293 | const QAbstractTextDocumentLayout::PaintContext &context, | - | ||||||||||||||||||||||||
1294 | const QTextBlock &bl, bool inRootFrame) const | - | ||||||||||||||||||||||||
1295 | { | - | ||||||||||||||||||||||||
1296 | const QTextLayout *tl = bl.layout(); | - | ||||||||||||||||||||||||
1297 | QRectF r = tl->boundingRect(); | - | ||||||||||||||||||||||||
1298 | r.translate(offset + tl->position()); | - | ||||||||||||||||||||||||
1299 | if (!bl.isVisible() || (context.clip.isValid() && (r.bottom() < context.clip.y() || r.top() > context.clip.bottom())))
| 0 | ||||||||||||||||||||||||
1300 | return; never executed: return; | 0 | ||||||||||||||||||||||||
1301 | // LDEBUG << debug_indent << "drawBlock" << bl.position() << "at" << offset << "br" << tl->boundingRect(); | - | ||||||||||||||||||||||||
1302 | - | |||||||||||||||||||||||||
1303 | QTextBlockFormat blockFormat = bl.blockFormat(); | - | ||||||||||||||||||||||||
1304 | - | |||||||||||||||||||||||||
1305 | QBrush bg = blockFormat.background(); | - | ||||||||||||||||||||||||
1306 | if (bg != Qt::NoBrush) {
| 0 | ||||||||||||||||||||||||
1307 | QRectF rect = r; | - | ||||||||||||||||||||||||
1308 | - | |||||||||||||||||||||||||
1309 | // extend the background rectangle if we're in the root frame with NoWrap, | - | ||||||||||||||||||||||||
1310 | // as the rect of the text block will then be only the width of the text | - | ||||||||||||||||||||||||
1311 | // instead of the full page width | - | ||||||||||||||||||||||||
1312 | if (inRootFrame && document->pageSize().width() <= 0) {
| 0 | ||||||||||||||||||||||||
1313 | const QTextFrameData *fd = data(document->rootFrame()); | - | ||||||||||||||||||||||||
1314 | rect.setRight((fd->size.width - fd->rightMargin).toReal()); | - | ||||||||||||||||||||||||
1315 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1316 | - | |||||||||||||||||||||||||
1317 | fillBackground(painter, rect, bg, r.topLeft()); | - | ||||||||||||||||||||||||
1318 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1319 | - | |||||||||||||||||||||||||
1320 | QVector<QTextLayout::FormatRange> selections; | - | ||||||||||||||||||||||||
1321 | int blpos = bl.position(); | - | ||||||||||||||||||||||||
1322 | int bllen = bl.length(); | - | ||||||||||||||||||||||||
1323 | const QTextCharFormat *selFormat = 0; | - | ||||||||||||||||||||||||
1324 | for (int i = 0; i < context.selections.size(); ++i) {
| 0 | ||||||||||||||||||||||||
1325 | const QAbstractTextDocumentLayout::Selection &range = context.selections.at(i); | - | ||||||||||||||||||||||||
1326 | const int selStart = range.cursor.selectionStart() - blpos; | - | ||||||||||||||||||||||||
1327 | const int selEnd = range.cursor.selectionEnd() - blpos; | - | ||||||||||||||||||||||||
1328 | if (selStart < bllen && selEnd > 0
| 0 | ||||||||||||||||||||||||
1329 | && selEnd > selStart) {
| 0 | ||||||||||||||||||||||||
1330 | QTextLayout::FormatRange o; | - | ||||||||||||||||||||||||
1331 | o.start = selStart; | - | ||||||||||||||||||||||||
1332 | o.length = selEnd - selStart; | - | ||||||||||||||||||||||||
1333 | o.format = range.format; | - | ||||||||||||||||||||||||
1334 | selections.append(o); | - | ||||||||||||||||||||||||
1335 | } else if (! range.cursor.hasSelection() && range.format.hasProperty(QTextFormat::FullWidthSelection) never executed: end of block
| 0 | ||||||||||||||||||||||||
1336 | && bl.contains(range.cursor.position())) {
| 0 | ||||||||||||||||||||||||
1337 | // for full width selections we don't require an actual selection, just | - | ||||||||||||||||||||||||
1338 | // a position to specify the line. that's more convenience in usage. | - | ||||||||||||||||||||||||
1339 | QTextLayout::FormatRange o; | - | ||||||||||||||||||||||||
1340 | QTextLine l = tl->lineForTextPosition(range.cursor.position() - blpos); | - | ||||||||||||||||||||||||
1341 | o.start = l.textStart(); | - | ||||||||||||||||||||||||
1342 | o.length = l.textLength(); | - | ||||||||||||||||||||||||
1343 | if (o.start + o.length == bllen - 1)
| 0 | ||||||||||||||||||||||||
1344 | ++o.length; // include newline never executed: ++o.length; | 0 | ||||||||||||||||||||||||
1345 | o.format = range.format; | - | ||||||||||||||||||||||||
1346 | selections.append(o); | - | ||||||||||||||||||||||||
1347 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1348 | if (selStart < 0 && selEnd >= 1)
| 0 | ||||||||||||||||||||||||
1349 | selFormat = &range.format; never executed: selFormat = &range.format; | 0 | ||||||||||||||||||||||||
1350 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1351 | - | |||||||||||||||||||||||||
1352 | QTextObject *object = document->objectForFormat(bl.blockFormat()); | - | ||||||||||||||||||||||||
1353 | if (object && object->format().toListFormat().style() != QTextListFormat::ListStyleUndefined)
| 0 | ||||||||||||||||||||||||
1354 | drawListItem(offset, painter, context, bl, selFormat); never executed: drawListItem(offset, painter, context, bl, selFormat); | 0 | ||||||||||||||||||||||||
1355 | - | |||||||||||||||||||||||||
1356 | QPen oldPen = painter->pen(); | - | ||||||||||||||||||||||||
1357 | painter->setPen(context.palette.color(QPalette::Text)); | - | ||||||||||||||||||||||||
1358 | - | |||||||||||||||||||||||||
1359 | tl->draw(painter, offset, selections, context.clip.isValid() ? (context.clip & clipRect) : clipRect); | - | ||||||||||||||||||||||||
1360 | - | |||||||||||||||||||||||||
1361 | if ((context.cursorPosition >= blpos && context.cursorPosition < blpos + bllen)
| 0 | ||||||||||||||||||||||||
1362 | || (context.cursorPosition < -1 && !tl->preeditAreaText().isEmpty())) {
| 0 | ||||||||||||||||||||||||
1363 | int cpos = context.cursorPosition; | - | ||||||||||||||||||||||||
1364 | if (cpos < -1)
| 0 | ||||||||||||||||||||||||
1365 | cpos = tl->preeditAreaPosition() - (cpos + 2); never executed: cpos = tl->preeditAreaPosition() - (cpos + 2); | 0 | ||||||||||||||||||||||||
1366 | else | - | ||||||||||||||||||||||||
1367 | cpos -= blpos; never executed: cpos -= blpos; | 0 | ||||||||||||||||||||||||
1368 | tl->drawCursor(painter, offset, cpos, cursorWidth); | - | ||||||||||||||||||||||||
1369 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1370 | - | |||||||||||||||||||||||||
1371 | if (blockFormat.hasProperty(QTextFormat::BlockTrailingHorizontalRulerWidth)) {
| 0 | ||||||||||||||||||||||||
1372 | const qreal width = blockFormat.lengthProperty(QTextFormat::BlockTrailingHorizontalRulerWidth).value(r.width()); | - | ||||||||||||||||||||||||
1373 | painter->setPen(context.palette.color(QPalette::Dark)); | - | ||||||||||||||||||||||||
1374 | qreal y = r.bottom(); | - | ||||||||||||||||||||||||
1375 | if (bl.length() == 1)
| 0 | ||||||||||||||||||||||||
1376 | y = r.top() + r.height() / 2; never executed: y = r.top() + r.height() / 2; | 0 | ||||||||||||||||||||||||
1377 | - | |||||||||||||||||||||||||
1378 | const qreal middleX = r.left() + r.width() / 2; | - | ||||||||||||||||||||||||
1379 | painter->drawLine(QLineF(middleX - width / 2, y, middleX + width / 2, y)); | - | ||||||||||||||||||||||||
1380 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1381 | - | |||||||||||||||||||||||||
1382 | painter->setPen(oldPen); | - | ||||||||||||||||||||||||
1383 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1384 | - | |||||||||||||||||||||||||
1385 | - | |||||||||||||||||||||||||
1386 | void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *painter, | - | ||||||||||||||||||||||||
1387 | const QAbstractTextDocumentLayout::PaintContext &context, | - | ||||||||||||||||||||||||
1388 | const QTextBlock &bl, const QTextCharFormat *selectionFormat) const | - | ||||||||||||||||||||||||
1389 | { | - | ||||||||||||||||||||||||
1390 | Q_Q(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
1391 | const QTextBlockFormat blockFormat = bl.blockFormat(); | - | ||||||||||||||||||||||||
1392 | const QTextCharFormat charFormat = QTextCursor(bl).charFormat(); | - | ||||||||||||||||||||||||
1393 | QFont font(charFormat.font()); | - | ||||||||||||||||||||||||
1394 | if (q->paintDevice())
| 0 | ||||||||||||||||||||||||
1395 | font = QFont(font, q->paintDevice()); never executed: font = QFont(font, q->paintDevice()); | 0 | ||||||||||||||||||||||||
1396 | - | |||||||||||||||||||||||||
1397 | const QFontMetrics fontMetrics(font); | - | ||||||||||||||||||||||||
1398 | QTextObject * const object = document->objectForFormat(blockFormat); | - | ||||||||||||||||||||||||
1399 | const QTextListFormat lf = object->format().toListFormat(); | - | ||||||||||||||||||||||||
1400 | int style = lf.style(); | - | ||||||||||||||||||||||||
1401 | QString itemText; | - | ||||||||||||||||||||||||
1402 | QSizeF size; | - | ||||||||||||||||||||||||
1403 | - | |||||||||||||||||||||||||
1404 | if (blockFormat.hasProperty(QTextFormat::ListStyle))
| 0 | ||||||||||||||||||||||||
1405 | style = QTextListFormat::Style(blockFormat.intProperty(QTextFormat::ListStyle)); never executed: style = QTextListFormat::Style(blockFormat.intProperty(QTextFormat::ListStyle)); | 0 | ||||||||||||||||||||||||
1406 | - | |||||||||||||||||||||||||
1407 | QTextLayout *layout = bl.layout(); | - | ||||||||||||||||||||||||
1408 | if (layout->lineCount() == 0)
| 0 | ||||||||||||||||||||||||
1409 | return; never executed: return; | 0 | ||||||||||||||||||||||||
1410 | QTextLine firstLine = layout->lineAt(0); | - | ||||||||||||||||||||||||
1411 | Q_ASSERT(firstLine.isValid()); | - | ||||||||||||||||||||||||
1412 | QPointF pos = (offset + layout->position()).toPoint(); | - | ||||||||||||||||||||||||
1413 | Qt::LayoutDirection dir = bl.textDirection(); | - | ||||||||||||||||||||||||
1414 | { | - | ||||||||||||||||||||||||
1415 | QRectF textRect = firstLine.naturalTextRect(); | - | ||||||||||||||||||||||||
1416 | pos += textRect.topLeft().toPoint(); | - | ||||||||||||||||||||||||
1417 | if (dir == Qt::RightToLeft)
| 0 | ||||||||||||||||||||||||
1418 | pos.rx() += textRect.width(); never executed: pos.rx() += textRect.width(); | 0 | ||||||||||||||||||||||||
1419 | } | - | ||||||||||||||||||||||||
1420 | - | |||||||||||||||||||||||||
1421 | switch (style) { | - | ||||||||||||||||||||||||
1422 | case QTextListFormat::ListDecimal: never executed: case QTextListFormat::ListDecimal: | 0 | ||||||||||||||||||||||||
1423 | case QTextListFormat::ListLowerAlpha: never executed: case QTextListFormat::ListLowerAlpha: | 0 | ||||||||||||||||||||||||
1424 | case QTextListFormat::ListUpperAlpha: never executed: case QTextListFormat::ListUpperAlpha: | 0 | ||||||||||||||||||||||||
1425 | case QTextListFormat::ListLowerRoman: never executed: case QTextListFormat::ListLowerRoman: | 0 | ||||||||||||||||||||||||
1426 | case QTextListFormat::ListUpperRoman: never executed: case QTextListFormat::ListUpperRoman: | 0 | ||||||||||||||||||||||||
1427 | itemText = static_cast<QTextList *>(object)->itemText(bl); | - | ||||||||||||||||||||||||
1428 | size.setWidth(fontMetrics.width(itemText)); | - | ||||||||||||||||||||||||
1429 | size.setHeight(fontMetrics.height()); | - | ||||||||||||||||||||||||
1430 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1431 | - | |||||||||||||||||||||||||
1432 | case QTextListFormat::ListSquare: never executed: case QTextListFormat::ListSquare: | 0 | ||||||||||||||||||||||||
1433 | case QTextListFormat::ListCircle: never executed: case QTextListFormat::ListCircle: | 0 | ||||||||||||||||||||||||
1434 | case QTextListFormat::ListDisc: never executed: case QTextListFormat::ListDisc: | 0 | ||||||||||||||||||||||||
1435 | size.setWidth(fontMetrics.lineSpacing() / 3); | - | ||||||||||||||||||||||||
1436 | size.setHeight(size.width()); | - | ||||||||||||||||||||||||
1437 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1438 | - | |||||||||||||||||||||||||
1439 | case QTextListFormat::ListStyleUndefined: never executed: case QTextListFormat::ListStyleUndefined: | 0 | ||||||||||||||||||||||||
1440 | return; never executed: return; | 0 | ||||||||||||||||||||||||
1441 | default: return; never executed: return; never executed: default: | 0 | ||||||||||||||||||||||||
1442 | } | - | ||||||||||||||||||||||||
1443 | - | |||||||||||||||||||||||||
1444 | QRectF r(pos, size); | - | ||||||||||||||||||||||||
1445 | - | |||||||||||||||||||||||||
1446 | qreal xoff = fontMetrics.width(QLatin1Char(' ')); | - | ||||||||||||||||||||||||
1447 | if (dir == Qt::LeftToRight)
| 0 | ||||||||||||||||||||||||
1448 | xoff = -xoff - size.width(); never executed: xoff = -xoff - size.width(); | 0 | ||||||||||||||||||||||||
1449 | r.translate( xoff, (fontMetrics.height() / 2) - (size.height() / 2)); | - | ||||||||||||||||||||||||
1450 | - | |||||||||||||||||||||||||
1451 | painter->save(); | - | ||||||||||||||||||||||||
1452 | - | |||||||||||||||||||||||||
1453 | painter->setRenderHint(QPainter::Antialiasing); | - | ||||||||||||||||||||||||
1454 | - | |||||||||||||||||||||||||
1455 | if (selectionFormat) {
| 0 | ||||||||||||||||||||||||
1456 | painter->setPen(QPen(selectionFormat->foreground(), 0)); | - | ||||||||||||||||||||||||
1457 | painter->fillRect(r, selectionFormat->background()); | - | ||||||||||||||||||||||||
1458 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
1459 | QBrush fg = charFormat.foreground(); | - | ||||||||||||||||||||||||
1460 | if (fg == Qt::NoBrush)
| 0 | ||||||||||||||||||||||||
1461 | fg = context.palette.text(); never executed: fg = context.palette.text(); | 0 | ||||||||||||||||||||||||
1462 | painter->setPen(QPen(fg, 0)); | - | ||||||||||||||||||||||||
1463 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1464 | - | |||||||||||||||||||||||||
1465 | QBrush brush = context.palette.brush(QPalette::Text); | - | ||||||||||||||||||||||||
1466 | - | |||||||||||||||||||||||||
1467 | switch (style) { | - | ||||||||||||||||||||||||
1468 | case QTextListFormat::ListDecimal: never executed: case QTextListFormat::ListDecimal: | 0 | ||||||||||||||||||||||||
1469 | case QTextListFormat::ListLowerAlpha: never executed: case QTextListFormat::ListLowerAlpha: | 0 | ||||||||||||||||||||||||
1470 | case QTextListFormat::ListUpperAlpha: never executed: case QTextListFormat::ListUpperAlpha: | 0 | ||||||||||||||||||||||||
1471 | case QTextListFormat::ListLowerRoman: never executed: case QTextListFormat::ListLowerRoman: | 0 | ||||||||||||||||||||||||
1472 | case QTextListFormat::ListUpperRoman: { never executed: case QTextListFormat::ListUpperRoman: | 0 | ||||||||||||||||||||||||
1473 | QTextLayout layout(itemText, font, q->paintDevice()); | - | ||||||||||||||||||||||||
1474 | layout.setCacheEnabled(true); | - | ||||||||||||||||||||||||
1475 | QTextOption option(Qt::AlignLeft | Qt::AlignAbsolute); | - | ||||||||||||||||||||||||
1476 | option.setTextDirection(dir); | - | ||||||||||||||||||||||||
1477 | layout.setTextOption(option); | - | ||||||||||||||||||||||||
1478 | layout.beginLayout(); | - | ||||||||||||||||||||||||
1479 | QTextLine line = layout.createLine(); | - | ||||||||||||||||||||||||
1480 | if (line.isValid())
| 0 | ||||||||||||||||||||||||
1481 | line.setLeadingIncluded(true); never executed: line.setLeadingIncluded(true); | 0 | ||||||||||||||||||||||||
1482 | layout.endLayout(); | - | ||||||||||||||||||||||||
1483 | layout.draw(painter, QPointF(r.left(), pos.y())); | - | ||||||||||||||||||||||||
1484 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1485 | } | - | ||||||||||||||||||||||||
1486 | case QTextListFormat::ListSquare: never executed: case QTextListFormat::ListSquare: | 0 | ||||||||||||||||||||||||
1487 | painter->fillRect(r, brush); | - | ||||||||||||||||||||||||
1488 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1489 | case QTextListFormat::ListCircle: never executed: case QTextListFormat::ListCircle: | 0 | ||||||||||||||||||||||||
1490 | painter->setPen(QPen(brush, 0)); | - | ||||||||||||||||||||||||
1491 | painter->drawEllipse(r.translated(0.5, 0.5)); // pixel align for sharper rendering | - | ||||||||||||||||||||||||
1492 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1493 | case QTextListFormat::ListDisc: never executed: case QTextListFormat::ListDisc: | 0 | ||||||||||||||||||||||||
1494 | painter->setBrush(brush); | - | ||||||||||||||||||||||||
1495 | painter->setPen(Qt::NoPen); | - | ||||||||||||||||||||||||
1496 | painter->drawEllipse(r); | - | ||||||||||||||||||||||||
1497 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1498 | case QTextListFormat::ListStyleUndefined: never executed: case QTextListFormat::ListStyleUndefined: | 0 | ||||||||||||||||||||||||
1499 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1500 | default: never executed: default: | 0 | ||||||||||||||||||||||||
1501 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1502 | } | - | ||||||||||||||||||||||||
1503 | - | |||||||||||||||||||||||||
1504 | painter->restore(); | - | ||||||||||||||||||||||||
1505 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1506 | - | |||||||||||||||||||||||||
1507 | static QFixed flowPosition(const QTextFrame::iterator it) | - | ||||||||||||||||||||||||
1508 | { | - | ||||||||||||||||||||||||
1509 | if (it.atEnd())
| 0 | ||||||||||||||||||||||||
1510 | return 0; never executed: return 0; | 0 | ||||||||||||||||||||||||
1511 | - | |||||||||||||||||||||||||
1512 | if (it.currentFrame()) {
| 0 | ||||||||||||||||||||||||
1513 | return data(it.currentFrame())->position.y; never executed: return data(it.currentFrame())->position.y; | 0 | ||||||||||||||||||||||||
1514 | } else { | - | ||||||||||||||||||||||||
1515 | QTextBlock block = it.currentBlock(); | - | ||||||||||||||||||||||||
1516 | QTextLayout *layout = block.layout(); | - | ||||||||||||||||||||||||
1517 | if (layout->lineCount() == 0)
| 0 | ||||||||||||||||||||||||
1518 | return QFixed::fromReal(layout->position().y()); never executed: return QFixed::fromReal(layout->position().y()); | 0 | ||||||||||||||||||||||||
1519 | else | - | ||||||||||||||||||||||||
1520 | return QFixed::fromReal(layout->position().y() + layout->lineAt(0).y()); never executed: return QFixed::fromReal(layout->position().y() + layout->lineAt(0).y()); | 0 | ||||||||||||||||||||||||
1521 | } | - | ||||||||||||||||||||||||
1522 | } | - | ||||||||||||||||||||||||
1523 | - | |||||||||||||||||||||||||
1524 | static QFixed firstChildPos(const QTextFrame *f) | - | ||||||||||||||||||||||||
1525 | { | - | ||||||||||||||||||||||||
1526 | return flowPosition(f->begin()); never executed: return flowPosition(f->begin()); | 0 | ||||||||||||||||||||||||
1527 | } | - | ||||||||||||||||||||||||
1528 | - | |||||||||||||||||||||||||
1529 | QTextLayoutStruct QTextDocumentLayoutPrivate::layoutCell(QTextTable *t, const QTextTableCell &cell, QFixed width, | - | ||||||||||||||||||||||||
1530 | int layoutFrom, int layoutTo, QTextTableData *td, | - | ||||||||||||||||||||||||
1531 | QFixed absoluteTableY, bool withPageBreaks) | - | ||||||||||||||||||||||||
1532 | { | - | ||||||||||||||||||||||||
1533 | LDEBUG << "layoutCell"; dead code: QMessageLogger(__FILE__, 1533, __PRETTY_FUNCTION__).debug() << "layoutCell"; | - | ||||||||||||||||||||||||
1534 | QTextLayoutStruct layoutStruct; | - | ||||||||||||||||||||||||
1535 | layoutStruct.frame = t; | - | ||||||||||||||||||||||||
1536 | layoutStruct.minimumWidth = 0; | - | ||||||||||||||||||||||||
1537 | layoutStruct.maximumWidth = QFIXED_MAX; | - | ||||||||||||||||||||||||
1538 | layoutStruct.y = 0; | - | ||||||||||||||||||||||||
1539 | - | |||||||||||||||||||||||||
1540 | const QTextFormat fmt = cell.format(); | - | ||||||||||||||||||||||||
1541 | const QFixed topPadding = td->topPadding(fmt); | - | ||||||||||||||||||||||||
1542 | if (withPageBreaks) {
| 0 | ||||||||||||||||||||||||
1543 | layoutStruct.frameY = absoluteTableY + td->rowPositions.at(cell.row()) + topPadding; | - | ||||||||||||||||||||||||
1544 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1545 | layoutStruct.x_left = 0; | - | ||||||||||||||||||||||||
1546 | layoutStruct.x_right = width; | - | ||||||||||||||||||||||||
1547 | // we get called with different widths all the time (for example for figuring | - | ||||||||||||||||||||||||
1548 | // out the min/max widths), so we always have to do the full layout ;( | - | ||||||||||||||||||||||||
1549 | // also when for example in a table layoutFrom/layoutTo affect only one cell, | - | ||||||||||||||||||||||||
1550 | // making that one cell grow the available width of the other cells may change | - | ||||||||||||||||||||||||
1551 | // (shrink) and therefore when layoutCell gets called for them they have to | - | ||||||||||||||||||||||||
1552 | // be re-laid out, even if layoutFrom/layoutTo is not in their range. Hence | - | ||||||||||||||||||||||||
1553 | // this line: | - | ||||||||||||||||||||||||
1554 | - | |||||||||||||||||||||||||
1555 | layoutStruct.pageHeight = QFixed::fromReal(document->pageSize().height()); | - | ||||||||||||||||||||||||
1556 | if (layoutStruct.pageHeight < 0 || !withPageBreaks)
| 0 | ||||||||||||||||||||||||
1557 | layoutStruct.pageHeight = QFIXED_MAX; never executed: layoutStruct.pageHeight = (2147483647/256); | 0 | ||||||||||||||||||||||||
1558 | const int currentPage = layoutStruct.currentPage(); | - | ||||||||||||||||||||||||
1559 | layoutStruct.pageTopMargin = td->effectiveTopMargin + td->cellSpacing + td->border + topPadding; | - | ||||||||||||||||||||||||
1560 | layoutStruct.pageBottomMargin = td->effectiveBottomMargin + td->cellSpacing + td->border + td->bottomPadding(fmt); | - | ||||||||||||||||||||||||
1561 | layoutStruct.pageBottom = (currentPage + 1) * layoutStruct.pageHeight - layoutStruct.pageBottomMargin; | - | ||||||||||||||||||||||||
1562 | - | |||||||||||||||||||||||||
1563 | layoutStruct.fullLayout = true; | - | ||||||||||||||||||||||||
1564 | - | |||||||||||||||||||||||||
1565 | QFixed pageTop = currentPage * layoutStruct.pageHeight + layoutStruct.pageTopMargin - layoutStruct.frameY; | - | ||||||||||||||||||||||||
1566 | layoutStruct.y = qMax(layoutStruct.y, pageTop); | - | ||||||||||||||||||||||||
1567 | - | |||||||||||||||||||||||||
1568 | const QList<QTextFrame *> childFrames = td->childFrameMap.values(cell.row() + cell.column() * t->rows()); | - | ||||||||||||||||||||||||
1569 | for (int i = 0; i < childFrames.size(); ++i) {
| 0 | ||||||||||||||||||||||||
1570 | QTextFrame *frame = childFrames.at(i); | - | ||||||||||||||||||||||||
1571 | QTextFrameData *cd = data(frame); | - | ||||||||||||||||||||||||
1572 | cd->sizeDirty = true; | - | ||||||||||||||||||||||||
1573 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1574 | - | |||||||||||||||||||||||||
1575 | layoutFlow(cell.begin(), &layoutStruct, layoutFrom, layoutTo, width); | - | ||||||||||||||||||||||||
1576 | - | |||||||||||||||||||||||||
1577 | QFixed floatMinWidth; | - | ||||||||||||||||||||||||
1578 | - | |||||||||||||||||||||||||
1579 | // floats that are located inside the text (like inline images) aren't taken into account by | - | ||||||||||||||||||||||||
1580 | // layoutFlow with regards to the cell height (layoutStruct->y), so for a safety measure we | - | ||||||||||||||||||||||||
1581 | // do that here. For example with <td><img align="right" src="..." />blah</td> | - | ||||||||||||||||||||||||
1582 | // when the image happens to be higher than the text | - | ||||||||||||||||||||||||
1583 | for (int i = 0; i < childFrames.size(); ++i) {
| 0 | ||||||||||||||||||||||||
1584 | QTextFrame *frame = childFrames.at(i); | - | ||||||||||||||||||||||||
1585 | QTextFrameData *cd = data(frame); | - | ||||||||||||||||||||||||
1586 | - | |||||||||||||||||||||||||
1587 | if (frame->frameFormat().position() != QTextFrameFormat::InFlow)
| 0 | ||||||||||||||||||||||||
1588 | layoutStruct.y = qMax(layoutStruct.y, cd->position.y + cd->size.height); never executed: layoutStruct.y = qMax(layoutStruct.y, cd->position.y + cd->size.height); | 0 | ||||||||||||||||||||||||
1589 | - | |||||||||||||||||||||||||
1590 | floatMinWidth = qMax(floatMinWidth, cd->minimumWidth); | - | ||||||||||||||||||||||||
1591 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1592 | - | |||||||||||||||||||||||||
1593 | // constraint the maximumWidth by the minimum width of the fixed size floats, to | - | ||||||||||||||||||||||||
1594 | // keep them visible | - | ||||||||||||||||||||||||
1595 | layoutStruct.maximumWidth = qMax(layoutStruct.maximumWidth, floatMinWidth); | - | ||||||||||||||||||||||||
1596 | - | |||||||||||||||||||||||||
1597 | // as floats in cells get added to the table's float list but must not affect | - | ||||||||||||||||||||||||
1598 | // floats in other cells we must clear the list here. | - | ||||||||||||||||||||||||
1599 | data(t)->floats.clear(); | - | ||||||||||||||||||||||||
1600 | - | |||||||||||||||||||||||||
1601 | // qDebug("layoutCell done"); | - | ||||||||||||||||||||||||
1602 | - | |||||||||||||||||||||||||
1603 | return layoutStruct; never executed: return layoutStruct; | 0 | ||||||||||||||||||||||||
1604 | } | - | ||||||||||||||||||||||||
1605 | - | |||||||||||||||||||||||||
1606 | QRectF QTextDocumentLayoutPrivate::layoutTable(QTextTable *table, int layoutFrom, int layoutTo, QFixed parentY) | - | ||||||||||||||||||||||||
1607 | { | - | ||||||||||||||||||||||||
1608 | LDEBUG << "layoutTable"; dead code: QMessageLogger(__FILE__, 1608, __PRETTY_FUNCTION__).debug() << "layoutTable"; | - | ||||||||||||||||||||||||
1609 | QTextTableData *td = static_cast<QTextTableData *>(data(table)); | - | ||||||||||||||||||||||||
1610 | Q_ASSERT(td->sizeDirty); | - | ||||||||||||||||||||||||
1611 | const int rows = table->rows(); | - | ||||||||||||||||||||||||
1612 | const int columns = table->columns(); | - | ||||||||||||||||||||||||
1613 | - | |||||||||||||||||||||||||
1614 | const QTextTableFormat fmt = table->format(); | - | ||||||||||||||||||||||||
1615 | - | |||||||||||||||||||||||||
1616 | td->childFrameMap.clear(); | - | ||||||||||||||||||||||||
1617 | { | - | ||||||||||||||||||||||||
1618 | const QList<QTextFrame *> children = table->childFrames(); | - | ||||||||||||||||||||||||
1619 | for (int i = 0; i < children.count(); ++i) {
| 0 | ||||||||||||||||||||||||
1620 | QTextFrame *frame = children.at(i); | - | ||||||||||||||||||||||||
1621 | QTextTableCell cell = table->cellAt(frame->firstPosition()); | - | ||||||||||||||||||||||||
1622 | td->childFrameMap.insertMulti(cell.row() + cell.column() * rows, frame); | - | ||||||||||||||||||||||||
1623 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1624 | } | - | ||||||||||||||||||||||||
1625 | - | |||||||||||||||||||||||||
1626 | QVector<QTextLength> columnWidthConstraints = fmt.columnWidthConstraints(); | - | ||||||||||||||||||||||||
1627 | if (columnWidthConstraints.size() != columns)
| 0 | ||||||||||||||||||||||||
1628 | columnWidthConstraints.resize(columns); never executed: columnWidthConstraints.resize(columns); | 0 | ||||||||||||||||||||||||
1629 | Q_ASSERT(columnWidthConstraints.count() == columns); | - | ||||||||||||||||||||||||
1630 | - | |||||||||||||||||||||||||
1631 | const QFixed cellSpacing = td->cellSpacing = QFixed::fromReal(scaleToDevice(fmt.cellSpacing())); | - | ||||||||||||||||||||||||
1632 | td->deviceScale = scaleToDevice(qreal(1)); | - | ||||||||||||||||||||||||
1633 | td->cellPadding = QFixed::fromReal(scaleToDevice(fmt.cellPadding())); | - | ||||||||||||||||||||||||
1634 | const QFixed leftMargin = td->leftMargin + td->border + td->padding; | - | ||||||||||||||||||||||||
1635 | const QFixed rightMargin = td->rightMargin + td->border + td->padding; | - | ||||||||||||||||||||||||
1636 | const QFixed topMargin = td->topMargin + td->border + td->padding; | - | ||||||||||||||||||||||||
1637 | - | |||||||||||||||||||||||||
1638 | const QFixed absoluteTableY = parentY + td->position.y; | - | ||||||||||||||||||||||||
1639 | - | |||||||||||||||||||||||||
1640 | const QTextOption::WrapMode oldDefaultWrapMode = docPrivate->defaultTextOption.wrapMode(); | - | ||||||||||||||||||||||||
1641 | - | |||||||||||||||||||||||||
1642 | recalc_minmax_widths: code before this statement never executed: recalc_minmax_widths: | 0 | ||||||||||||||||||||||||
1643 | - | |||||||||||||||||||||||||
1644 | QFixed remainingWidth = td->contentsWidth; | - | ||||||||||||||||||||||||
1645 | // two (vertical) borders per cell per column | - | ||||||||||||||||||||||||
1646 | remainingWidth -= columns * 2 * td->border; | - | ||||||||||||||||||||||||
1647 | // inter-cell spacing | - | ||||||||||||||||||||||||
1648 | remainingWidth -= (columns - 1) * cellSpacing; | - | ||||||||||||||||||||||||
1649 | // cell spacing at the left and right hand side | - | ||||||||||||||||||||||||
1650 | remainingWidth -= 2 * cellSpacing; | - | ||||||||||||||||||||||||
1651 | // remember the width used to distribute to percentaged columns | - | ||||||||||||||||||||||||
1652 | const QFixed initialTotalWidth = remainingWidth; | - | ||||||||||||||||||||||||
1653 | - | |||||||||||||||||||||||||
1654 | td->widths.resize(columns); | - | ||||||||||||||||||||||||
1655 | td->widths.fill(0); | - | ||||||||||||||||||||||||
1656 | - | |||||||||||||||||||||||||
1657 | td->minWidths.resize(columns); | - | ||||||||||||||||||||||||
1658 | // start with a minimum width of 0. totally empty | - | ||||||||||||||||||||||||
1659 | // cells of default created tables are invisible otherwise | - | ||||||||||||||||||||||||
1660 | // and therefore hardly editable | - | ||||||||||||||||||||||||
1661 | td->minWidths.fill(1); | - | ||||||||||||||||||||||||
1662 | - | |||||||||||||||||||||||||
1663 | td->maxWidths.resize(columns); | - | ||||||||||||||||||||||||
1664 | td->maxWidths.fill(QFIXED_MAX); | - | ||||||||||||||||||||||||
1665 | - | |||||||||||||||||||||||||
1666 | // calculate minimum and maximum sizes of the columns | - | ||||||||||||||||||||||||
1667 | for (int i = 0; i < columns; ++i) {
| 0 | ||||||||||||||||||||||||
1668 | for (int row = 0; row < rows; ++row) {
| 0 | ||||||||||||||||||||||||
1669 | const QTextTableCell cell = table->cellAt(row, i); | - | ||||||||||||||||||||||||
1670 | const int cspan = cell.columnSpan(); | - | ||||||||||||||||||||||||
1671 | - | |||||||||||||||||||||||||
1672 | if (cspan > 1 && i != cell.column())
| 0 | ||||||||||||||||||||||||
1673 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1674 | - | |||||||||||||||||||||||||
1675 | const QTextFormat fmt = cell.format(); | - | ||||||||||||||||||||||||
1676 | const QFixed leftPadding = td->leftPadding(fmt); | - | ||||||||||||||||||||||||
1677 | const QFixed rightPadding = td->rightPadding(fmt); | - | ||||||||||||||||||||||||
1678 | const QFixed widthPadding = leftPadding + rightPadding; | - | ||||||||||||||||||||||||
1679 | - | |||||||||||||||||||||||||
1680 | // to figure out the min and the max width lay out the cell at | - | ||||||||||||||||||||||||
1681 | // maximum width. otherwise the maxwidth calculation sometimes | - | ||||||||||||||||||||||||
1682 | // returns wrong values | - | ||||||||||||||||||||||||
1683 | QTextLayoutStruct layoutStruct = layoutCell(table, cell, QFIXED_MAX, layoutFrom, | - | ||||||||||||||||||||||||
1684 | layoutTo, td, absoluteTableY, | - | ||||||||||||||||||||||||
1685 | /*withPageBreaks =*/false); | - | ||||||||||||||||||||||||
1686 | - | |||||||||||||||||||||||||
1687 | // distribute the minimum width over all columns the cell spans | - | ||||||||||||||||||||||||
1688 | QFixed widthToDistribute = layoutStruct.minimumWidth + widthPadding; | - | ||||||||||||||||||||||||
1689 | for (int n = 0; n < cspan; ++n) {
| 0 | ||||||||||||||||||||||||
1690 | const int col = i + n; | - | ||||||||||||||||||||||||
1691 | QFixed w = widthToDistribute / (cspan - n); | - | ||||||||||||||||||||||||
1692 | td->minWidths[col] = qMax(td->minWidths.at(col), w); | - | ||||||||||||||||||||||||
1693 | widthToDistribute -= td->minWidths.at(col); | - | ||||||||||||||||||||||||
1694 | if (widthToDistribute <= 0)
| 0 | ||||||||||||||||||||||||
1695 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1696 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1697 | - | |||||||||||||||||||||||||
1698 | QFixed maxW = td->maxWidths.at(i); | - | ||||||||||||||||||||||||
1699 | if (layoutStruct.maximumWidth != QFIXED_MAX) {
| 0 | ||||||||||||||||||||||||
1700 | if (maxW == QFIXED_MAX)
| 0 | ||||||||||||||||||||||||
1701 | maxW = layoutStruct.maximumWidth + widthPadding; never executed: maxW = layoutStruct.maximumWidth + widthPadding; | 0 | ||||||||||||||||||||||||
1702 | else | - | ||||||||||||||||||||||||
1703 | maxW = qMax(maxW, layoutStruct.maximumWidth + widthPadding); never executed: maxW = qMax(maxW, layoutStruct.maximumWidth + widthPadding); | 0 | ||||||||||||||||||||||||
1704 | } | - | ||||||||||||||||||||||||
1705 | if (maxW == QFIXED_MAX)
| 0 | ||||||||||||||||||||||||
1706 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1707 | - | |||||||||||||||||||||||||
1708 | widthToDistribute = maxW; | - | ||||||||||||||||||||||||
1709 | for (int n = 0; n < cspan; ++n) {
| 0 | ||||||||||||||||||||||||
1710 | const int col = i + n; | - | ||||||||||||||||||||||||
1711 | QFixed w = widthToDistribute / (cspan - n); | - | ||||||||||||||||||||||||
1712 | td->maxWidths[col] = qMax(td->minWidths.at(col), w); | - | ||||||||||||||||||||||||
1713 | widthToDistribute -= td->maxWidths.at(col); | - | ||||||||||||||||||||||||
1714 | if (widthToDistribute <= 0)
| 0 | ||||||||||||||||||||||||
1715 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1716 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1717 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1718 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1719 | - | |||||||||||||||||||||||||
1720 | // set fixed values, figure out total percentages used and number of | - | ||||||||||||||||||||||||
1721 | // variable length cells. Also assign the minimum width for variable columns. | - | ||||||||||||||||||||||||
1722 | QFixed totalPercentage; | - | ||||||||||||||||||||||||
1723 | int variableCols = 0; | - | ||||||||||||||||||||||||
1724 | QFixed totalMinWidth = 0; | - | ||||||||||||||||||||||||
1725 | for (int i = 0; i < columns; ++i) {
| 0 | ||||||||||||||||||||||||
1726 | const QTextLength &length = columnWidthConstraints.at(i); | - | ||||||||||||||||||||||||
1727 | if (length.type() == QTextLength::FixedLength) {
| 0 | ||||||||||||||||||||||||
1728 | td->minWidths[i] = td->widths[i] = qMax(scaleToDevice(QFixed::fromReal(length.rawValue())), td->minWidths.at(i)); | - | ||||||||||||||||||||||||
1729 | remainingWidth -= td->widths.at(i); | - | ||||||||||||||||||||||||
1730 | } else if (length.type() == QTextLength::PercentageLength) { never executed: end of block
| 0 | ||||||||||||||||||||||||
1731 | totalPercentage += QFixed::fromReal(length.rawValue()); | - | ||||||||||||||||||||||||
1732 | } else if (length.type() == QTextLength::VariableLength) { never executed: end of block
| 0 | ||||||||||||||||||||||||
1733 | variableCols++; | - | ||||||||||||||||||||||||
1734 | - | |||||||||||||||||||||||||
1735 | td->widths[i] = td->minWidths.at(i); | - | ||||||||||||||||||||||||
1736 | remainingWidth -= td->minWidths.at(i); | - | ||||||||||||||||||||||||
1737 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1738 | totalMinWidth += td->minWidths.at(i); | - | ||||||||||||||||||||||||
1739 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1740 | - | |||||||||||||||||||||||||
1741 | // set percentage values | - | ||||||||||||||||||||||||
1742 | { | - | ||||||||||||||||||||||||
1743 | const QFixed totalPercentagedWidth = initialTotalWidth * totalPercentage / 100; | - | ||||||||||||||||||||||||
1744 | QFixed remainingMinWidths = totalMinWidth; | - | ||||||||||||||||||||||||
1745 | for (int i = 0; i < columns; ++i) {
| 0 | ||||||||||||||||||||||||
1746 | remainingMinWidths -= td->minWidths.at(i); | - | ||||||||||||||||||||||||
1747 | if (columnWidthConstraints.at(i).type() == QTextLength::PercentageLength) {
| 0 | ||||||||||||||||||||||||
1748 | const QFixed allottedPercentage = QFixed::fromReal(columnWidthConstraints.at(i).rawValue()); | - | ||||||||||||||||||||||||
1749 | - | |||||||||||||||||||||||||
1750 | const QFixed percentWidth = totalPercentagedWidth * allottedPercentage / totalPercentage; | - | ||||||||||||||||||||||||
1751 | if (percentWidth >= td->minWidths.at(i)) {
| 0 | ||||||||||||||||||||||||
1752 | td->widths[i] = qBound(td->minWidths.at(i), percentWidth, remainingWidth - remainingMinWidths); | - | ||||||||||||||||||||||||
1753 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
1754 | td->widths[i] = td->minWidths.at(i); | - | ||||||||||||||||||||||||
1755 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1756 | remainingWidth -= td->widths.at(i); | - | ||||||||||||||||||||||||
1757 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1758 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1759 | } | - | ||||||||||||||||||||||||
1760 | - | |||||||||||||||||||||||||
1761 | // for variable columns distribute the remaining space | - | ||||||||||||||||||||||||
1762 | if (variableCols > 0 && remainingWidth > 0) {
| 0 | ||||||||||||||||||||||||
1763 | QVarLengthArray<int> columnsWithProperMaxSize; | - | ||||||||||||||||||||||||
1764 | for (int i = 0; i < columns; ++i)
| 0 | ||||||||||||||||||||||||
1765 | if (columnWidthConstraints.at(i).type() == QTextLength::VariableLength
| 0 | ||||||||||||||||||||||||
1766 | && td->maxWidths.at(i) != QFIXED_MAX)
| 0 | ||||||||||||||||||||||||
1767 | columnsWithProperMaxSize.append(i); never executed: columnsWithProperMaxSize.append(i); | 0 | ||||||||||||||||||||||||
1768 | - | |||||||||||||||||||||||||
1769 | QFixed lastRemainingWidth = remainingWidth; | - | ||||||||||||||||||||||||
1770 | while (remainingWidth > 0) {
| 0 | ||||||||||||||||||||||||
1771 | for (int k = 0; k < columnsWithProperMaxSize.count(); ++k) {
| 0 | ||||||||||||||||||||||||
1772 | const int col = columnsWithProperMaxSize[k]; | - | ||||||||||||||||||||||||
1773 | const int colsLeft = columnsWithProperMaxSize.count() - k; | - | ||||||||||||||||||||||||
1774 | const QFixed w = qMin(td->maxWidths.at(col) - td->widths.at(col), remainingWidth / colsLeft); | - | ||||||||||||||||||||||||
1775 | td->widths[col] += w; | - | ||||||||||||||||||||||||
1776 | remainingWidth -= w; | - | ||||||||||||||||||||||||
1777 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1778 | if (remainingWidth == lastRemainingWidth)
| 0 | ||||||||||||||||||||||||
1779 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1780 | lastRemainingWidth = remainingWidth; | - | ||||||||||||||||||||||||
1781 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1782 | - | |||||||||||||||||||||||||
1783 | if (remainingWidth > 0
| 0 | ||||||||||||||||||||||||
1784 | // don't unnecessarily grow variable length sized tables | - | ||||||||||||||||||||||||
1785 | && fmt.width().type() != QTextLength::VariableLength) {
| 0 | ||||||||||||||||||||||||
1786 | const QFixed widthPerAnySizedCol = remainingWidth / variableCols; | - | ||||||||||||||||||||||||
1787 | for (int col = 0; col < columns; ++col) {
| 0 | ||||||||||||||||||||||||
1788 | if (columnWidthConstraints.at(col).type() == QTextLength::VariableLength)
| 0 | ||||||||||||||||||||||||
1789 | td->widths[col] += widthPerAnySizedCol; never executed: td->widths[col] += widthPerAnySizedCol; | 0 | ||||||||||||||||||||||||
1790 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1791 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1792 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1793 | - | |||||||||||||||||||||||||
1794 | td->columnPositions.resize(columns); | - | ||||||||||||||||||||||||
1795 | td->columnPositions[0] = leftMargin /*includes table border*/ + cellSpacing + td->border; | - | ||||||||||||||||||||||||
1796 | - | |||||||||||||||||||||||||
1797 | for (int i = 1; i < columns; ++i)
| 0 | ||||||||||||||||||||||||
1798 | td->columnPositions[i] = td->columnPositions.at(i-1) + td->widths.at(i-1) + 2 * td->border + cellSpacing; never executed: td->columnPositions[i] = td->columnPositions.at(i-1) + td->widths.at(i-1) + 2 * td->border + cellSpacing; | 0 | ||||||||||||||||||||||||
1799 | - | |||||||||||||||||||||||||
1800 | // - margin to compensate the + margin in columnPositions[0] | - | ||||||||||||||||||||||||
1801 | const QFixed contentsWidth = td->columnPositions.constLast() + td->widths.constLast() + td->padding + td->border + cellSpacing - leftMargin; | - | ||||||||||||||||||||||||
1802 | - | |||||||||||||||||||||||||
1803 | // if the table is too big and causes an overflow re-do the layout with WrapAnywhere as wrap | - | ||||||||||||||||||||||||
1804 | // mode | - | ||||||||||||||||||||||||
1805 | if (docPrivate->defaultTextOption.wrapMode() == QTextOption::WrapAtWordBoundaryOrAnywhere
| 0 | ||||||||||||||||||||||||
1806 | && contentsWidth > td->contentsWidth) {
| 0 | ||||||||||||||||||||||||
1807 | docPrivate->defaultTextOption.setWrapMode(QTextOption::WrapAnywhere); | - | ||||||||||||||||||||||||
1808 | // go back to the top of the function | - | ||||||||||||||||||||||||
1809 | goto recalc_minmax_widths; never executed: goto recalc_minmax_widths; | 0 | ||||||||||||||||||||||||
1810 | } | - | ||||||||||||||||||||||||
1811 | - | |||||||||||||||||||||||||
1812 | td->contentsWidth = contentsWidth; | - | ||||||||||||||||||||||||
1813 | - | |||||||||||||||||||||||||
1814 | docPrivate->defaultTextOption.setWrapMode(oldDefaultWrapMode); | - | ||||||||||||||||||||||||
1815 | - | |||||||||||||||||||||||||
1816 | td->heights.resize(rows); | - | ||||||||||||||||||||||||
1817 | td->heights.fill(0); | - | ||||||||||||||||||||||||
1818 | - | |||||||||||||||||||||||||
1819 | td->rowPositions.resize(rows); | - | ||||||||||||||||||||||||
1820 | td->rowPositions[0] = topMargin /*includes table border*/ + cellSpacing + td->border; | - | ||||||||||||||||||||||||
1821 | - | |||||||||||||||||||||||||
1822 | bool haveRowSpannedCells = false; | - | ||||||||||||||||||||||||
1823 | - | |||||||||||||||||||||||||
1824 | // need to keep track of cell heights for vertical alignment | - | ||||||||||||||||||||||||
1825 | QVector<QFixed> cellHeights; | - | ||||||||||||||||||||||||
1826 | cellHeights.reserve(rows * columns); | - | ||||||||||||||||||||||||
1827 | - | |||||||||||||||||||||||||
1828 | QFixed pageHeight = QFixed::fromReal(document->pageSize().height()); | - | ||||||||||||||||||||||||
1829 | if (pageHeight <= 0)
| 0 | ||||||||||||||||||||||||
1830 | pageHeight = QFIXED_MAX; never executed: pageHeight = (2147483647/256); | 0 | ||||||||||||||||||||||||
1831 | - | |||||||||||||||||||||||||
1832 | QVector<QFixed> heightToDistribute; | - | ||||||||||||||||||||||||
1833 | heightToDistribute.resize(columns); | - | ||||||||||||||||||||||||
1834 | - | |||||||||||||||||||||||||
1835 | td->headerHeight = 0; | - | ||||||||||||||||||||||||
1836 | const int headerRowCount = qMin(table->format().headerRowCount(), rows - 1); | - | ||||||||||||||||||||||||
1837 | const QFixed originalTopMargin = td->effectiveTopMargin; | - | ||||||||||||||||||||||||
1838 | bool hasDroppedTable = false; | - | ||||||||||||||||||||||||
1839 | - | |||||||||||||||||||||||||
1840 | // now that we have the column widths we can lay out all cells with the right width. | - | ||||||||||||||||||||||||
1841 | // spanning cells are only allowed to grow the last row spanned by the cell. | - | ||||||||||||||||||||||||
1842 | // | - | ||||||||||||||||||||||||
1843 | // ### this could be made faster by iterating over the cells array of QTextTable | - | ||||||||||||||||||||||||
1844 | for (int r = 0; r < rows; ++r) {
| 0 | ||||||||||||||||||||||||
1845 | td->calcRowPosition(r); | - | ||||||||||||||||||||||||
1846 | - | |||||||||||||||||||||||||
1847 | const int tableStartPage = (absoluteTableY / pageHeight).truncate(); | - | ||||||||||||||||||||||||
1848 | const int currentPage = ((td->rowPositions.at(r) + absoluteTableY) / pageHeight).truncate(); | - | ||||||||||||||||||||||||
1849 | const QFixed pageBottom = (currentPage + 1) * pageHeight - td->effectiveBottomMargin - absoluteTableY - cellSpacing - td->border; | - | ||||||||||||||||||||||||
1850 | const QFixed pageTop = currentPage * pageHeight + td->effectiveTopMargin - absoluteTableY + cellSpacing + td->border; | - | ||||||||||||||||||||||||
1851 | const QFixed nextPageTop = pageTop + pageHeight; | - | ||||||||||||||||||||||||
1852 | - | |||||||||||||||||||||||||
1853 | if (td->rowPositions.at(r) > pageBottom)
| 0 | ||||||||||||||||||||||||
1854 | td->rowPositions[r] = nextPageTop; never executed: td->rowPositions[r] = nextPageTop; | 0 | ||||||||||||||||||||||||
1855 | else if (td->rowPositions.at(r) < pageTop)
| 0 | ||||||||||||||||||||||||
1856 | td->rowPositions[r] = pageTop; never executed: td->rowPositions[r] = pageTop; | 0 | ||||||||||||||||||||||||
1857 | - | |||||||||||||||||||||||||
1858 | bool dropRowToNextPage = true; | - | ||||||||||||||||||||||||
1859 | int cellCountBeforeRow = cellHeights.size(); | - | ||||||||||||||||||||||||
1860 | - | |||||||||||||||||||||||||
1861 | // if we drop the row to the next page we need to subtract the drop | - | ||||||||||||||||||||||||
1862 | // distance from any row spanning cells | - | ||||||||||||||||||||||||
1863 | QFixed dropDistance = 0; | - | ||||||||||||||||||||||||
1864 | - | |||||||||||||||||||||||||
1865 | relayout: code before this statement never executed: relayout: | 0 | ||||||||||||||||||||||||
1866 | const int rowStartPage = ((td->rowPositions.at(r) + absoluteTableY) / pageHeight).truncate(); | - | ||||||||||||||||||||||||
1867 | // if any of the header rows or the first non-header row start on the next page | - | ||||||||||||||||||||||||
1868 | // then the entire header should be dropped | - | ||||||||||||||||||||||||
1869 | if (r <= headerRowCount && rowStartPage > tableStartPage && !hasDroppedTable) {
| 0 | ||||||||||||||||||||||||
1870 | td->rowPositions[0] = nextPageTop; | - | ||||||||||||||||||||||||
1871 | cellHeights.clear(); | - | ||||||||||||||||||||||||
1872 | td->effectiveTopMargin = originalTopMargin; | - | ||||||||||||||||||||||||
1873 | hasDroppedTable = true; | - | ||||||||||||||||||||||||
1874 | r = -1; | - | ||||||||||||||||||||||||
1875 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1876 | } | - | ||||||||||||||||||||||||
1877 | - | |||||||||||||||||||||||||
1878 | int rowCellCount = 0; | - | ||||||||||||||||||||||||
1879 | for (int c = 0; c < columns; ++c) {
| 0 | ||||||||||||||||||||||||
1880 | QTextTableCell cell = table->cellAt(r, c); | - | ||||||||||||||||||||||||
1881 | const int rspan = cell.rowSpan(); | - | ||||||||||||||||||||||||
1882 | const int cspan = cell.columnSpan(); | - | ||||||||||||||||||||||||
1883 | - | |||||||||||||||||||||||||
1884 | if (cspan > 1 && cell.column() != c)
| 0 | ||||||||||||||||||||||||
1885 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1886 | - | |||||||||||||||||||||||||
1887 | if (rspan > 1) {
| 0 | ||||||||||||||||||||||||
1888 | haveRowSpannedCells = true; | - | ||||||||||||||||||||||||
1889 | - | |||||||||||||||||||||||||
1890 | const int cellRow = cell.row(); | - | ||||||||||||||||||||||||
1891 | if (cellRow != r) {
| 0 | ||||||||||||||||||||||||
1892 | // the last row gets all the remaining space | - | ||||||||||||||||||||||||
1893 | if (cellRow + rspan - 1 == r)
| 0 | ||||||||||||||||||||||||
1894 | td->heights[r] = qMax(td->heights.at(r), heightToDistribute.at(c) - dropDistance); never executed: td->heights[r] = qMax(td->heights.at(r), heightToDistribute.at(c) - dropDistance); | 0 | ||||||||||||||||||||||||
1895 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1896 | } | - | ||||||||||||||||||||||||
1897 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1898 | - | |||||||||||||||||||||||||
1899 | const QTextFormat fmt = cell.format(); | - | ||||||||||||||||||||||||
1900 | - | |||||||||||||||||||||||||
1901 | const QFixed topPadding = td->topPadding(fmt); | - | ||||||||||||||||||||||||
1902 | const QFixed bottomPadding = td->bottomPadding(fmt); | - | ||||||||||||||||||||||||
1903 | const QFixed leftPadding = td->leftPadding(fmt); | - | ||||||||||||||||||||||||
1904 | const QFixed rightPadding = td->rightPadding(fmt); | - | ||||||||||||||||||||||||
1905 | const QFixed widthPadding = leftPadding + rightPadding; | - | ||||||||||||||||||||||||
1906 | - | |||||||||||||||||||||||||
1907 | ++rowCellCount; | - | ||||||||||||||||||||||||
1908 | - | |||||||||||||||||||||||||
1909 | const QFixed width = td->cellWidth(c, cspan) - widthPadding; | - | ||||||||||||||||||||||||
1910 | QTextLayoutStruct layoutStruct = layoutCell(table, cell, width, | - | ||||||||||||||||||||||||
1911 | layoutFrom, layoutTo, | - | ||||||||||||||||||||||||
1912 | td, absoluteTableY, | - | ||||||||||||||||||||||||
1913 | /*withPageBreaks =*/true); | - | ||||||||||||||||||||||||
1914 | - | |||||||||||||||||||||||||
1915 | const QFixed height = layoutStruct.y + bottomPadding + topPadding; | - | ||||||||||||||||||||||||
1916 | - | |||||||||||||||||||||||||
1917 | if (rspan > 1)
| 0 | ||||||||||||||||||||||||
1918 | heightToDistribute[c] = height + dropDistance; never executed: heightToDistribute[c] = height + dropDistance; | 0 | ||||||||||||||||||||||||
1919 | else | - | ||||||||||||||||||||||||
1920 | td->heights[r] = qMax(td->heights.at(r), height); never executed: td->heights[r] = qMax(td->heights.at(r), height); | 0 | ||||||||||||||||||||||||
1921 | - | |||||||||||||||||||||||||
1922 | cellHeights.append(layoutStruct.y); | - | ||||||||||||||||||||||||
1923 | - | |||||||||||||||||||||||||
1924 | QFixed childPos = td->rowPositions.at(r) + topPadding + flowPosition(cell.begin()); | - | ||||||||||||||||||||||||
1925 | if (childPos < pageBottom)
| 0 | ||||||||||||||||||||||||
1926 | dropRowToNextPage = false; never executed: dropRowToNextPage = false; | 0 | ||||||||||||||||||||||||
1927 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1928 | - | |||||||||||||||||||||||||
1929 | if (rowCellCount > 0 && dropRowToNextPage) {
| 0 | ||||||||||||||||||||||||
1930 | dropDistance = nextPageTop - td->rowPositions.at(r); | - | ||||||||||||||||||||||||
1931 | td->rowPositions[r] = nextPageTop; | - | ||||||||||||||||||||||||
1932 | td->heights[r] = 0; | - | ||||||||||||||||||||||||
1933 | dropRowToNextPage = false; | - | ||||||||||||||||||||||||
1934 | cellHeights.resize(cellCountBeforeRow); | - | ||||||||||||||||||||||||
1935 | if (r > headerRowCount)
| 0 | ||||||||||||||||||||||||
1936 | td->heights[r - 1] = pageBottom - td->rowPositions.at(r - 1); never executed: td->heights[r - 1] = pageBottom - td->rowPositions.at(r - 1); | 0 | ||||||||||||||||||||||||
1937 | goto relayout; never executed: goto relayout; | 0 | ||||||||||||||||||||||||
1938 | } | - | ||||||||||||||||||||||||
1939 | - | |||||||||||||||||||||||||
1940 | if (haveRowSpannedCells) {
| 0 | ||||||||||||||||||||||||
1941 | const QFixed effectiveHeight = td->heights.at(r) + td->border + cellSpacing + td->border; | - | ||||||||||||||||||||||||
1942 | for (int c = 0; c < columns; ++c)
| 0 | ||||||||||||||||||||||||
1943 | heightToDistribute[c] = qMax(heightToDistribute.at(c) - effectiveHeight - dropDistance, QFixed(0)); never executed: heightToDistribute[c] = qMax(heightToDistribute.at(c) - effectiveHeight - dropDistance, QFixed(0)); | 0 | ||||||||||||||||||||||||
1944 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1945 | - | |||||||||||||||||||||||||
1946 | if (r == headerRowCount - 1) {
| 0 | ||||||||||||||||||||||||
1947 | td->headerHeight = td->rowPositions.at(r) + td->heights.at(r) - td->rowPositions.at(0) + td->cellSpacing + 2 * td->border; | - | ||||||||||||||||||||||||
1948 | td->headerHeight -= td->headerHeight * (td->headerHeight / pageHeight).truncate(); | - | ||||||||||||||||||||||||
1949 | td->effectiveTopMargin += td->headerHeight; | - | ||||||||||||||||||||||||
1950 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1951 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1952 | - | |||||||||||||||||||||||||
1953 | td->effectiveTopMargin = originalTopMargin; | - | ||||||||||||||||||||||||
1954 | - | |||||||||||||||||||||||||
1955 | // now that all cells have been properly laid out, we can compute the | - | ||||||||||||||||||||||||
1956 | // vertical offsets for vertical alignment | - | ||||||||||||||||||||||||
1957 | td->cellVerticalOffsets.resize(rows * columns); | - | ||||||||||||||||||||||||
1958 | int cellIndex = 0; | - | ||||||||||||||||||||||||
1959 | for (int r = 0; r < rows; ++r) {
| 0 | ||||||||||||||||||||||||
1960 | for (int c = 0; c < columns; ++c) {
| 0 | ||||||||||||||||||||||||
1961 | QTextTableCell cell = table->cellAt(r, c); | - | ||||||||||||||||||||||||
1962 | if (cell.row() != r || cell.column() != c)
| 0 | ||||||||||||||||||||||||
1963 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1964 | - | |||||||||||||||||||||||||
1965 | const int rowSpan = cell.rowSpan(); | - | ||||||||||||||||||||||||
1966 | const QFixed availableHeight = td->rowPositions.at(r + rowSpan - 1) + td->heights.at(r + rowSpan - 1) - td->rowPositions.at(r); | - | ||||||||||||||||||||||||
1967 | - | |||||||||||||||||||||||||
1968 | const QTextCharFormat cellFormat = cell.format(); | - | ||||||||||||||||||||||||
1969 | const QFixed cellHeight = cellHeights.at(cellIndex++) + td->topPadding(cellFormat) + td->bottomPadding(cellFormat); | - | ||||||||||||||||||||||||
1970 | - | |||||||||||||||||||||||||
1971 | QFixed offset = 0; | - | ||||||||||||||||||||||||
1972 | switch (cellFormat.verticalAlignment()) { | - | ||||||||||||||||||||||||
1973 | case QTextCharFormat::AlignMiddle: never executed: case QTextCharFormat::AlignMiddle: | 0 | ||||||||||||||||||||||||
1974 | offset = (availableHeight - cellHeight) / 2; | - | ||||||||||||||||||||||||
1975 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1976 | case QTextCharFormat::AlignBottom: never executed: case QTextCharFormat::AlignBottom: | 0 | ||||||||||||||||||||||||
1977 | offset = availableHeight - cellHeight; | - | ||||||||||||||||||||||||
1978 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1979 | default: never executed: default: | 0 | ||||||||||||||||||||||||
1980 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1981 | }; | - | ||||||||||||||||||||||||
1982 | - | |||||||||||||||||||||||||
1983 | for (int rd = 0; rd < cell.rowSpan(); ++rd) {
| 0 | ||||||||||||||||||||||||
1984 | for (int cd = 0; cd < cell.columnSpan(); ++cd) {
| 0 | ||||||||||||||||||||||||
1985 | const int index = (c + cd) + (r + rd) * columns; | - | ||||||||||||||||||||||||
1986 | td->cellVerticalOffsets[index] = offset; | - | ||||||||||||||||||||||||
1987 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1988 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1989 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1990 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1991 | - | |||||||||||||||||||||||||
1992 | td->minimumWidth = td->columnPositions.at(0); | - | ||||||||||||||||||||||||
1993 | for (int i = 0; i < columns; ++i) {
| 0 | ||||||||||||||||||||||||
1994 | td->minimumWidth += td->minWidths.at(i) + 2 * td->border + cellSpacing; | - | ||||||||||||||||||||||||
1995 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1996 | td->minimumWidth += rightMargin - td->border; | - | ||||||||||||||||||||||||
1997 | - | |||||||||||||||||||||||||
1998 | td->maximumWidth = td->columnPositions.at(0); | - | ||||||||||||||||||||||||
1999 | for (int i = 0; i < columns; ++i)
| 0 | ||||||||||||||||||||||||
2000 | if (td->maxWidths.at(i) != QFIXED_MAX)
| 0 | ||||||||||||||||||||||||
2001 | td->maximumWidth += td->maxWidths.at(i) + 2 * td->border + cellSpacing; never executed: td->maximumWidth += td->maxWidths.at(i) + 2 * td->border + cellSpacing; | 0 | ||||||||||||||||||||||||
2002 | td->maximumWidth += rightMargin - td->border; | - | ||||||||||||||||||||||||
2003 | - | |||||||||||||||||||||||||
2004 | td->updateTableSize(); | - | ||||||||||||||||||||||||
2005 | td->sizeDirty = false; | - | ||||||||||||||||||||||||
2006 | return QRectF(); // invalid rect -> update everything never executed: return QRectF(); | 0 | ||||||||||||||||||||||||
2007 | } | - | ||||||||||||||||||||||||
2008 | - | |||||||||||||||||||||||||
2009 | void QTextDocumentLayoutPrivate::positionFloat(QTextFrame *frame, QTextLine *currentLine) | - | ||||||||||||||||||||||||
2010 | { | - | ||||||||||||||||||||||||
2011 | QTextFrameData *fd = data(frame); | - | ||||||||||||||||||||||||
2012 | - | |||||||||||||||||||||||||
2013 | QTextFrame *parent = frame->parentFrame(); | - | ||||||||||||||||||||||||
2014 | Q_ASSERT(parent); | - | ||||||||||||||||||||||||
2015 | QTextFrameData *pd = data(parent); | - | ||||||||||||||||||||||||
2016 | Q_ASSERT(pd && pd->currentLayoutStruct); | - | ||||||||||||||||||||||||
2017 | - | |||||||||||||||||||||||||
2018 | QTextLayoutStruct *layoutStruct = pd->currentLayoutStruct; | - | ||||||||||||||||||||||||
2019 | - | |||||||||||||||||||||||||
2020 | if (!pd->floats.contains(frame))
| 0 | ||||||||||||||||||||||||
2021 | pd->floats.append(frame); never executed: pd->floats.append(frame); | 0 | ||||||||||||||||||||||||
2022 | fd->layoutDirty = true; | - | ||||||||||||||||||||||||
2023 | Q_ASSERT(!fd->sizeDirty); | - | ||||||||||||||||||||||||
2024 | - | |||||||||||||||||||||||||
2025 | // qDebug() << "positionFloat:" << frame << "width=" << fd->size.width; | - | ||||||||||||||||||||||||
2026 | QFixed y = layoutStruct->y; | - | ||||||||||||||||||||||||
2027 | if (currentLine) {
| 0 | ||||||||||||||||||||||||
2028 | QFixed left, right; | - | ||||||||||||||||||||||||
2029 | floatMargins(y, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2030 | // qDebug() << "have line: right=" << right << "left=" << left << "textWidth=" << currentLine->width(); | - | ||||||||||||||||||||||||
2031 | if (right - left < QFixed::fromReal(currentLine->naturalTextWidth()) + fd->size.width) {
| 0 | ||||||||||||||||||||||||
2032 | layoutStruct->pendingFloats.append(frame); | - | ||||||||||||||||||||||||
2033 | // qDebug(" adding to pending list"); | - | ||||||||||||||||||||||||
2034 | return; never executed: return; | 0 | ||||||||||||||||||||||||
2035 | } | - | ||||||||||||||||||||||||
2036 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2037 | - | |||||||||||||||||||||||||
2038 | bool frameSpansIntoNextPage = (y + layoutStruct->frameY + fd->size.height > layoutStruct->pageBottom); | - | ||||||||||||||||||||||||
2039 | if (frameSpansIntoNextPage && fd->size.height <= layoutStruct->pageHeight) {
| 0 | ||||||||||||||||||||||||
2040 | layoutStruct->newPage(); | - | ||||||||||||||||||||||||
2041 | y = layoutStruct->y; | - | ||||||||||||||||||||||||
2042 | - | |||||||||||||||||||||||||
2043 | frameSpansIntoNextPage = false; | - | ||||||||||||||||||||||||
2044 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2045 | - | |||||||||||||||||||||||||
2046 | y = findY(y, layoutStruct, fd->size.width); | - | ||||||||||||||||||||||||
2047 | - | |||||||||||||||||||||||||
2048 | QFixed left, right; | - | ||||||||||||||||||||||||
2049 | floatMargins(y, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2050 | - | |||||||||||||||||||||||||
2051 | if (frame->frameFormat().position() == QTextFrameFormat::FloatLeft) {
| 0 | ||||||||||||||||||||||||
2052 | fd->position.x = left; | - | ||||||||||||||||||||||||
2053 | fd->position.y = y; | - | ||||||||||||||||||||||||
2054 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2055 | fd->position.x = right - fd->size.width; | - | ||||||||||||||||||||||||
2056 | fd->position.y = y; | - | ||||||||||||||||||||||||
2057 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2058 | - | |||||||||||||||||||||||||
2059 | layoutStruct->minimumWidth = qMax(layoutStruct->minimumWidth, fd->minimumWidth); | - | ||||||||||||||||||||||||
2060 | layoutStruct->maximumWidth = qMin(layoutStruct->maximumWidth, fd->maximumWidth); | - | ||||||||||||||||||||||||
2061 | - | |||||||||||||||||||||||||
2062 | // qDebug()<< "float positioned at " << fd->position.x << fd->position.y; | - | ||||||||||||||||||||||||
2063 | fd->layoutDirty = false; | - | ||||||||||||||||||||||||
2064 | - | |||||||||||||||||||||||||
2065 | // If the frame is a table, then positioning it will affect the size if it covers more than | - | ||||||||||||||||||||||||
2066 | // one page, because of page breaks and repeating the header. | - | ||||||||||||||||||||||||
2067 | if (qobject_cast<QTextTable *>(frame) != 0)
| 0 | ||||||||||||||||||||||||
2068 | fd->sizeDirty = frameSpansIntoNextPage; never executed: fd->sizeDirty = frameSpansIntoNextPage; | 0 | ||||||||||||||||||||||||
2069 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2070 | - | |||||||||||||||||||||||||
2071 | QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed parentY) | - | ||||||||||||||||||||||||
2072 | { | - | ||||||||||||||||||||||||
2073 | LDEBUG << "layoutFrame (pre)"; dead code: QMessageLogger(__FILE__, 2073, __PRETTY_FUNCTION__).debug() << "layoutFrame (pre)"; | - | ||||||||||||||||||||||||
2074 | Q_ASSERT(data(f)->sizeDirty); | - | ||||||||||||||||||||||||
2075 | // qDebug("layouting frame (%d--%d), parent=%p", f->firstPosition(), f->lastPosition(), f->parentFrame()); | - | ||||||||||||||||||||||||
2076 | - | |||||||||||||||||||||||||
2077 | QTextFrameFormat fformat = f->frameFormat(); | - | ||||||||||||||||||||||||
2078 | - | |||||||||||||||||||||||||
2079 | QTextFrame *parent = f->parentFrame(); | - | ||||||||||||||||||||||||
2080 | const QTextFrameData *pd = parent ? data(parent) : 0;
| 0 | ||||||||||||||||||||||||
2081 | - | |||||||||||||||||||||||||
2082 | const qreal maximumWidth = qMax(qreal(0), pd ? pd->contentsWidth.toReal() : document->pageSize().width()); | - | ||||||||||||||||||||||||
2083 | QFixed width = QFixed::fromReal(fformat.width().value(maximumWidth)); | - | ||||||||||||||||||||||||
2084 | if (fformat.width().type() == QTextLength::FixedLength)
| 0 | ||||||||||||||||||||||||
2085 | width = scaleToDevice(width); never executed: width = scaleToDevice(width); | 0 | ||||||||||||||||||||||||
2086 | - | |||||||||||||||||||||||||
2087 | const QFixed maximumHeight = pd ? pd->contentsHeight : -1;
| 0 | ||||||||||||||||||||||||
2088 | const QFixed height = (maximumHeight != -1 || fformat.height().type() != QTextLength::PercentageLength)
| 0 | ||||||||||||||||||||||||
2089 | ? QFixed::fromReal(fformat.height().value(maximumHeight.toReal())) | - | ||||||||||||||||||||||||
2090 | : -1; | - | ||||||||||||||||||||||||
2091 | - | |||||||||||||||||||||||||
2092 | return layoutFrame(f, layoutFrom, layoutTo, width, height, parentY); never executed: return layoutFrame(f, layoutFrom, layoutTo, width, height, parentY); | 0 | ||||||||||||||||||||||||
2093 | } | - | ||||||||||||||||||||||||
2094 | - | |||||||||||||||||||||||||
2095 | QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed frameWidth, QFixed frameHeight, QFixed parentY) | - | ||||||||||||||||||||||||
2096 | { | - | ||||||||||||||||||||||||
2097 | LDEBUG << "layoutFrame from=" << layoutFrom << "to=" << layoutTo; dead code: QMessageLogger(__FILE__, 2097, __PRETTY_FUNCTION__).debug() << "layoutFrame from=" << layoutFrom << "to=" << layoutTo; | - | ||||||||||||||||||||||||
2098 | Q_ASSERT(data(f)->sizeDirty); | - | ||||||||||||||||||||||||
2099 | // qDebug("layouting frame (%d--%d), parent=%p", f->firstPosition(), f->lastPosition(), f->parentFrame()); | - | ||||||||||||||||||||||||
2100 | - | |||||||||||||||||||||||||
2101 | QTextFrameData *fd = data(f); | - | ||||||||||||||||||||||||
2102 | QFixed newContentsWidth; | - | ||||||||||||||||||||||||
2103 | - | |||||||||||||||||||||||||
2104 | bool fullLayout = false; | - | ||||||||||||||||||||||||
2105 | { | - | ||||||||||||||||||||||||
2106 | QTextFrameFormat fformat = f->frameFormat(); | - | ||||||||||||||||||||||||
2107 | // set sizes of this frame from the format | - | ||||||||||||||||||||||||
2108 | QFixed tm = QFixed::fromReal(fformat.topMargin()); | - | ||||||||||||||||||||||||
2109 | if (tm != fd->topMargin) {
| 0 | ||||||||||||||||||||||||
2110 | fd->topMargin = tm; | - | ||||||||||||||||||||||||
2111 | fullLayout = true; | - | ||||||||||||||||||||||||
2112 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2113 | QFixed bm = QFixed::fromReal(fformat.bottomMargin()); | - | ||||||||||||||||||||||||
2114 | if (bm != fd->bottomMargin) {
| 0 | ||||||||||||||||||||||||
2115 | fd->bottomMargin = bm; | - | ||||||||||||||||||||||||
2116 | fullLayout = true; | - | ||||||||||||||||||||||||
2117 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2118 | fd->leftMargin = QFixed::fromReal(fformat.leftMargin()); | - | ||||||||||||||||||||||||
2119 | fd->rightMargin = QFixed::fromReal(fformat.rightMargin()); | - | ||||||||||||||||||||||||
2120 | QFixed b = QFixed::fromReal(fformat.border()); | - | ||||||||||||||||||||||||
2121 | if (b != fd->border) {
| 0 | ||||||||||||||||||||||||
2122 | fd->border = b; | - | ||||||||||||||||||||||||
2123 | fullLayout = true; | - | ||||||||||||||||||||||||
2124 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2125 | QFixed p = QFixed::fromReal(fformat.padding()); | - | ||||||||||||||||||||||||
2126 | if (p != fd->padding) {
| 0 | ||||||||||||||||||||||||
2127 | fd->padding = p; | - | ||||||||||||||||||||||||
2128 | fullLayout = true; | - | ||||||||||||||||||||||||
2129 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2130 | - | |||||||||||||||||||||||||
2131 | QTextFrame *parent = f->parentFrame(); | - | ||||||||||||||||||||||||
2132 | const QTextFrameData *pd = parent ? data(parent) : 0;
| 0 | ||||||||||||||||||||||||
2133 | - | |||||||||||||||||||||||||
2134 | // accumulate top and bottom margins | - | ||||||||||||||||||||||||
2135 | if (parent) {
| 0 | ||||||||||||||||||||||||
2136 | fd->effectiveTopMargin = pd->effectiveTopMargin + fd->topMargin + fd->border + fd->padding; | - | ||||||||||||||||||||||||
2137 | fd->effectiveBottomMargin = pd->effectiveBottomMargin + fd->topMargin + fd->border + fd->padding; | - | ||||||||||||||||||||||||
2138 | - | |||||||||||||||||||||||||
2139 | if (qobject_cast<QTextTable *>(parent)) {
| 0 | ||||||||||||||||||||||||
2140 | const QTextTableData *td = static_cast<const QTextTableData *>(pd); | - | ||||||||||||||||||||||||
2141 | fd->effectiveTopMargin += td->cellSpacing + td->border + td->cellPadding; | - | ||||||||||||||||||||||||
2142 | fd->effectiveBottomMargin += td->cellSpacing + td->border + td->cellPadding; | - | ||||||||||||||||||||||||
2143 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2144 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2145 | fd->effectiveTopMargin = fd->topMargin + fd->border + fd->padding; | - | ||||||||||||||||||||||||
2146 | fd->effectiveBottomMargin = fd->bottomMargin + fd->border + fd->padding; | - | ||||||||||||||||||||||||
2147 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2148 | - | |||||||||||||||||||||||||
2149 | newContentsWidth = frameWidth - 2*(fd->border + fd->padding) | - | ||||||||||||||||||||||||
2150 | - fd->leftMargin - fd->rightMargin; | - | ||||||||||||||||||||||||
2151 | - | |||||||||||||||||||||||||
2152 | if (frameHeight != -1) {
| 0 | ||||||||||||||||||||||||
2153 | fd->contentsHeight = frameHeight - 2*(fd->border + fd->padding) | - | ||||||||||||||||||||||||
2154 | - fd->topMargin - fd->bottomMargin; | - | ||||||||||||||||||||||||
2155 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2156 | fd->contentsHeight = frameHeight; | - | ||||||||||||||||||||||||
2157 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2158 | } | - | ||||||||||||||||||||||||
2159 | - | |||||||||||||||||||||||||
2160 | if (isFrameFromInlineObject(f)) {
| 0 | ||||||||||||||||||||||||
2161 | // never reached, handled in resizeInlineObject/positionFloat instead | - | ||||||||||||||||||||||||
2162 | return QRectF(); never executed: return QRectF(); | 0 | ||||||||||||||||||||||||
2163 | } | - | ||||||||||||||||||||||||
2164 | - | |||||||||||||||||||||||||
2165 | if (QTextTable *table = qobject_cast<QTextTable *>(f)) {
| 0 | ||||||||||||||||||||||||
2166 | fd->contentsWidth = newContentsWidth; | - | ||||||||||||||||||||||||
2167 | return layoutTable(table, layoutFrom, layoutTo, parentY); never executed: return layoutTable(table, layoutFrom, layoutTo, parentY); | 0 | ||||||||||||||||||||||||
2168 | } | - | ||||||||||||||||||||||||
2169 | - | |||||||||||||||||||||||||
2170 | // set fd->contentsWidth temporarily, so that layoutFrame for the children | - | ||||||||||||||||||||||||
2171 | // picks the right width. We'll initialize it properly at the end of this | - | ||||||||||||||||||||||||
2172 | // function. | - | ||||||||||||||||||||||||
2173 | fd->contentsWidth = newContentsWidth; | - | ||||||||||||||||||||||||
2174 | - | |||||||||||||||||||||||||
2175 | QTextLayoutStruct layoutStruct; | - | ||||||||||||||||||||||||
2176 | layoutStruct.frame = f; | - | ||||||||||||||||||||||||
2177 | layoutStruct.x_left = fd->leftMargin + fd->border + fd->padding; | - | ||||||||||||||||||||||||
2178 | layoutStruct.x_right = layoutStruct.x_left + newContentsWidth; | - | ||||||||||||||||||||||||
2179 | layoutStruct.y = fd->topMargin + fd->border + fd->padding; | - | ||||||||||||||||||||||||
2180 | layoutStruct.frameY = parentY + fd->position.y; | - | ||||||||||||||||||||||||
2181 | layoutStruct.contentsWidth = 0; | - | ||||||||||||||||||||||||
2182 | layoutStruct.minimumWidth = 0; | - | ||||||||||||||||||||||||
2183 | layoutStruct.maximumWidth = QFIXED_MAX; | - | ||||||||||||||||||||||||
2184 | layoutStruct.fullLayout = fullLayout || (fd->oldContentsWidth != newContentsWidth);
| 0 | ||||||||||||||||||||||||
2185 | layoutStruct.updateRect = QRectF(QPointF(0, 0), QSizeF(qreal(INT_MAX), qreal(INT_MAX))); | - | ||||||||||||||||||||||||
2186 | LDEBUG << "layoutStruct: x_left" << layoutStruct.x_left << "x_right" << layoutStruct.x_right dead code: QMessageLogger(__FILE__, 2186, __PRETTY_FUNCTION__).debug() << "layoutStruct: x_left" << layoutStruct.x_left << "x_right" << layoutStruct.x_right << "fullLayout" << layoutStruct.fullLayout; | - | ||||||||||||||||||||||||
2187 | << "fullLayout" << layoutStruct.fullLayout; dead code: QMessageLogger(__FILE__, 2186, __PRETTY_FUNCTION__).debug() << "layoutStruct: x_left" << layoutStruct.x_left << "x_right" << layoutStruct.x_right << "fullLayout" << layoutStruct.fullLayout; | - | ||||||||||||||||||||||||
2188 | fd->oldContentsWidth = newContentsWidth; | - | ||||||||||||||||||||||||
2189 | - | |||||||||||||||||||||||||
2190 | layoutStruct.pageHeight = QFixed::fromReal(document->pageSize().height()); | - | ||||||||||||||||||||||||
2191 | if (layoutStruct.pageHeight < 0)
| 0 | ||||||||||||||||||||||||
2192 | layoutStruct.pageHeight = QFIXED_MAX; never executed: layoutStruct.pageHeight = (2147483647/256); | 0 | ||||||||||||||||||||||||
2193 | - | |||||||||||||||||||||||||
2194 | const int currentPage = layoutStruct.pageHeight == 0 ? 0 : (layoutStruct.frameY / layoutStruct.pageHeight).truncate();
| 0 | ||||||||||||||||||||||||
2195 | layoutStruct.pageTopMargin = fd->effectiveTopMargin; | - | ||||||||||||||||||||||||
2196 | layoutStruct.pageBottomMargin = fd->effectiveBottomMargin; | - | ||||||||||||||||||||||||
2197 | layoutStruct.pageBottom = (currentPage + 1) * layoutStruct.pageHeight - layoutStruct.pageBottomMargin; | - | ||||||||||||||||||||||||
2198 | - | |||||||||||||||||||||||||
2199 | if (!f->parentFrame())
| 0 | ||||||||||||||||||||||||
2200 | idealWidth = 0; // reset never executed: idealWidth = 0; | 0 | ||||||||||||||||||||||||
2201 | - | |||||||||||||||||||||||||
2202 | QTextFrame::Iterator it = f->begin(); | - | ||||||||||||||||||||||||
2203 | layoutFlow(it, &layoutStruct, layoutFrom, layoutTo); | - | ||||||||||||||||||||||||
2204 | - | |||||||||||||||||||||||||
2205 | QFixed maxChildFrameWidth = 0; | - | ||||||||||||||||||||||||
2206 | QList<QTextFrame *> children = f->childFrames(); | - | ||||||||||||||||||||||||
2207 | for (int i = 0; i < children.size(); ++i) {
| 0 | ||||||||||||||||||||||||
2208 | QTextFrame *c = children.at(i); | - | ||||||||||||||||||||||||
2209 | QTextFrameData *cd = data(c); | - | ||||||||||||||||||||||||
2210 | maxChildFrameWidth = qMax(maxChildFrameWidth, cd->size.width); | - | ||||||||||||||||||||||||
2211 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2212 | - | |||||||||||||||||||||||||
2213 | const QFixed marginWidth = 2*(fd->border + fd->padding) + fd->leftMargin + fd->rightMargin; | - | ||||||||||||||||||||||||
2214 | if (!f->parentFrame()) {
| 0 | ||||||||||||||||||||||||
2215 | idealWidth = qMax(maxChildFrameWidth, layoutStruct.contentsWidth).toReal(); | - | ||||||||||||||||||||||||
2216 | idealWidth += marginWidth.toReal(); | - | ||||||||||||||||||||||||
2217 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2218 | - | |||||||||||||||||||||||||
2219 | QFixed actualWidth = qMax(newContentsWidth, qMax(maxChildFrameWidth, layoutStruct.contentsWidth)); | - | ||||||||||||||||||||||||
2220 | fd->contentsWidth = actualWidth; | - | ||||||||||||||||||||||||
2221 | if (newContentsWidth <= 0) { // nowrap layout?
| 0 | ||||||||||||||||||||||||
2222 | fd->contentsWidth = newContentsWidth; | - | ||||||||||||||||||||||||
2223 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2224 | - | |||||||||||||||||||||||||
2225 | fd->minimumWidth = layoutStruct.minimumWidth; | - | ||||||||||||||||||||||||
2226 | fd->maximumWidth = layoutStruct.maximumWidth; | - | ||||||||||||||||||||||||
2227 | - | |||||||||||||||||||||||||
2228 | fd->size.height = fd->contentsHeight == -1
| 0 | ||||||||||||||||||||||||
2229 | ? layoutStruct.y + fd->border + fd->padding + fd->bottomMargin | - | ||||||||||||||||||||||||
2230 | : fd->contentsHeight + 2*(fd->border + fd->padding) + fd->topMargin + fd->bottomMargin; | - | ||||||||||||||||||||||||
2231 | fd->size.width = actualWidth + marginWidth; | - | ||||||||||||||||||||||||
2232 | fd->sizeDirty = false; | - | ||||||||||||||||||||||||
2233 | if (layoutStruct.updateRectForFloats.isValid())
| 0 | ||||||||||||||||||||||||
2234 | layoutStruct.updateRect |= layoutStruct.updateRectForFloats; never executed: layoutStruct.updateRect |= layoutStruct.updateRectForFloats; | 0 | ||||||||||||||||||||||||
2235 | return layoutStruct.updateRect; never executed: return layoutStruct.updateRect; | 0 | ||||||||||||||||||||||||
2236 | } | - | ||||||||||||||||||||||||
2237 | - | |||||||||||||||||||||||||
2238 | void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QTextLayoutStruct *layoutStruct, | - | ||||||||||||||||||||||||
2239 | int layoutFrom, int layoutTo, QFixed width) | - | ||||||||||||||||||||||||
2240 | { | - | ||||||||||||||||||||||||
2241 | LDEBUG << "layoutFlow from=" << layoutFrom << "to=" << layoutTo; dead code: QMessageLogger(__FILE__, 2241, __PRETTY_FUNCTION__).debug() << "layoutFlow from=" << layoutFrom << "to=" << layoutTo; | - | ||||||||||||||||||||||||
2242 | QTextFrameData *fd = data(layoutStruct->frame); | - | ||||||||||||||||||||||||
2243 | - | |||||||||||||||||||||||||
2244 | fd->currentLayoutStruct = layoutStruct; | - | ||||||||||||||||||||||||
2245 | - | |||||||||||||||||||||||||
2246 | QTextFrame::Iterator previousIt; | - | ||||||||||||||||||||||||
2247 | - | |||||||||||||||||||||||||
2248 | const bool inRootFrame = (it.parentFrame() == document->rootFrame()); | - | ||||||||||||||||||||||||
2249 | if (inRootFrame) {
| 0 | ||||||||||||||||||||||||
2250 | bool redoCheckPoints = layoutStruct->fullLayout || checkPoints.isEmpty();
| 0 | ||||||||||||||||||||||||
2251 | - | |||||||||||||||||||||||||
2252 | if (!redoCheckPoints) {
| 0 | ||||||||||||||||||||||||
2253 | QVector<QCheckPoint>::Iterator checkPoint = std::lower_bound(checkPoints.begin(), checkPoints.end(), layoutFrom); | - | ||||||||||||||||||||||||
2254 | if (checkPoint != checkPoints.end()) {
| 0 | ||||||||||||||||||||||||
2255 | if (checkPoint != checkPoints.begin())
| 0 | ||||||||||||||||||||||||
2256 | --checkPoint; never executed: --checkPoint; | 0 | ||||||||||||||||||||||||
2257 | - | |||||||||||||||||||||||||
2258 | layoutStruct->y = checkPoint->y; | - | ||||||||||||||||||||||||
2259 | layoutStruct->frameY = checkPoint->frameY; | - | ||||||||||||||||||||||||
2260 | layoutStruct->minimumWidth = checkPoint->minimumWidth; | - | ||||||||||||||||||||||||
2261 | layoutStruct->maximumWidth = checkPoint->maximumWidth; | - | ||||||||||||||||||||||||
2262 | layoutStruct->contentsWidth = checkPoint->contentsWidth; | - | ||||||||||||||||||||||||
2263 | - | |||||||||||||||||||||||||
2264 | if (layoutStruct->pageHeight > 0) {
| 0 | ||||||||||||||||||||||||
2265 | int page = layoutStruct->currentPage(); | - | ||||||||||||||||||||||||
2266 | layoutStruct->pageBottom = (page + 1) * layoutStruct->pageHeight - layoutStruct->pageBottomMargin; | - | ||||||||||||||||||||||||
2267 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2268 | - | |||||||||||||||||||||||||
2269 | it = frameIteratorForTextPosition(checkPoint->positionInFrame); | - | ||||||||||||||||||||||||
2270 | checkPoints.resize(checkPoint - checkPoints.begin() + 1); | - | ||||||||||||||||||||||||
2271 | - | |||||||||||||||||||||||||
2272 | if (checkPoint != checkPoints.begin()) {
| 0 | ||||||||||||||||||||||||
2273 | previousIt = it; | - | ||||||||||||||||||||||||
2274 | --previousIt; | - | ||||||||||||||||||||||||
2275 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2276 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2277 | redoCheckPoints = true; | - | ||||||||||||||||||||||||
2278 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2279 | } | - | ||||||||||||||||||||||||
2280 | - | |||||||||||||||||||||||||
2281 | if (redoCheckPoints) {
| 0 | ||||||||||||||||||||||||
2282 | checkPoints.clear(); | - | ||||||||||||||||||||||||
2283 | QCheckPoint cp; | - | ||||||||||||||||||||||||
2284 | cp.y = layoutStruct->y; | - | ||||||||||||||||||||||||
2285 | cp.frameY = layoutStruct->frameY; | - | ||||||||||||||||||||||||
2286 | cp.positionInFrame = 0; | - | ||||||||||||||||||||||||
2287 | cp.minimumWidth = layoutStruct->minimumWidth; | - | ||||||||||||||||||||||||
2288 | cp.maximumWidth = layoutStruct->maximumWidth; | - | ||||||||||||||||||||||||
2289 | cp.contentsWidth = layoutStruct->contentsWidth; | - | ||||||||||||||||||||||||
2290 | checkPoints.append(cp); | - | ||||||||||||||||||||||||
2291 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2292 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2293 | - | |||||||||||||||||||||||||
2294 | QTextBlockFormat previousBlockFormat = previousIt.currentBlock().blockFormat(); | - | ||||||||||||||||||||||||
2295 | - | |||||||||||||||||||||||||
2296 | QFixed maximumBlockWidth = 0; | - | ||||||||||||||||||||||||
2297 | while (!it.atEnd()) {
| 0 | ||||||||||||||||||||||||
2298 | QTextFrame *c = it.currentFrame(); | - | ||||||||||||||||||||||||
2299 | - | |||||||||||||||||||||||||
2300 | int docPos; | - | ||||||||||||||||||||||||
2301 | if (it.currentFrame())
| 0 | ||||||||||||||||||||||||
2302 | docPos = it.currentFrame()->firstPosition(); never executed: docPos = it.currentFrame()->firstPosition(); | 0 | ||||||||||||||||||||||||
2303 | else | - | ||||||||||||||||||||||||
2304 | docPos = it.currentBlock().position(); never executed: docPos = it.currentBlock().position(); | 0 | ||||||||||||||||||||||||
2305 | - | |||||||||||||||||||||||||
2306 | if (inRootFrame) {
| 0 | ||||||||||||||||||||||||
2307 | if (qAbs(layoutStruct->y - checkPoints.constLast().y) > 2000) {
| 0 | ||||||||||||||||||||||||
2308 | QFixed left, right; | - | ||||||||||||||||||||||||
2309 | floatMargins(layoutStruct->y, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2310 | if (left == layoutStruct->x_left && right == layoutStruct->x_right) {
| 0 | ||||||||||||||||||||||||
2311 | QCheckPoint p; | - | ||||||||||||||||||||||||
2312 | p.y = layoutStruct->y; | - | ||||||||||||||||||||||||
2313 | p.frameY = layoutStruct->frameY; | - | ||||||||||||||||||||||||
2314 | p.positionInFrame = docPos; | - | ||||||||||||||||||||||||
2315 | p.minimumWidth = layoutStruct->minimumWidth; | - | ||||||||||||||||||||||||
2316 | p.maximumWidth = layoutStruct->maximumWidth; | - | ||||||||||||||||||||||||
2317 | p.contentsWidth = layoutStruct->contentsWidth; | - | ||||||||||||||||||||||||
2318 | checkPoints.append(p); | - | ||||||||||||||||||||||||
2319 | - | |||||||||||||||||||||||||
2320 | if (currentLazyLayoutPosition != -1
| 0 | ||||||||||||||||||||||||
2321 | && docPos > currentLazyLayoutPosition + lazyLayoutStepSize)
| 0 | ||||||||||||||||||||||||
2322 | break; never executed: break; | 0 | ||||||||||||||||||||||||
2323 | - | |||||||||||||||||||||||||
2324 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2325 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2326 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2327 | - | |||||||||||||||||||||||||
2328 | if (c) {
| 0 | ||||||||||||||||||||||||
2329 | // position child frame | - | ||||||||||||||||||||||||
2330 | QTextFrameData *cd = data(c); | - | ||||||||||||||||||||||||
2331 | - | |||||||||||||||||||||||||
2332 | QTextFrameFormat fformat = c->frameFormat(); | - | ||||||||||||||||||||||||
2333 | - | |||||||||||||||||||||||||
2334 | if (fformat.position() == QTextFrameFormat::InFlow) {
| 0 | ||||||||||||||||||||||||
2335 | if (fformat.pageBreakPolicy() & QTextFormat::PageBreak_AlwaysBefore)
| 0 | ||||||||||||||||||||||||
2336 | layoutStruct->newPage(); never executed: layoutStruct->newPage(); | 0 | ||||||||||||||||||||||||
2337 | - | |||||||||||||||||||||||||
2338 | QFixed left, right; | - | ||||||||||||||||||||||||
2339 | floatMargins(layoutStruct->y, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2340 | left = qMax(left, layoutStruct->x_left); | - | ||||||||||||||||||||||||
2341 | right = qMin(right, layoutStruct->x_right); | - | ||||||||||||||||||||||||
2342 | - | |||||||||||||||||||||||||
2343 | if (right - left < cd->size.width) {
| 0 | ||||||||||||||||||||||||
2344 | layoutStruct->y = findY(layoutStruct->y, layoutStruct, cd->size.width); | - | ||||||||||||||||||||||||
2345 | floatMargins(layoutStruct->y, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2346 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2347 | - | |||||||||||||||||||||||||
2348 | QFixedPoint pos(left, layoutStruct->y); | - | ||||||||||||||||||||||||
2349 | - | |||||||||||||||||||||||||
2350 | Qt::Alignment align = Qt::AlignLeft; | - | ||||||||||||||||||||||||
2351 | - | |||||||||||||||||||||||||
2352 | QTextTable *table = qobject_cast<QTextTable *>(c); | - | ||||||||||||||||||||||||
2353 | - | |||||||||||||||||||||||||
2354 | if (table)
| 0 | ||||||||||||||||||||||||
2355 | align = table->format().alignment() & Qt::AlignHorizontal_Mask; never executed: align = table->format().alignment() & Qt::AlignHorizontal_Mask; | 0 | ||||||||||||||||||||||||
2356 | - | |||||||||||||||||||||||||
2357 | // detect whether we have any alignment in the document that disallows optimizations, | - | ||||||||||||||||||||||||
2358 | // such as not laying out the document again in a textedit with wrapping disabled. | - | ||||||||||||||||||||||||
2359 | if (inRootFrame && !(align & Qt::AlignLeft))
| 0 | ||||||||||||||||||||||||
2360 | contentHasAlignment = true; never executed: contentHasAlignment = true; | 0 | ||||||||||||||||||||||||
2361 | - | |||||||||||||||||||||||||
2362 | cd->position = pos; | - | ||||||||||||||||||||||||
2363 | - | |||||||||||||||||||||||||
2364 | if (document->pageSize().height() > 0.0f)
| 0 | ||||||||||||||||||||||||
2365 | cd->sizeDirty = true; never executed: cd->sizeDirty = true; | 0 | ||||||||||||||||||||||||
2366 | - | |||||||||||||||||||||||||
2367 | if (cd->sizeDirty) {
| 0 | ||||||||||||||||||||||||
2368 | if (width != 0)
| 0 | ||||||||||||||||||||||||
2369 | layoutFrame(c, layoutFrom, layoutTo, width, -1, layoutStruct->frameY); never executed: layoutFrame(c, layoutFrom, layoutTo, width, -1, layoutStruct->frameY); | 0 | ||||||||||||||||||||||||
2370 | else | - | ||||||||||||||||||||||||
2371 | layoutFrame(c, layoutFrom, layoutTo, layoutStruct->frameY); never executed: layoutFrame(c, layoutFrom, layoutTo, layoutStruct->frameY); | 0 | ||||||||||||||||||||||||
2372 | - | |||||||||||||||||||||||||
2373 | QFixed absoluteChildPos = table ? pos.y + static_cast<QTextTableData *>(data(table))->rowPositions.at(0) : pos.y + firstChildPos(c);
| 0 | ||||||||||||||||||||||||
2374 | absoluteChildPos += layoutStruct->frameY; | - | ||||||||||||||||||||||||
2375 | - | |||||||||||||||||||||||||
2376 | // drop entire frame to next page if first child of frame is on next page | - | ||||||||||||||||||||||||
2377 | if (absoluteChildPos > layoutStruct->pageBottom) {
| 0 | ||||||||||||||||||||||||
2378 | layoutStruct->newPage(); | - | ||||||||||||||||||||||||
2379 | pos.y = layoutStruct->y; | - | ||||||||||||||||||||||||
2380 | - | |||||||||||||||||||||||||
2381 | cd->position = pos; | - | ||||||||||||||||||||||||
2382 | cd->sizeDirty = true; | - | ||||||||||||||||||||||||
2383 | - | |||||||||||||||||||||||||
2384 | if (width != 0)
| 0 | ||||||||||||||||||||||||
2385 | layoutFrame(c, layoutFrom, layoutTo, width, -1, layoutStruct->frameY); never executed: layoutFrame(c, layoutFrom, layoutTo, width, -1, layoutStruct->frameY); | 0 | ||||||||||||||||||||||||
2386 | else | - | ||||||||||||||||||||||||
2387 | layoutFrame(c, layoutFrom, layoutTo, layoutStruct->frameY); never executed: layoutFrame(c, layoutFrom, layoutTo, layoutStruct->frameY); | 0 | ||||||||||||||||||||||||
2388 | } | - | ||||||||||||||||||||||||
2389 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2390 | - | |||||||||||||||||||||||||
2391 | // align only if there is space for alignment | - | ||||||||||||||||||||||||
2392 | if (right - left > cd->size.width) {
| 0 | ||||||||||||||||||||||||
2393 | if (align & Qt::AlignRight)
| 0 | ||||||||||||||||||||||||
2394 | pos.x += layoutStruct->x_right - cd->size.width; never executed: pos.x += layoutStruct->x_right - cd->size.width; | 0 | ||||||||||||||||||||||||
2395 | else if (align & Qt::AlignHCenter)
| 0 | ||||||||||||||||||||||||
2396 | pos.x += (layoutStruct->x_right - cd->size.width) / 2; never executed: pos.x += (layoutStruct->x_right - cd->size.width) / 2; | 0 | ||||||||||||||||||||||||
2397 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2398 | - | |||||||||||||||||||||||||
2399 | cd->position = pos; | - | ||||||||||||||||||||||||
2400 | - | |||||||||||||||||||||||||
2401 | layoutStruct->y += cd->size.height; | - | ||||||||||||||||||||||||
2402 | const int page = layoutStruct->currentPage(); | - | ||||||||||||||||||||||||
2403 | layoutStruct->pageBottom = (page + 1) * layoutStruct->pageHeight - layoutStruct->pageBottomMargin; | - | ||||||||||||||||||||||||
2404 | - | |||||||||||||||||||||||||
2405 | cd->layoutDirty = false; | - | ||||||||||||||||||||||||
2406 | - | |||||||||||||||||||||||||
2407 | if (c->frameFormat().pageBreakPolicy() & QTextFormat::PageBreak_AlwaysAfter)
| 0 | ||||||||||||||||||||||||
2408 | layoutStruct->newPage(); never executed: layoutStruct->newPage(); | 0 | ||||||||||||||||||||||||
2409 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2410 | QRectF oldFrameRect(cd->position.toPointF(), cd->size.toSizeF()); | - | ||||||||||||||||||||||||
2411 | QRectF updateRect; | - | ||||||||||||||||||||||||
2412 | - | |||||||||||||||||||||||||
2413 | if (cd->sizeDirty)
| 0 | ||||||||||||||||||||||||
2414 | updateRect = layoutFrame(c, layoutFrom, layoutTo); never executed: updateRect = layoutFrame(c, layoutFrom, layoutTo); | 0 | ||||||||||||||||||||||||
2415 | - | |||||||||||||||||||||||||
2416 | positionFloat(c); | - | ||||||||||||||||||||||||
2417 | - | |||||||||||||||||||||||||
2418 | // If the size was made dirty when the position was set, layout again | - | ||||||||||||||||||||||||
2419 | if (cd->sizeDirty)
| 0 | ||||||||||||||||||||||||
2420 | updateRect = layoutFrame(c, layoutFrom, layoutTo); never executed: updateRect = layoutFrame(c, layoutFrom, layoutTo); | 0 | ||||||||||||||||||||||||
2421 | - | |||||||||||||||||||||||||
2422 | QRectF frameRect(cd->position.toPointF(), cd->size.toSizeF()); | - | ||||||||||||||||||||||||
2423 | - | |||||||||||||||||||||||||
2424 | if (frameRect == oldFrameRect && updateRect.isValid())
| 0 | ||||||||||||||||||||||||
2425 | updateRect.translate(cd->position.toPointF()); never executed: updateRect.translate(cd->position.toPointF()); | 0 | ||||||||||||||||||||||||
2426 | else | - | ||||||||||||||||||||||||
2427 | updateRect = frameRect; never executed: updateRect = frameRect; | 0 | ||||||||||||||||||||||||
2428 | - | |||||||||||||||||||||||||
2429 | layoutStruct->addUpdateRectForFloat(updateRect); | - | ||||||||||||||||||||||||
2430 | if (oldFrameRect.isValid())
| 0 | ||||||||||||||||||||||||
2431 | layoutStruct->addUpdateRectForFloat(oldFrameRect); never executed: layoutStruct->addUpdateRectForFloat(oldFrameRect); | 0 | ||||||||||||||||||||||||
2432 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2433 | - | |||||||||||||||||||||||||
2434 | layoutStruct->minimumWidth = qMax(layoutStruct->minimumWidth, cd->minimumWidth); | - | ||||||||||||||||||||||||
2435 | layoutStruct->maximumWidth = qMin(layoutStruct->maximumWidth, cd->maximumWidth); | - | ||||||||||||||||||||||||
2436 | - | |||||||||||||||||||||||||
2437 | previousIt = it; | - | ||||||||||||||||||||||||
2438 | ++it; | - | ||||||||||||||||||||||||
2439 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2440 | QTextFrame::Iterator lastIt; | - | ||||||||||||||||||||||||
2441 | if (!previousIt.atEnd() && previousIt != it)
| 0 | ||||||||||||||||||||||||
2442 | lastIt = previousIt; never executed: lastIt = previousIt; | 0 | ||||||||||||||||||||||||
2443 | previousIt = it; | - | ||||||||||||||||||||||||
2444 | QTextBlock block = it.currentBlock(); | - | ||||||||||||||||||||||||
2445 | ++it; | - | ||||||||||||||||||||||||
2446 | - | |||||||||||||||||||||||||
2447 | const QTextBlockFormat blockFormat = block.blockFormat(); | - | ||||||||||||||||||||||||
2448 | - | |||||||||||||||||||||||||
2449 | if (blockFormat.pageBreakPolicy() & QTextFormat::PageBreak_AlwaysBefore)
| 0 | ||||||||||||||||||||||||
2450 | layoutStruct->newPage(); never executed: layoutStruct->newPage(); | 0 | ||||||||||||||||||||||||
2451 | - | |||||||||||||||||||||||||
2452 | const QFixed origY = layoutStruct->y; | - | ||||||||||||||||||||||||
2453 | const QFixed origPageBottom = layoutStruct->pageBottom; | - | ||||||||||||||||||||||||
2454 | const QFixed origMaximumWidth = layoutStruct->maximumWidth; | - | ||||||||||||||||||||||||
2455 | layoutStruct->maximumWidth = 0; | - | ||||||||||||||||||||||||
2456 | - | |||||||||||||||||||||||||
2457 | const QTextBlockFormat *previousBlockFormatPtr = 0; | - | ||||||||||||||||||||||||
2458 | if (lastIt.currentBlock().isValid())
| 0 | ||||||||||||||||||||||||
2459 | previousBlockFormatPtr = &previousBlockFormat; never executed: previousBlockFormatPtr = &previousBlockFormat; | 0 | ||||||||||||||||||||||||
2460 | - | |||||||||||||||||||||||||
2461 | // layout and position child block | - | ||||||||||||||||||||||||
2462 | layoutBlock(block, docPos, blockFormat, layoutStruct, layoutFrom, layoutTo, previousBlockFormatPtr); | - | ||||||||||||||||||||||||
2463 | - | |||||||||||||||||||||||||
2464 | // detect whether we have any alignment in the document that disallows optimizations, | - | ||||||||||||||||||||||||
2465 | // such as not laying out the document again in a textedit with wrapping disabled. | - | ||||||||||||||||||||||||
2466 | if (inRootFrame && !(block.layout()->textOption().alignment() & Qt::AlignLeft))
| 0 | ||||||||||||||||||||||||
2467 | contentHasAlignment = true; never executed: contentHasAlignment = true; | 0 | ||||||||||||||||||||||||
2468 | - | |||||||||||||||||||||||||
2469 | // if the block right before a table is empty 'hide' it by | - | ||||||||||||||||||||||||
2470 | // positioning it into the table border | - | ||||||||||||||||||||||||
2471 | if (isEmptyBlockBeforeTable(block, blockFormat, it)) {
| 0 | ||||||||||||||||||||||||
2472 | const QTextBlock lastBlock = lastIt.currentBlock(); | - | ||||||||||||||||||||||||
2473 | const qreal lastBlockBottomMargin = lastBlock.isValid() ? lastBlock.blockFormat().bottomMargin() : 0.0f;
| 0 | ||||||||||||||||||||||||
2474 | layoutStruct->y = origY + QFixed::fromReal(qMax(lastBlockBottomMargin, block.blockFormat().topMargin())); | - | ||||||||||||||||||||||||
2475 | layoutStruct->pageBottom = origPageBottom; | - | ||||||||||||||||||||||||
2476 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2477 | // if the block right after a table is empty then 'hide' it, too | - | ||||||||||||||||||||||||
2478 | if (isEmptyBlockAfterTable(block, lastIt.currentFrame())) {
| 0 | ||||||||||||||||||||||||
2479 | QTextTableData *td = static_cast<QTextTableData *>(data(lastIt.currentFrame())); | - | ||||||||||||||||||||||||
2480 | QTextLayout *layout = block.layout(); | - | ||||||||||||||||||||||||
2481 | - | |||||||||||||||||||||||||
2482 | QPointF pos((td->position.x + td->size.width).toReal(), | - | ||||||||||||||||||||||||
2483 | (td->position.y + td->size.height).toReal() - layout->boundingRect().height()); | - | ||||||||||||||||||||||||
2484 | - | |||||||||||||||||||||||||
2485 | layout->setPosition(pos); | - | ||||||||||||||||||||||||
2486 | layoutStruct->y = origY; | - | ||||||||||||||||||||||||
2487 | layoutStruct->pageBottom = origPageBottom; | - | ||||||||||||||||||||||||
2488 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2489 | - | |||||||||||||||||||||||||
2490 | // if the block right after a table starts with a line separator, shift it up by one line | - | ||||||||||||||||||||||||
2491 | if (isLineSeparatorBlockAfterTable(block, lastIt.currentFrame())) {
| 0 | ||||||||||||||||||||||||
2492 | QTextTableData *td = static_cast<QTextTableData *>(data(lastIt.currentFrame())); | - | ||||||||||||||||||||||||
2493 | QTextLayout *layout = block.layout(); | - | ||||||||||||||||||||||||
2494 | - | |||||||||||||||||||||||||
2495 | QFixed height = QFixed::fromReal(layout->lineAt(0).height()); | - | ||||||||||||||||||||||||
2496 | - | |||||||||||||||||||||||||
2497 | if (layoutStruct->pageBottom == origPageBottom) {
| 0 | ||||||||||||||||||||||||
2498 | layoutStruct->y -= height; | - | ||||||||||||||||||||||||
2499 | layout->setPosition(layout->position() - QPointF(0, height.toReal())); | - | ||||||||||||||||||||||||
2500 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2501 | // relayout block to correctly handle page breaks | - | ||||||||||||||||||||||||
2502 | layoutStruct->y = origY - height; | - | ||||||||||||||||||||||||
2503 | layoutStruct->pageBottom = origPageBottom; | - | ||||||||||||||||||||||||
2504 | layoutBlock(block, docPos, blockFormat, layoutStruct, layoutFrom, layoutTo, previousBlockFormatPtr); | - | ||||||||||||||||||||||||
2505 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2506 | - | |||||||||||||||||||||||||
2507 | QPointF linePos((td->position.x + td->size.width).toReal(), | - | ||||||||||||||||||||||||
2508 | (td->position.y + td->size.height - height).toReal()); | - | ||||||||||||||||||||||||
2509 | - | |||||||||||||||||||||||||
2510 | layout->lineAt(0).setPosition(linePos - layout->position()); | - | ||||||||||||||||||||||||
2511 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2512 | - | |||||||||||||||||||||||||
2513 | if (blockFormat.pageBreakPolicy() & QTextFormat::PageBreak_AlwaysAfter)
| 0 | ||||||||||||||||||||||||
2514 | layoutStruct->newPage(); never executed: layoutStruct->newPage(); | 0 | ||||||||||||||||||||||||
2515 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2516 | - | |||||||||||||||||||||||||
2517 | maximumBlockWidth = qMax(maximumBlockWidth, layoutStruct->maximumWidth); | - | ||||||||||||||||||||||||
2518 | layoutStruct->maximumWidth = origMaximumWidth; | - | ||||||||||||||||||||||||
2519 | previousBlockFormat = blockFormat; | - | ||||||||||||||||||||||||
2520 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2521 | } | - | ||||||||||||||||||||||||
2522 | if (layoutStruct->maximumWidth == QFIXED_MAX && maximumBlockWidth > 0)
| 0 | ||||||||||||||||||||||||
2523 | layoutStruct->maximumWidth = maximumBlockWidth; never executed: layoutStruct->maximumWidth = maximumBlockWidth; | 0 | ||||||||||||||||||||||||
2524 | else | - | ||||||||||||||||||||||||
2525 | layoutStruct->maximumWidth = qMax(layoutStruct->maximumWidth, maximumBlockWidth); never executed: layoutStruct->maximumWidth = qMax(layoutStruct->maximumWidth, maximumBlockWidth); | 0 | ||||||||||||||||||||||||
2526 | - | |||||||||||||||||||||||||
2527 | // a float at the bottom of a frame may make it taller, hence the qMax() for layoutStruct->y. | - | ||||||||||||||||||||||||
2528 | // we don't need to do it for tables though because floats in tables are per table | - | ||||||||||||||||||||||||
2529 | // and not per cell and layoutCell already takes care of doing the same as we do here | - | ||||||||||||||||||||||||
2530 | if (!qobject_cast<QTextTable *>(layoutStruct->frame)) {
| 0 | ||||||||||||||||||||||||
2531 | QList<QTextFrame *> children = layoutStruct->frame->childFrames(); | - | ||||||||||||||||||||||||
2532 | for (int i = 0; i < children.count(); ++i) {
| 0 | ||||||||||||||||||||||||
2533 | QTextFrameData *fd = data(children.at(i)); | - | ||||||||||||||||||||||||
2534 | if (!fd->layoutDirty && children.at(i)->frameFormat().position() != QTextFrameFormat::InFlow)
| 0 | ||||||||||||||||||||||||
2535 | layoutStruct->y = qMax(layoutStruct->y, fd->position.y + fd->size.height); never executed: layoutStruct->y = qMax(layoutStruct->y, fd->position.y + fd->size.height); | 0 | ||||||||||||||||||||||||
2536 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2537 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2538 | - | |||||||||||||||||||||||||
2539 | if (inRootFrame) {
| 0 | ||||||||||||||||||||||||
2540 | // we assume that any float is aligned in a way that disallows the optimizations that rely | - | ||||||||||||||||||||||||
2541 | // on unaligned content. | - | ||||||||||||||||||||||||
2542 | if (!fd->floats.isEmpty())
| 0 | ||||||||||||||||||||||||
2543 | contentHasAlignment = true; never executed: contentHasAlignment = true; | 0 | ||||||||||||||||||||||||
2544 | - | |||||||||||||||||||||||||
2545 | if (it.atEnd()) {
| 0 | ||||||||||||||||||||||||
2546 | //qDebug("layout done!"); | - | ||||||||||||||||||||||||
2547 | currentLazyLayoutPosition = -1; | - | ||||||||||||||||||||||||
2548 | QCheckPoint cp; | - | ||||||||||||||||||||||||
2549 | cp.y = layoutStruct->y; | - | ||||||||||||||||||||||||
2550 | cp.positionInFrame = docPrivate->length(); | - | ||||||||||||||||||||||||
2551 | cp.minimumWidth = layoutStruct->minimumWidth; | - | ||||||||||||||||||||||||
2552 | cp.maximumWidth = layoutStruct->maximumWidth; | - | ||||||||||||||||||||||||
2553 | cp.contentsWidth = layoutStruct->contentsWidth; | - | ||||||||||||||||||||||||
2554 | checkPoints.append(cp); | - | ||||||||||||||||||||||||
2555 | checkPoints.reserve(checkPoints.size()); | - | ||||||||||||||||||||||||
2556 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2557 | currentLazyLayoutPosition = checkPoints.constLast().positionInFrame; | - | ||||||||||||||||||||||||
2558 | // ####### | - | ||||||||||||||||||||||||
2559 | //checkPoints.last().positionInFrame = q->document()->docHandle()->length(); | - | ||||||||||||||||||||||||
2560 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2561 | } | - | ||||||||||||||||||||||||
2562 | - | |||||||||||||||||||||||||
2563 | - | |||||||||||||||||||||||||
2564 | fd->currentLayoutStruct = 0; | - | ||||||||||||||||||||||||
2565 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2566 | - | |||||||||||||||||||||||||
2567 | static inline void getLineHeightParams(const QTextBlockFormat &blockFormat, const QTextLine &line, qreal scaling, | - | ||||||||||||||||||||||||
2568 | QFixed *lineAdjustment, QFixed *lineBreakHeight, QFixed *lineHeight) | - | ||||||||||||||||||||||||
2569 | { | - | ||||||||||||||||||||||||
2570 | *lineHeight = QFixed::fromReal(blockFormat.lineHeight(line.height(), scaling)); | - | ||||||||||||||||||||||||
2571 | - | |||||||||||||||||||||||||
2572 | if (blockFormat.lineHeightType() == QTextBlockFormat::FixedHeight || blockFormat.lineHeightType() == QTextBlockFormat::MinimumHeight) {
| 0 | ||||||||||||||||||||||||
2573 | *lineBreakHeight = *lineHeight; | - | ||||||||||||||||||||||||
2574 | if (blockFormat.lineHeightType() == QTextBlockFormat::FixedHeight)
| 0 | ||||||||||||||||||||||||
2575 | *lineAdjustment = QFixed::fromReal(line.ascent() + qMax(line.leading(), qreal(0.0))) - ((*lineHeight * 4) / 5); never executed: *lineAdjustment = QFixed::fromReal(line.ascent() + qMax(line.leading(), qreal(0.0))) - ((*lineHeight * 4) / 5); | 0 | ||||||||||||||||||||||||
2576 | else | - | ||||||||||||||||||||||||
2577 | *lineAdjustment = QFixed::fromReal(line.height()) - *lineHeight; never executed: *lineAdjustment = QFixed::fromReal(line.height()) - *lineHeight; | 0 | ||||||||||||||||||||||||
2578 | } | - | ||||||||||||||||||||||||
2579 | else { | - | ||||||||||||||||||||||||
2580 | *lineBreakHeight = QFixed::fromReal(line.height()); | - | ||||||||||||||||||||||||
2581 | *lineAdjustment = 0; | - | ||||||||||||||||||||||||
2582 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2583 | } | - | ||||||||||||||||||||||||
2584 | - | |||||||||||||||||||||||||
2585 | void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosition, const QTextBlockFormat &blockFormat, | - | ||||||||||||||||||||||||
2586 | QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, const QTextBlockFormat *previousBlockFormat) | - | ||||||||||||||||||||||||
2587 | { | - | ||||||||||||||||||||||||
2588 | Q_Q(QTextDocumentLayout); | - | ||||||||||||||||||||||||
2589 | if (!bl.isVisible())
| 0 | ||||||||||||||||||||||||
2590 | return; never executed: return; | 0 | ||||||||||||||||||||||||
2591 | - | |||||||||||||||||||||||||
2592 | QTextLayout *tl = bl.layout(); | - | ||||||||||||||||||||||||
2593 | const int blockLength = bl.length(); | - | ||||||||||||||||||||||||
2594 | - | |||||||||||||||||||||||||
2595 | LDEBUG << "layoutBlock from=" << layoutFrom << "to=" << layoutTo; dead code: QMessageLogger(__FILE__, 2595, __PRETTY_FUNCTION__).debug() << "layoutBlock from=" << layoutFrom << "to=" << layoutTo; | - | ||||||||||||||||||||||||
2596 | - | |||||||||||||||||||||||||
2597 | // qDebug() << "layoutBlock; width" << layoutStruct->x_right - layoutStruct->x_left << "(maxWidth is btw" << tl->maximumWidth() << ')'; | - | ||||||||||||||||||||||||
2598 | - | |||||||||||||||||||||||||
2599 | if (previousBlockFormat) {
| 0 | ||||||||||||||||||||||||
2600 | qreal margin = qMax(blockFormat.topMargin(), previousBlockFormat->bottomMargin()); | - | ||||||||||||||||||||||||
2601 | if (margin > 0 && q->paintDevice()) {
| 0 | ||||||||||||||||||||||||
2602 | margin *= qreal(q->paintDevice()->logicalDpiY()) / qreal(qt_defaultDpi()); | - | ||||||||||||||||||||||||
2603 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2604 | layoutStruct->y += QFixed::fromReal(margin); | - | ||||||||||||||||||||||||
2605 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2606 | - | |||||||||||||||||||||||||
2607 | //QTextFrameData *fd = data(layoutStruct->frame); | - | ||||||||||||||||||||||||
2608 | - | |||||||||||||||||||||||||
2609 | Qt::LayoutDirection dir = bl.textDirection(); | - | ||||||||||||||||||||||||
2610 | - | |||||||||||||||||||||||||
2611 | QFixed extraMargin; | - | ||||||||||||||||||||||||
2612 | if (docPrivate->defaultTextOption.flags() & QTextOption::AddSpaceForLineAndParagraphSeparators) {
| 0 | ||||||||||||||||||||||||
2613 | QFontMetricsF fm(bl.charFormat().font()); | - | ||||||||||||||||||||||||
2614 | extraMargin = QFixed::fromReal(fm.width(QChar(QChar(0x21B5)))); | - | ||||||||||||||||||||||||
2615 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2616 | - | |||||||||||||||||||||||||
2617 | const QFixed indent = this->blockIndent(blockFormat); | - | ||||||||||||||||||||||||
2618 | const QFixed totalLeftMargin = QFixed::fromReal(blockFormat.leftMargin()) + (dir == Qt::RightToLeft ? extraMargin : indent);
| 0 | ||||||||||||||||||||||||
2619 | const QFixed totalRightMargin = QFixed::fromReal(blockFormat.rightMargin()) + (dir == Qt::RightToLeft ? indent : extraMargin);
| 0 | ||||||||||||||||||||||||
2620 | - | |||||||||||||||||||||||||
2621 | const QPointF oldPosition = tl->position(); | - | ||||||||||||||||||||||||
2622 | tl->setPosition(QPointF(layoutStruct->x_left.toReal(), layoutStruct->y.toReal())); | - | ||||||||||||||||||||||||
2623 | - | |||||||||||||||||||||||||
2624 | if (layoutStruct->fullLayout
| 0 | ||||||||||||||||||||||||
2625 | || (blockPosition + blockLength > layoutFrom && blockPosition <= layoutTo)
| 0 | ||||||||||||||||||||||||
2626 | // force relayout if we cross a page boundary | - | ||||||||||||||||||||||||
2627 | || (layoutStruct->pageHeight != QFIXED_MAX && layoutStruct->absoluteY() + QFixed::fromReal(tl->boundingRect().height()) > layoutStruct->pageBottom)) {
| 0 | ||||||||||||||||||||||||
2628 | - | |||||||||||||||||||||||||
2629 | LDEBUG << " do layout"; dead code: QMessageLogger(__FILE__, 2629, __PRETTY_FUNCTION__).debug() << " do layout"; | - | ||||||||||||||||||||||||
2630 | QTextOption option = docPrivate->defaultTextOption; | - | ||||||||||||||||||||||||
2631 | option.setTextDirection(dir); | - | ||||||||||||||||||||||||
2632 | option.setTabs( blockFormat.tabPositions() ); | - | ||||||||||||||||||||||||
2633 | - | |||||||||||||||||||||||||
2634 | Qt::Alignment align = docPrivate->defaultTextOption.alignment(); | - | ||||||||||||||||||||||||
2635 | if (blockFormat.hasProperty(QTextFormat::BlockAlignment))
| 0 | ||||||||||||||||||||||||
2636 | align = blockFormat.alignment(); never executed: align = blockFormat.alignment(); | 0 | ||||||||||||||||||||||||
2637 | option.setAlignment(QGuiApplicationPrivate::visualAlignment(dir, align)); // for paragraph that are RTL, alignment is auto-reversed; | - | ||||||||||||||||||||||||
2638 | - | |||||||||||||||||||||||||
2639 | if (blockFormat.nonBreakableLines() || document->pageSize().width() < 0) {
| 0 | ||||||||||||||||||||||||
2640 | option.setWrapMode(QTextOption::ManualWrap); | - | ||||||||||||||||||||||||
2641 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2642 | - | |||||||||||||||||||||||||
2643 | tl->setTextOption(option); | - | ||||||||||||||||||||||||
2644 | - | |||||||||||||||||||||||||
2645 | const bool haveWordOrAnyWrapMode = (option.wrapMode() == QTextOption::WrapAtWordBoundaryOrAnywhere); | - | ||||||||||||||||||||||||
2646 | - | |||||||||||||||||||||||||
2647 | // qDebug() << " layouting block at" << bl.position(); | - | ||||||||||||||||||||||||
2648 | const QFixed cy = layoutStruct->y; | - | ||||||||||||||||||||||||
2649 | const QFixed l = layoutStruct->x_left + totalLeftMargin; | - | ||||||||||||||||||||||||
2650 | const QFixed r = layoutStruct->x_right - totalRightMargin; | - | ||||||||||||||||||||||||
2651 | - | |||||||||||||||||||||||||
2652 | tl->beginLayout(); | - | ||||||||||||||||||||||||
2653 | bool firstLine = true; | - | ||||||||||||||||||||||||
2654 | while (1) { | - | ||||||||||||||||||||||||
2655 | QTextLine line = tl->createLine(); | - | ||||||||||||||||||||||||
2656 | if (!line.isValid())
| 0 | ||||||||||||||||||||||||
2657 | break; never executed: break; | 0 | ||||||||||||||||||||||||
2658 | line.setLeadingIncluded(true); | - | ||||||||||||||||||||||||
2659 | - | |||||||||||||||||||||||||
2660 | QFixed left, right; | - | ||||||||||||||||||||||||
2661 | floatMargins(layoutStruct->y, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2662 | left = qMax(left, l); | - | ||||||||||||||||||||||||
2663 | right = qMin(right, r); | - | ||||||||||||||||||||||||
2664 | QFixed text_indent; | - | ||||||||||||||||||||||||
2665 | if (firstLine) {
| 0 | ||||||||||||||||||||||||
2666 | text_indent = QFixed::fromReal(blockFormat.textIndent()); | - | ||||||||||||||||||||||||
2667 | if (dir == Qt::LeftToRight)
| 0 | ||||||||||||||||||||||||
2668 | left += text_indent; never executed: left += text_indent; | 0 | ||||||||||||||||||||||||
2669 | else | - | ||||||||||||||||||||||||
2670 | right -= text_indent; never executed: right -= text_indent; | 0 | ||||||||||||||||||||||||
2671 | firstLine = false; | - | ||||||||||||||||||||||||
2672 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2673 | // qDebug() << "layout line y=" << currentYPos << "left=" << left << "right=" <<right; | - | ||||||||||||||||||||||||
2674 | - | |||||||||||||||||||||||||
2675 | if (fixedColumnWidth != -1)
| 0 | ||||||||||||||||||||||||
2676 | line.setNumColumns(fixedColumnWidth, (right - left).toReal()); never executed: line.setNumColumns(fixedColumnWidth, (right - left).toReal()); | 0 | ||||||||||||||||||||||||
2677 | else | - | ||||||||||||||||||||||||
2678 | line.setLineWidth((right - left).toReal()); never executed: line.setLineWidth((right - left).toReal()); | 0 | ||||||||||||||||||||||||
2679 | - | |||||||||||||||||||||||||
2680 | // qDebug() << "layoutBlock; layouting line with width" << right - left << "->textWidth" << line.textWidth(); | - | ||||||||||||||||||||||||
2681 | floatMargins(layoutStruct->y, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2682 | left = qMax(left, l); | - | ||||||||||||||||||||||||
2683 | right = qMin(right, r); | - | ||||||||||||||||||||||||
2684 | if (dir == Qt::LeftToRight)
| 0 | ||||||||||||||||||||||||
2685 | left += text_indent; never executed: left += text_indent; | 0 | ||||||||||||||||||||||||
2686 | else | - | ||||||||||||||||||||||||
2687 | right -= text_indent; never executed: right -= text_indent; | 0 | ||||||||||||||||||||||||
2688 | - | |||||||||||||||||||||||||
2689 | if (fixedColumnWidth == -1 && QFixed::fromReal(line.naturalTextWidth()) > right-left) {
| 0 | ||||||||||||||||||||||||
2690 | // float has been added in the meantime, redo | - | ||||||||||||||||||||||||
2691 | layoutStruct->pendingFloats.clear(); | - | ||||||||||||||||||||||||
2692 | - | |||||||||||||||||||||||||
2693 | line.setLineWidth((right-left).toReal()); | - | ||||||||||||||||||||||||
2694 | if (QFixed::fromReal(line.naturalTextWidth()) > right-left) {
| 0 | ||||||||||||||||||||||||
2695 | if (haveWordOrAnyWrapMode) {
| 0 | ||||||||||||||||||||||||
2696 | option.setWrapMode(QTextOption::WrapAnywhere); | - | ||||||||||||||||||||||||
2697 | tl->setTextOption(option); | - | ||||||||||||||||||||||||
2698 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2699 | - | |||||||||||||||||||||||||
2700 | layoutStruct->pendingFloats.clear(); | - | ||||||||||||||||||||||||
2701 | // lines min width more than what we have | - | ||||||||||||||||||||||||
2702 | layoutStruct->y = findY(layoutStruct->y, layoutStruct, QFixed::fromReal(line.naturalTextWidth())); | - | ||||||||||||||||||||||||
2703 | floatMargins(layoutStruct->y, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2704 | left = qMax(left, l); | - | ||||||||||||||||||||||||
2705 | right = qMin(right, r); | - | ||||||||||||||||||||||||
2706 | if (dir == Qt::LeftToRight)
| 0 | ||||||||||||||||||||||||
2707 | left += text_indent; never executed: left += text_indent; | 0 | ||||||||||||||||||||||||
2708 | else | - | ||||||||||||||||||||||||
2709 | right -= text_indent; never executed: right -= text_indent; | 0 | ||||||||||||||||||||||||
2710 | line.setLineWidth(qMax<qreal>(line.naturalTextWidth(), (right-left).toReal())); | - | ||||||||||||||||||||||||
2711 | - | |||||||||||||||||||||||||
2712 | if (haveWordOrAnyWrapMode) {
| 0 | ||||||||||||||||||||||||
2713 | option.setWrapMode(QTextOption::WordWrap); | - | ||||||||||||||||||||||||
2714 | tl->setTextOption(option); | - | ||||||||||||||||||||||||
2715 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2716 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2717 | - | |||||||||||||||||||||||||
2718 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2719 | - | |||||||||||||||||||||||||
2720 | QFixed lineBreakHeight, lineHeight, lineAdjustment; | - | ||||||||||||||||||||||||
2721 | qreal scaling = (q->paintDevice() && q->paintDevice()->logicalDpiY() != qt_defaultDpi()) ?
| 0 | ||||||||||||||||||||||||
2722 | qreal(q->paintDevice()->logicalDpiY()) / qreal(qt_defaultDpi()) : 1; | - | ||||||||||||||||||||||||
2723 | getLineHeightParams(blockFormat, line, scaling, &lineAdjustment, &lineBreakHeight, &lineHeight); | - | ||||||||||||||||||||||||
2724 | - | |||||||||||||||||||||||||
2725 | if (layoutStruct->pageHeight > 0 && layoutStruct->absoluteY() + lineBreakHeight > layoutStruct->pageBottom) {
| 0 | ||||||||||||||||||||||||
2726 | layoutStruct->newPage(); | - | ||||||||||||||||||||||||
2727 | - | |||||||||||||||||||||||||
2728 | floatMargins(layoutStruct->y, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2729 | left = qMax(left, l); | - | ||||||||||||||||||||||||
2730 | right = qMin(right, r); | - | ||||||||||||||||||||||||
2731 | if (dir == Qt::LeftToRight)
| 0 | ||||||||||||||||||||||||
2732 | left += text_indent; never executed: left += text_indent; | 0 | ||||||||||||||||||||||||
2733 | else | - | ||||||||||||||||||||||||
2734 | right -= text_indent; never executed: right -= text_indent; | 0 | ||||||||||||||||||||||||
2735 | } | - | ||||||||||||||||||||||||
2736 | - | |||||||||||||||||||||||||
2737 | line.setPosition(QPointF((left - layoutStruct->x_left).toReal(), (layoutStruct->y - cy - lineAdjustment).toReal())); | - | ||||||||||||||||||||||||
2738 | layoutStruct->y += lineHeight; | - | ||||||||||||||||||||||||
2739 | layoutStruct->contentsWidth | - | ||||||||||||||||||||||||
2740 | = qMax<QFixed>(layoutStruct->contentsWidth, QFixed::fromReal(line.x() + line.naturalTextWidth()) + totalRightMargin); | - | ||||||||||||||||||||||||
2741 | - | |||||||||||||||||||||||||
2742 | // position floats | - | ||||||||||||||||||||||||
2743 | for (int i = 0; i < layoutStruct->pendingFloats.size(); ++i) {
| 0 | ||||||||||||||||||||||||
2744 | QTextFrame *f = layoutStruct->pendingFloats.at(i); | - | ||||||||||||||||||||||||
2745 | positionFloat(f); | - | ||||||||||||||||||||||||
2746 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2747 | layoutStruct->pendingFloats.clear(); | - | ||||||||||||||||||||||||
2748 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2749 | tl->endLayout(); | - | ||||||||||||||||||||||||
2750 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2751 | const int cnt = tl->lineCount(); | - | ||||||||||||||||||||||||
2752 | for (int i = 0; i < cnt; ++i) {
| 0 | ||||||||||||||||||||||||
2753 | LDEBUG << "going to move text line" << i; dead code: QMessageLogger(__FILE__, 2753, __PRETTY_FUNCTION__).debug() << "going to move text line" << i; | - | ||||||||||||||||||||||||
2754 | QTextLine line = tl->lineAt(i); | - | ||||||||||||||||||||||||
2755 | layoutStruct->contentsWidth | - | ||||||||||||||||||||||||
2756 | = qMax(layoutStruct->contentsWidth, QFixed::fromReal(line.x() + tl->lineAt(i).naturalTextWidth()) + totalRightMargin); | - | ||||||||||||||||||||||||
2757 | - | |||||||||||||||||||||||||
2758 | QFixed lineBreakHeight, lineHeight, lineAdjustment; | - | ||||||||||||||||||||||||
2759 | qreal scaling = (q->paintDevice() && q->paintDevice()->logicalDpiY() != qt_defaultDpi()) ?
| 0 | ||||||||||||||||||||||||
2760 | qreal(q->paintDevice()->logicalDpiY()) / qreal(qt_defaultDpi()) : 1; | - | ||||||||||||||||||||||||
2761 | getLineHeightParams(blockFormat, line, scaling, &lineAdjustment, &lineBreakHeight, &lineHeight); | - | ||||||||||||||||||||||||
2762 | - | |||||||||||||||||||||||||
2763 | if (layoutStruct->pageHeight != QFIXED_MAX) {
| 0 | ||||||||||||||||||||||||
2764 | if (layoutStruct->absoluteY() + lineBreakHeight > layoutStruct->pageBottom)
| 0 | ||||||||||||||||||||||||
2765 | layoutStruct->newPage(); never executed: layoutStruct->newPage(); | 0 | ||||||||||||||||||||||||
2766 | line.setPosition(QPointF(line.position().x(), (layoutStruct->y - lineAdjustment).toReal() - tl->position().y())); | - | ||||||||||||||||||||||||
2767 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2768 | layoutStruct->y += lineHeight; | - | ||||||||||||||||||||||||
2769 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2770 | if (layoutStruct->updateRect.isValid()
| 0 | ||||||||||||||||||||||||
2771 | && blockLength > 1) {
| 0 | ||||||||||||||||||||||||
2772 | if (layoutFrom >= blockPosition + blockLength) {
| 0 | ||||||||||||||||||||||||
2773 | // if our height didn't change and the change in the document is | - | ||||||||||||||||||||||||
2774 | // in one of the later paragraphs, then we don't need to repaint | - | ||||||||||||||||||||||||
2775 | // this one | - | ||||||||||||||||||||||||
2776 | layoutStruct->updateRect.setTop(qMax(layoutStruct->updateRect.top(), layoutStruct->y.toReal())); | - | ||||||||||||||||||||||||
2777 | } else if (layoutTo < blockPosition) { never executed: end of block
| 0 | ||||||||||||||||||||||||
2778 | if (oldPosition == tl->position())
| 0 | ||||||||||||||||||||||||
2779 | // if the change in the document happened earlier in the document | - | ||||||||||||||||||||||||
2780 | // and our position did /not/ change because none of the earlier paragraphs | - | ||||||||||||||||||||||||
2781 | // or frames changed their height, then we don't need to repaint | - | ||||||||||||||||||||||||
2782 | // this one | - | ||||||||||||||||||||||||
2783 | layoutStruct->updateRect.setBottom(qMin(layoutStruct->updateRect.bottom(), tl->position().y())); never executed: layoutStruct->updateRect.setBottom(qMin(layoutStruct->updateRect.bottom(), tl->position().y())); | 0 | ||||||||||||||||||||||||
2784 | else | - | ||||||||||||||||||||||||
2785 | layoutStruct->updateRect.setBottom(qreal(INT_MAX)); // reset never executed: layoutStruct->updateRect.setBottom(qreal(2147483647)); | 0 | ||||||||||||||||||||||||
2786 | } | - | ||||||||||||||||||||||||
2787 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2788 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2789 | - | |||||||||||||||||||||||||
2790 | // ### doesn't take floats into account. would need to do it per line. but how to retrieve then? (Simon) | - | ||||||||||||||||||||||||
2791 | const QFixed margins = totalLeftMargin + totalRightMargin; | - | ||||||||||||||||||||||||
2792 | layoutStruct->minimumWidth = qMax(layoutStruct->minimumWidth, QFixed::fromReal(tl->minimumWidth()) + margins); | - | ||||||||||||||||||||||||
2793 | - | |||||||||||||||||||||||||
2794 | const QFixed maxW = QFixed::fromReal(tl->maximumWidth()) + margins; | - | ||||||||||||||||||||||||
2795 | - | |||||||||||||||||||||||||
2796 | if (maxW > 0) {
| 0 | ||||||||||||||||||||||||
2797 | if (layoutStruct->maximumWidth == QFIXED_MAX)
| 0 | ||||||||||||||||||||||||
2798 | layoutStruct->maximumWidth = maxW; never executed: layoutStruct->maximumWidth = maxW; | 0 | ||||||||||||||||||||||||
2799 | else | - | ||||||||||||||||||||||||
2800 | layoutStruct->maximumWidth = qMax(layoutStruct->maximumWidth, maxW); never executed: layoutStruct->maximumWidth = qMax(layoutStruct->maximumWidth, maxW); | 0 | ||||||||||||||||||||||||
2801 | } | - | ||||||||||||||||||||||||
2802 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2803 | - | |||||||||||||||||||||||||
2804 | void QTextDocumentLayoutPrivate::floatMargins(const QFixed &y, const QTextLayoutStruct *layoutStruct, | - | ||||||||||||||||||||||||
2805 | QFixed *left, QFixed *right) const | - | ||||||||||||||||||||||||
2806 | { | - | ||||||||||||||||||||||||
2807 | // qDebug() << "floatMargins y=" << y; | - | ||||||||||||||||||||||||
2808 | *left = layoutStruct->x_left; | - | ||||||||||||||||||||||||
2809 | *right = layoutStruct->x_right; | - | ||||||||||||||||||||||||
2810 | QTextFrameData *lfd = data(layoutStruct->frame); | - | ||||||||||||||||||||||||
2811 | for (int i = 0; i < lfd->floats.size(); ++i) {
| 0 | ||||||||||||||||||||||||
2812 | QTextFrameData *fd = data(lfd->floats.at(i)); | - | ||||||||||||||||||||||||
2813 | if (!fd->layoutDirty) {
| 0 | ||||||||||||||||||||||||
2814 | if (fd->position.y <= y && fd->position.y + fd->size.height > y) {
| 0 | ||||||||||||||||||||||||
2815 | // qDebug() << "adjusting with float" << f << fd->position.x()<< fd->size.width(); | - | ||||||||||||||||||||||||
2816 | if (lfd->floats.at(i)->frameFormat().position() == QTextFrameFormat::FloatLeft)
| 0 | ||||||||||||||||||||||||
2817 | *left = qMax(*left, fd->position.x + fd->size.width); never executed: *left = qMax(*left, fd->position.x + fd->size.width); | 0 | ||||||||||||||||||||||||
2818 | else | - | ||||||||||||||||||||||||
2819 | *right = qMin(*right, fd->position.x); never executed: *right = qMin(*right, fd->position.x); | 0 | ||||||||||||||||||||||||
2820 | } | - | ||||||||||||||||||||||||
2821 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2822 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2823 | // qDebug() << "floatMargins: left="<<*left<<"right="<<*right<<"y="<<y; | - | ||||||||||||||||||||||||
2824 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2825 | - | |||||||||||||||||||||||||
2826 | QFixed QTextDocumentLayoutPrivate::findY(QFixed yFrom, const QTextLayoutStruct *layoutStruct, QFixed requiredWidth) const | - | ||||||||||||||||||||||||
2827 | { | - | ||||||||||||||||||||||||
2828 | QFixed right, left; | - | ||||||||||||||||||||||||
2829 | requiredWidth = qMin(requiredWidth, layoutStruct->x_right - layoutStruct->x_left); | - | ||||||||||||||||||||||||
2830 | - | |||||||||||||||||||||||||
2831 | // qDebug() << "findY:" << yFrom; | - | ||||||||||||||||||||||||
2832 | while (1) { | - | ||||||||||||||||||||||||
2833 | floatMargins(yFrom, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2834 | // qDebug() << " yFrom=" << yFrom<<"right=" << right << "left=" << left << "requiredWidth=" << requiredWidth; | - | ||||||||||||||||||||||||
2835 | if (right-left >= requiredWidth)
| 0 | ||||||||||||||||||||||||
2836 | break; never executed: break; | 0 | ||||||||||||||||||||||||
2837 | - | |||||||||||||||||||||||||
2838 | // move float down until we find enough space | - | ||||||||||||||||||||||||
2839 | QFixed newY = QFIXED_MAX; | - | ||||||||||||||||||||||||
2840 | QTextFrameData *lfd = data(layoutStruct->frame); | - | ||||||||||||||||||||||||
2841 | for (int i = 0; i < lfd->floats.size(); ++i) {
| 0 | ||||||||||||||||||||||||
2842 | QTextFrameData *fd = data(lfd->floats.at(i)); | - | ||||||||||||||||||||||||
2843 | if (!fd->layoutDirty) {
| 0 | ||||||||||||||||||||||||
2844 | if (fd->position.y <= yFrom && fd->position.y + fd->size.height > yFrom)
| 0 | ||||||||||||||||||||||||
2845 | newY = qMin(newY, fd->position.y + fd->size.height); never executed: newY = qMin(newY, fd->position.y + fd->size.height); | 0 | ||||||||||||||||||||||||
2846 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2847 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2848 | if (newY == QFIXED_MAX)
| 0 | ||||||||||||||||||||||||
2849 | break; never executed: break; | 0 | ||||||||||||||||||||||||
2850 | yFrom = newY; | - | ||||||||||||||||||||||||
2851 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2852 | return yFrom; never executed: return yFrom; | 0 | ||||||||||||||||||||||||
2853 | } | - | ||||||||||||||||||||||||
2854 | - | |||||||||||||||||||||||||
2855 | QTextDocumentLayout::QTextDocumentLayout(QTextDocument *doc) | - | ||||||||||||||||||||||||
2856 | : QAbstractTextDocumentLayout(*new QTextDocumentLayoutPrivate, doc) | - | ||||||||||||||||||||||||
2857 | { | - | ||||||||||||||||||||||||
2858 | registerHandler(QTextFormat::ImageObject, new QTextImageHandler(this)); | - | ||||||||||||||||||||||||
2859 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2860 | - | |||||||||||||||||||||||||
2861 | - | |||||||||||||||||||||||||
2862 | void QTextDocumentLayout::draw(QPainter *painter, const PaintContext &context) | - | ||||||||||||||||||||||||
2863 | { | - | ||||||||||||||||||||||||
2864 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
2865 | QTextFrame *frame = d->document->rootFrame(); | - | ||||||||||||||||||||||||
2866 | QTextFrameData *fd = data(frame); | - | ||||||||||||||||||||||||
2867 | - | |||||||||||||||||||||||||
2868 | if(fd->sizeDirty)
| 0 | ||||||||||||||||||||||||
2869 | return; never executed: return; | 0 | ||||||||||||||||||||||||
2870 | - | |||||||||||||||||||||||||
2871 | if (context.clip.isValid()) {
| 0 | ||||||||||||||||||||||||
2872 | d->ensureLayouted(QFixed::fromReal(context.clip.bottom())); | - | ||||||||||||||||||||||||
2873 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2874 | d->ensureLayoutFinished(); | - | ||||||||||||||||||||||||
2875 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2876 | - | |||||||||||||||||||||||||
2877 | QFixed width = fd->size.width; | - | ||||||||||||||||||||||||
2878 | if (d->document->pageSize().width() == 0 && d->viewportRect.isValid()) {
| 0 | ||||||||||||||||||||||||
2879 | // we're in NoWrap mode, meaning the frame should expand to the viewport | - | ||||||||||||||||||||||||
2880 | // so that backgrounds are drawn correctly | - | ||||||||||||||||||||||||
2881 | fd->size.width = qMax(width, QFixed::fromReal(d->viewportRect.right())); | - | ||||||||||||||||||||||||
2882 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2883 | - | |||||||||||||||||||||||||
2884 | // Make sure we conform to the root frames bounds when drawing. | - | ||||||||||||||||||||||||
2885 | d->clipRect = QRectF(fd->position.toPointF(), fd->size.toSizeF()).adjusted(fd->leftMargin.toReal(), 0, -fd->rightMargin.toReal(), 0); | - | ||||||||||||||||||||||||
2886 | d->drawFrame(QPointF(), painter, context, frame); | - | ||||||||||||||||||||||||
2887 | fd->size.width = width; | - | ||||||||||||||||||||||||
2888 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2889 | - | |||||||||||||||||||||||||
2890 | void QTextDocumentLayout::setViewport(const QRectF &viewport) | - | ||||||||||||||||||||||||
2891 | { | - | ||||||||||||||||||||||||
2892 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
2893 | d->viewportRect = viewport; | - | ||||||||||||||||||||||||
2894 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2895 | - | |||||||||||||||||||||||||
2896 | static void markFrames(QTextFrame *current, int from, int oldLength, int length) | - | ||||||||||||||||||||||||
2897 | { | - | ||||||||||||||||||||||||
2898 | int end = qMax(oldLength, length) + from; | - | ||||||||||||||||||||||||
2899 | - | |||||||||||||||||||||||||
2900 | if (current->firstPosition() >= end || current->lastPosition() < from)
| 0 | ||||||||||||||||||||||||
2901 | return; never executed: return; | 0 | ||||||||||||||||||||||||
2902 | - | |||||||||||||||||||||||||
2903 | QTextFrameData *fd = data(current); | - | ||||||||||||||||||||||||
2904 | // float got removed in editing operation | - | ||||||||||||||||||||||||
2905 | QTextFrame *null = nullptr; // work-around for (at least) MSVC 2012 emitting | - | ||||||||||||||||||||||||
2906 | // warning C4100 for its own header <algorithm> | - | ||||||||||||||||||||||||
2907 | // when passing nullptr directly to std::remove | - | ||||||||||||||||||||||||
2908 | fd->floats.erase(std::remove(fd->floats.begin(), fd->floats.end(), null), | - | ||||||||||||||||||||||||
2909 | fd->floats.end()); | - | ||||||||||||||||||||||||
2910 | - | |||||||||||||||||||||||||
2911 | fd->layoutDirty = true; | - | ||||||||||||||||||||||||
2912 | fd->sizeDirty = true; | - | ||||||||||||||||||||||||
2913 | - | |||||||||||||||||||||||||
2914 | // qDebug(" marking frame (%d--%d) as dirty", current->firstPosition(), current->lastPosition()); | - | ||||||||||||||||||||||||
2915 | QList<QTextFrame *> children = current->childFrames(); | - | ||||||||||||||||||||||||
2916 | for (int i = 0; i < children.size(); ++i)
| 0 | ||||||||||||||||||||||||
2917 | markFrames(children.at(i), from, oldLength, length); never executed: markFrames(children.at(i), from, oldLength, length); | 0 | ||||||||||||||||||||||||
2918 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2919 | - | |||||||||||||||||||||||||
2920 | void QTextDocumentLayout::documentChanged(int from, int oldLength, int length) | - | ||||||||||||||||||||||||
2921 | { | - | ||||||||||||||||||||||||
2922 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
2923 | - | |||||||||||||||||||||||||
2924 | QTextBlock startIt = document()->findBlock(from); | - | ||||||||||||||||||||||||
2925 | QTextBlock endIt = document()->findBlock(qMax(0, from + length - 1)); | - | ||||||||||||||||||||||||
2926 | if (endIt.isValid())
| 0 | ||||||||||||||||||||||||
2927 | endIt = endIt.next(); never executed: endIt = endIt.next(); | 0 | ||||||||||||||||||||||||
2928 | for (QTextBlock blockIt = startIt; blockIt.isValid() && blockIt != endIt; blockIt = blockIt.next())
| 0 | ||||||||||||||||||||||||
2929 | blockIt.clearLayout(); never executed: blockIt.clearLayout(); | 0 | ||||||||||||||||||||||||
2930 | - | |||||||||||||||||||||||||
2931 | if (d->docPrivate->pageSize.isNull())
| 0 | ||||||||||||||||||||||||
2932 | return; never executed: return; | 0 | ||||||||||||||||||||||||
2933 | - | |||||||||||||||||||||||||
2934 | QRectF updateRect; | - | ||||||||||||||||||||||||
2935 | - | |||||||||||||||||||||||||
2936 | d->lazyLayoutStepSize = 1000; | - | ||||||||||||||||||||||||
2937 | d->sizeChangedTimer.stop(); | - | ||||||||||||||||||||||||
2938 | d->insideDocumentChange = true; | - | ||||||||||||||||||||||||
2939 | - | |||||||||||||||||||||||||
2940 | const int documentLength = d->docPrivate->length(); | - | ||||||||||||||||||||||||
2941 | const bool fullLayout = (oldLength == 0 && length == documentLength);
| 0 | ||||||||||||||||||||||||
2942 | const bool smallChange = documentLength > 0
| 0 | ||||||||||||||||||||||||
2943 | && (qMax(length, oldLength) * 100 / documentLength) < 5;
| 0 | ||||||||||||||||||||||||
2944 | - | |||||||||||||||||||||||||
2945 | // don't show incremental layout progress (avoid scroll bar flicker) | - | ||||||||||||||||||||||||
2946 | // if we see only a small change in the document and we're either starting | - | ||||||||||||||||||||||||
2947 | // a layout run or we're already in progress for that and we haven't seen | - | ||||||||||||||||||||||||
2948 | // any bigger change previously (showLayoutProgress already false) | - | ||||||||||||||||||||||||
2949 | if (smallChange
| 0 | ||||||||||||||||||||||||
2950 | && (d->currentLazyLayoutPosition == -1 || d->showLayoutProgress == false))
| 0 | ||||||||||||||||||||||||
2951 | d->showLayoutProgress = false; never executed: d->showLayoutProgress = false; | 0 | ||||||||||||||||||||||||
2952 | else | - | ||||||||||||||||||||||||
2953 | d->showLayoutProgress = true; never executed: d->showLayoutProgress = true; | 0 | ||||||||||||||||||||||||
2954 | - | |||||||||||||||||||||||||
2955 | if (fullLayout) {
| 0 | ||||||||||||||||||||||||
2956 | d->contentHasAlignment = false; | - | ||||||||||||||||||||||||
2957 | d->currentLazyLayoutPosition = 0; | - | ||||||||||||||||||||||||
2958 | d->checkPoints.clear(); | - | ||||||||||||||||||||||||
2959 | d->layoutStep(); | - | ||||||||||||||||||||||||
2960 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2961 | d->ensureLayoutedByPosition(from); | - | ||||||||||||||||||||||||
2962 | updateRect = doLayout(from, oldLength, length); | - | ||||||||||||||||||||||||
2963 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2964 | - | |||||||||||||||||||||||||
2965 | if (!d->layoutTimer.isActive() && d->currentLazyLayoutPosition != -1)
| 0 | ||||||||||||||||||||||||
2966 | d->layoutTimer.start(10, this); never executed: d->layoutTimer.start(10, this); | 0 | ||||||||||||||||||||||||
2967 | - | |||||||||||||||||||||||||
2968 | d->insideDocumentChange = false; | - | ||||||||||||||||||||||||
2969 | - | |||||||||||||||||||||||||
2970 | for (QTextBlock blockIt = startIt; blockIt.isValid() && blockIt != endIt; blockIt = blockIt.next())
| 0 | ||||||||||||||||||||||||
2971 | emit updateBlock(blockIt); never executed: updateBlock(blockIt); | 0 | ||||||||||||||||||||||||
2972 | - | |||||||||||||||||||||||||
2973 | if (d->showLayoutProgress) {
| 0 | ||||||||||||||||||||||||
2974 | const QSizeF newSize = dynamicDocumentSize(); | - | ||||||||||||||||||||||||
2975 | if (newSize != d->lastReportedSize) {
| 0 | ||||||||||||||||||||||||
2976 | d->lastReportedSize = newSize; | - | ||||||||||||||||||||||||
2977 | emit documentSizeChanged(newSize); | - | ||||||||||||||||||||||||
2978 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2979 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2980 | - | |||||||||||||||||||||||||
2981 | if (!updateRect.isValid()) {
| 0 | ||||||||||||||||||||||||
2982 | // don't use the frame size, it might have shrunken | - | ||||||||||||||||||||||||
2983 | updateRect = QRectF(QPointF(0, 0), QSizeF(qreal(INT_MAX), qreal(INT_MAX))); | - | ||||||||||||||||||||||||
2984 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2985 | - | |||||||||||||||||||||||||
2986 | emit update(updateRect); | - | ||||||||||||||||||||||||
2987 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2988 | - | |||||||||||||||||||||||||
2989 | QRectF QTextDocumentLayout::doLayout(int from, int oldLength, int length) | - | ||||||||||||||||||||||||
2990 | { | - | ||||||||||||||||||||||||
2991 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
2992 | - | |||||||||||||||||||||||||
2993 | // qDebug("documentChange: from=%d, oldLength=%d, length=%d", from, oldLength, length); | - | ||||||||||||||||||||||||
2994 | - | |||||||||||||||||||||||||
2995 | // mark all frames between f_start and f_end as dirty | - | ||||||||||||||||||||||||
2996 | markFrames(d->docPrivate->rootFrame(), from, oldLength, length); | - | ||||||||||||||||||||||||
2997 | - | |||||||||||||||||||||||||
2998 | QRectF updateRect; | - | ||||||||||||||||||||||||
2999 | - | |||||||||||||||||||||||||
3000 | QTextFrame *root = d->docPrivate->rootFrame(); | - | ||||||||||||||||||||||||
3001 | if(data(root)->sizeDirty)
| 0 | ||||||||||||||||||||||||
3002 | updateRect = d->layoutFrame(root, from, from + length); never executed: updateRect = d->layoutFrame(root, from, from + length); | 0 | ||||||||||||||||||||||||
3003 | data(root)->layoutDirty = false; | - | ||||||||||||||||||||||||
3004 | - | |||||||||||||||||||||||||
3005 | if (d->currentLazyLayoutPosition == -1)
| 0 | ||||||||||||||||||||||||
3006 | layoutFinished(); never executed: layoutFinished(); | 0 | ||||||||||||||||||||||||
3007 | else if (d->showLayoutProgress)
| 0 | ||||||||||||||||||||||||
3008 | d->sizeChangedTimer.start(0, this); never executed: d->sizeChangedTimer.start(0, this); | 0 | ||||||||||||||||||||||||
3009 | - | |||||||||||||||||||||||||
3010 | return updateRect; never executed: return updateRect; | 0 | ||||||||||||||||||||||||
3011 | } | - | ||||||||||||||||||||||||
3012 | - | |||||||||||||||||||||||||
3013 | int QTextDocumentLayout::hitTest(const QPointF &point, Qt::HitTestAccuracy accuracy) const | - | ||||||||||||||||||||||||
3014 | { | - | ||||||||||||||||||||||||
3015 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3016 | d->ensureLayouted(QFixed::fromReal(point.y())); | - | ||||||||||||||||||||||||
3017 | QTextFrame *f = d->docPrivate->rootFrame(); | - | ||||||||||||||||||||||||
3018 | int position = 0; | - | ||||||||||||||||||||||||
3019 | QTextLayout *l = 0; | - | ||||||||||||||||||||||||
3020 | QFixedPoint pointf; | - | ||||||||||||||||||||||||
3021 | pointf.x = QFixed::fromReal(point.x()); | - | ||||||||||||||||||||||||
3022 | pointf.y = QFixed::fromReal(point.y()); | - | ||||||||||||||||||||||||
3023 | QTextDocumentLayoutPrivate::HitPoint p = d->hitTest(f, pointf, &position, &l, accuracy); | - | ||||||||||||||||||||||||
3024 | if (accuracy == Qt::ExactHit && p < QTextDocumentLayoutPrivate::PointExact)
| 0 | ||||||||||||||||||||||||
3025 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
3026 | - | |||||||||||||||||||||||||
3027 | // ensure we stay within document bounds | - | ||||||||||||||||||||||||
3028 | int lastPos = f->lastPosition(); | - | ||||||||||||||||||||||||
3029 | if (l && !l->preeditAreaText().isEmpty())
| 0 | ||||||||||||||||||||||||
3030 | lastPos += l->preeditAreaText().length(); never executed: lastPos += l->preeditAreaText().length(); | 0 | ||||||||||||||||||||||||
3031 | if (position > lastPos)
| 0 | ||||||||||||||||||||||||
3032 | position = lastPos; never executed: position = lastPos; | 0 | ||||||||||||||||||||||||
3033 | else if (position < 0)
| 0 | ||||||||||||||||||||||||
3034 | position = 0; never executed: position = 0; | 0 | ||||||||||||||||||||||||
3035 | - | |||||||||||||||||||||||||
3036 | return position; never executed: return position; | 0 | ||||||||||||||||||||||||
3037 | } | - | ||||||||||||||||||||||||
3038 | - | |||||||||||||||||||||||||
3039 | void QTextDocumentLayout::resizeInlineObject(QTextInlineObject item, int posInDocument, const QTextFormat &format) | - | ||||||||||||||||||||||||
3040 | { | - | ||||||||||||||||||||||||
3041 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
3042 | QTextCharFormat f = format.toCharFormat(); | - | ||||||||||||||||||||||||
3043 | Q_ASSERT(f.isValid()); | - | ||||||||||||||||||||||||
3044 | QTextObjectHandler handler = d->handlers.value(f.objectType()); | - | ||||||||||||||||||||||||
3045 | if (!handler.component)
| 0 | ||||||||||||||||||||||||
3046 | return; never executed: return; | 0 | ||||||||||||||||||||||||
3047 | - | |||||||||||||||||||||||||
3048 | QSizeF intrinsic = handler.iface->intrinsicSize(d->document, posInDocument, format); | - | ||||||||||||||||||||||||
3049 | - | |||||||||||||||||||||||||
3050 | QTextFrameFormat::Position pos = QTextFrameFormat::InFlow; | - | ||||||||||||||||||||||||
3051 | QTextFrame *frame = qobject_cast<QTextFrame *>(d->document->objectForFormat(f)); | - | ||||||||||||||||||||||||
3052 | if (frame) {
| 0 | ||||||||||||||||||||||||
3053 | pos = frame->frameFormat().position(); | - | ||||||||||||||||||||||||
3054 | QTextFrameData *fd = data(frame); | - | ||||||||||||||||||||||||
3055 | fd->sizeDirty = false; | - | ||||||||||||||||||||||||
3056 | fd->size = QFixedSize::fromSizeF(intrinsic); | - | ||||||||||||||||||||||||
3057 | fd->minimumWidth = fd->maximumWidth = fd->size.width; | - | ||||||||||||||||||||||||
3058 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3059 | - | |||||||||||||||||||||||||
3060 | QSizeF inlineSize = (pos == QTextFrameFormat::InFlow ? intrinsic : QSizeF(0, 0));
| 0 | ||||||||||||||||||||||||
3061 | item.setWidth(inlineSize.width()); | - | ||||||||||||||||||||||||
3062 | - | |||||||||||||||||||||||||
3063 | QFontMetrics m(f.font()); | - | ||||||||||||||||||||||||
3064 | switch (f.verticalAlignment()) | - | ||||||||||||||||||||||||
3065 | { | - | ||||||||||||||||||||||||
3066 | case QTextCharFormat::AlignMiddle: never executed: case QTextCharFormat::AlignMiddle: | 0 | ||||||||||||||||||||||||
3067 | item.setDescent(inlineSize.height() / 2); | - | ||||||||||||||||||||||||
3068 | item.setAscent(inlineSize.height() / 2); | - | ||||||||||||||||||||||||
3069 | break; never executed: break; | 0 | ||||||||||||||||||||||||
3070 | case QTextCharFormat::AlignBaseline: never executed: case QTextCharFormat::AlignBaseline: | 0 | ||||||||||||||||||||||||
3071 | item.setDescent(m.descent()); | - | ||||||||||||||||||||||||
3072 | item.setAscent(inlineSize.height() - m.descent()); | - | ||||||||||||||||||||||||
3073 | break; never executed: break; | 0 | ||||||||||||||||||||||||
3074 | default: never executed: default: | 0 | ||||||||||||||||||||||||
3075 | item.setDescent(0); | - | ||||||||||||||||||||||||
3076 | item.setAscent(inlineSize.height()); | - | ||||||||||||||||||||||||
3077 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3078 | } | - | ||||||||||||||||||||||||
3079 | - | |||||||||||||||||||||||||
3080 | void QTextDocumentLayout::positionInlineObject(QTextInlineObject item, int posInDocument, const QTextFormat &format) | - | ||||||||||||||||||||||||
3081 | { | - | ||||||||||||||||||||||||
3082 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
3083 | Q_UNUSED(posInDocument); | - | ||||||||||||||||||||||||
3084 | if (item.width() != 0)
| 0 | ||||||||||||||||||||||||
3085 | // inline | - | ||||||||||||||||||||||||
3086 | return; never executed: return; | 0 | ||||||||||||||||||||||||
3087 | - | |||||||||||||||||||||||||
3088 | QTextCharFormat f = format.toCharFormat(); | - | ||||||||||||||||||||||||
3089 | Q_ASSERT(f.isValid()); | - | ||||||||||||||||||||||||
3090 | QTextObjectHandler handler = d->handlers.value(f.objectType()); | - | ||||||||||||||||||||||||
3091 | if (!handler.component)
| 0 | ||||||||||||||||||||||||
3092 | return; never executed: return; | 0 | ||||||||||||||||||||||||
3093 | - | |||||||||||||||||||||||||
3094 | QTextFrame *frame = qobject_cast<QTextFrame *>(d->document->objectForFormat(f)); | - | ||||||||||||||||||||||||
3095 | if (!frame)
| 0 | ||||||||||||||||||||||||
3096 | return; never executed: return; | 0 | ||||||||||||||||||||||||
3097 | - | |||||||||||||||||||||||||
3098 | QTextBlock b = d->document->findBlock(frame->firstPosition()); | - | ||||||||||||||||||||||||
3099 | QTextLine line; | - | ||||||||||||||||||||||||
3100 | if (b.position() <= frame->firstPosition() && b.position() + b.length() > frame->lastPosition())
| 0 | ||||||||||||||||||||||||
3101 | line = b.layout()->lineAt(b.layout()->lineCount()-1); never executed: line = b.layout()->lineAt(b.layout()->lineCount()-1); | 0 | ||||||||||||||||||||||||
3102 | // qDebug() << "layoutObject: line.isValid" << line.isValid() << b.position() << b.length() << | - | ||||||||||||||||||||||||
3103 | // frame->firstPosition() << frame->lastPosition(); | - | ||||||||||||||||||||||||
3104 | d->positionFloat(frame, line.isValid() ? &line : 0); | - | ||||||||||||||||||||||||
3105 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3106 | - | |||||||||||||||||||||||||
3107 | void QTextDocumentLayout::drawInlineObject(QPainter *p, const QRectF &rect, QTextInlineObject item, | - | ||||||||||||||||||||||||
3108 | int posInDocument, const QTextFormat &format) | - | ||||||||||||||||||||||||
3109 | { | - | ||||||||||||||||||||||||
3110 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
3111 | QTextCharFormat f = format.toCharFormat(); | - | ||||||||||||||||||||||||
3112 | Q_ASSERT(f.isValid()); | - | ||||||||||||||||||||||||
3113 | QTextFrame *frame = qobject_cast<QTextFrame *>(d->document->objectForFormat(f)); | - | ||||||||||||||||||||||||
3114 | if (frame && frame->frameFormat().position() != QTextFrameFormat::InFlow)
| 0 | ||||||||||||||||||||||||
3115 | return; // don't draw floating frames from inline objects here but in drawFlow instead never executed: return; | 0 | ||||||||||||||||||||||||
3116 | - | |||||||||||||||||||||||||
3117 | // qDebug() << "drawObject at" << r; | - | ||||||||||||||||||||||||
3118 | QAbstractTextDocumentLayout::drawInlineObject(p, rect, item, posInDocument, format); | - | ||||||||||||||||||||||||
3119 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3120 | - | |||||||||||||||||||||||||
3121 | int QTextDocumentLayout::dynamicPageCount() const | - | ||||||||||||||||||||||||
3122 | { | - | ||||||||||||||||||||||||
3123 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3124 | const QSizeF pgSize = d->document->pageSize(); | - | ||||||||||||||||||||||||
3125 | if (pgSize.height() < 0)
| 0 | ||||||||||||||||||||||||
3126 | return 1; never executed: return 1; | 0 | ||||||||||||||||||||||||
3127 | return qCeil(dynamicDocumentSize().height() / pgSize.height()); never executed: return qCeil(dynamicDocumentSize().height() / pgSize.height()); | 0 | ||||||||||||||||||||||||
3128 | } | - | ||||||||||||||||||||||||
3129 | - | |||||||||||||||||||||||||
3130 | QSizeF QTextDocumentLayout::dynamicDocumentSize() const | - | ||||||||||||||||||||||||
3131 | { | - | ||||||||||||||||||||||||
3132 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3133 | return data(d->docPrivate->rootFrame())->size.toSizeF(); never executed: return data(d->docPrivate->rootFrame())->size.toSizeF(); | 0 | ||||||||||||||||||||||||
3134 | } | - | ||||||||||||||||||||||||
3135 | - | |||||||||||||||||||||||||
3136 | int QTextDocumentLayout::pageCount() const | - | ||||||||||||||||||||||||
3137 | { | - | ||||||||||||||||||||||||
3138 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3139 | d->ensureLayoutFinished(); | - | ||||||||||||||||||||||||
3140 | return dynamicPageCount(); never executed: return dynamicPageCount(); | 0 | ||||||||||||||||||||||||
3141 | } | - | ||||||||||||||||||||||||
3142 | - | |||||||||||||||||||||||||
3143 | QSizeF QTextDocumentLayout::documentSize() const | - | ||||||||||||||||||||||||
3144 | { | - | ||||||||||||||||||||||||
3145 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3146 | d->ensureLayoutFinished(); | - | ||||||||||||||||||||||||
3147 | return dynamicDocumentSize(); never executed: return dynamicDocumentSize(); | 0 | ||||||||||||||||||||||||
3148 | } | - | ||||||||||||||||||||||||
3149 | - | |||||||||||||||||||||||||
3150 | void QTextDocumentLayoutPrivate::ensureLayouted(QFixed y) const | - | ||||||||||||||||||||||||
3151 | { | - | ||||||||||||||||||||||||
3152 | Q_Q(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3153 | if (currentLazyLayoutPosition == -1)
| 0 | ||||||||||||||||||||||||
3154 | return; never executed: return; | 0 | ||||||||||||||||||||||||
3155 | const QSizeF oldSize = q->dynamicDocumentSize(); | - | ||||||||||||||||||||||||
3156 | Q_UNUSED(oldSize); | - | ||||||||||||||||||||||||
3157 | - | |||||||||||||||||||||||||
3158 | if (checkPoints.isEmpty())
| 0 | ||||||||||||||||||||||||
3159 | layoutStep(); never executed: layoutStep(); | 0 | ||||||||||||||||||||||||
3160 | - | |||||||||||||||||||||||||
3161 | while (currentLazyLayoutPosition != -1
| 0 | ||||||||||||||||||||||||
3162 | && checkPoints.last().y < y)
| 0 | ||||||||||||||||||||||||
3163 | layoutStep(); never executed: layoutStep(); | 0 | ||||||||||||||||||||||||
3164 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3165 | - | |||||||||||||||||||||||||
3166 | void QTextDocumentLayoutPrivate::ensureLayoutedByPosition(int position) const | - | ||||||||||||||||||||||||
3167 | { | - | ||||||||||||||||||||||||
3168 | if (currentLazyLayoutPosition == -1)
| 0 | ||||||||||||||||||||||||
3169 | return; never executed: return; | 0 | ||||||||||||||||||||||||
3170 | if (position < currentLazyLayoutPosition)
| 0 | ||||||||||||||||||||||||
3171 | return; never executed: return; | 0 | ||||||||||||||||||||||||
3172 | while (currentLazyLayoutPosition != -1
| 0 | ||||||||||||||||||||||||
3173 | && currentLazyLayoutPosition < position) {
| 0 | ||||||||||||||||||||||||
3174 | const_cast<QTextDocumentLayout *>(q_func())->doLayout(currentLazyLayoutPosition, 0, INT_MAX - currentLazyLayoutPosition); | - | ||||||||||||||||||||||||
3175 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3176 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3177 | - | |||||||||||||||||||||||||
3178 | void QTextDocumentLayoutPrivate::layoutStep() const | - | ||||||||||||||||||||||||
3179 | { | - | ||||||||||||||||||||||||
3180 | ensureLayoutedByPosition(currentLazyLayoutPosition + lazyLayoutStepSize); | - | ||||||||||||||||||||||||
3181 | lazyLayoutStepSize = qMin(200000, lazyLayoutStepSize * 2); | - | ||||||||||||||||||||||||
3182 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3183 | - | |||||||||||||||||||||||||
3184 | void QTextDocumentLayout::setCursorWidth(int width) | - | ||||||||||||||||||||||||
3185 | { | - | ||||||||||||||||||||||||
3186 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
3187 | d->cursorWidth = width; | - | ||||||||||||||||||||||||
3188 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3189 | - | |||||||||||||||||||||||||
3190 | int QTextDocumentLayout::cursorWidth() const | - | ||||||||||||||||||||||||
3191 | { | - | ||||||||||||||||||||||||
3192 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3193 | return d->cursorWidth; never executed: return d->cursorWidth; | 0 | ||||||||||||||||||||||||
3194 | } | - | ||||||||||||||||||||||||
3195 | - | |||||||||||||||||||||||||
3196 | void QTextDocumentLayout::setFixedColumnWidth(int width) | - | ||||||||||||||||||||||||
3197 | { | - | ||||||||||||||||||||||||
3198 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
3199 | d->fixedColumnWidth = width; | - | ||||||||||||||||||||||||
3200 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3201 | - | |||||||||||||||||||||||||
3202 | QRectF QTextDocumentLayout::tableCellBoundingRect(QTextTable *table, const QTextTableCell &cell) const | - | ||||||||||||||||||||||||
3203 | { | - | ||||||||||||||||||||||||
3204 | if (!cell.isValid())
| 0 | ||||||||||||||||||||||||
3205 | return QRectF(); never executed: return QRectF(); | 0 | ||||||||||||||||||||||||
3206 | - | |||||||||||||||||||||||||
3207 | QTextTableData *td = static_cast<QTextTableData *>(data(table)); | - | ||||||||||||||||||||||||
3208 | - | |||||||||||||||||||||||||
3209 | QRectF tableRect = tableBoundingRect(table); | - | ||||||||||||||||||||||||
3210 | QRectF cellRect = td->cellRect(cell); | - | ||||||||||||||||||||||||
3211 | - | |||||||||||||||||||||||||
3212 | return cellRect.translated(tableRect.topLeft()); never executed: return cellRect.translated(tableRect.topLeft()); | 0 | ||||||||||||||||||||||||
3213 | } | - | ||||||||||||||||||||||||
3214 | - | |||||||||||||||||||||||||
3215 | QRectF QTextDocumentLayout::tableBoundingRect(QTextTable *table) const | - | ||||||||||||||||||||||||
3216 | { | - | ||||||||||||||||||||||||
3217 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3218 | if (d->docPrivate->pageSize.isNull())
| 0 | ||||||||||||||||||||||||
3219 | return QRectF(); never executed: return QRectF(); | 0 | ||||||||||||||||||||||||
3220 | d->ensureLayoutFinished(); | - | ||||||||||||||||||||||||
3221 | - | |||||||||||||||||||||||||
3222 | QPointF pos; | - | ||||||||||||||||||||||||
3223 | const int framePos = table->firstPosition(); | - | ||||||||||||||||||||||||
3224 | QTextFrame *f = table; | - | ||||||||||||||||||||||||
3225 | while (f) {
| 0 | ||||||||||||||||||||||||
3226 | QTextFrameData *fd = data(f); | - | ||||||||||||||||||||||||
3227 | pos += fd->position.toPointF(); | - | ||||||||||||||||||||||||
3228 | - | |||||||||||||||||||||||||
3229 | if (f != table) {
| 0 | ||||||||||||||||||||||||
3230 | if (QTextTable *table = qobject_cast<QTextTable *>(f)) {
| 0 | ||||||||||||||||||||||||
3231 | QTextTableCell cell = table->cellAt(framePos); | - | ||||||||||||||||||||||||
3232 | if (cell.isValid())
| 0 | ||||||||||||||||||||||||
3233 | pos += static_cast<QTextTableData *>(fd)->cellPosition(cell).toPointF(); never executed: pos += static_cast<QTextTableData *>(fd)->cellPosition(cell).toPointF(); | 0 | ||||||||||||||||||||||||
3234 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3235 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3236 | - | |||||||||||||||||||||||||
3237 | f = f->parentFrame(); | - | ||||||||||||||||||||||||
3238 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3239 | return QRectF(pos, data(table)->size.toSizeF()); never executed: return QRectF(pos, data(table)->size.toSizeF()); | 0 | ||||||||||||||||||||||||
3240 | } | - | ||||||||||||||||||||||||
3241 | - | |||||||||||||||||||||||||
3242 | QRectF QTextDocumentLayout::frameBoundingRect(QTextFrame *frame) const | - | ||||||||||||||||||||||||
3243 | { | - | ||||||||||||||||||||||||
3244 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3245 | if (d->docPrivate->pageSize.isNull())
| 0 | ||||||||||||||||||||||||
3246 | return QRectF(); never executed: return QRectF(); | 0 | ||||||||||||||||||||||||
3247 | d->ensureLayoutFinished(); | - | ||||||||||||||||||||||||
3248 | return d->frameBoundingRectInternal(frame); never executed: return d->frameBoundingRectInternal(frame); | 0 | ||||||||||||||||||||||||
3249 | } | - | ||||||||||||||||||||||||
3250 | - | |||||||||||||||||||||||||
3251 | QRectF QTextDocumentLayoutPrivate::frameBoundingRectInternal(QTextFrame *frame) const | - | ||||||||||||||||||||||||
3252 | { | - | ||||||||||||||||||||||||
3253 | QPointF pos; | - | ||||||||||||||||||||||||
3254 | const int framePos = frame->firstPosition(); | - | ||||||||||||||||||||||||
3255 | QTextFrame *f = frame; | - | ||||||||||||||||||||||||
3256 | while (f) {
| 0 | ||||||||||||||||||||||||
3257 | QTextFrameData *fd = data(f); | - | ||||||||||||||||||||||||
3258 | pos += fd->position.toPointF(); | - | ||||||||||||||||||||||||
3259 | - | |||||||||||||||||||||||||
3260 | if (QTextTable *table = qobject_cast<QTextTable *>(f)) {
| 0 | ||||||||||||||||||||||||
3261 | QTextTableCell cell = table->cellAt(framePos); | - | ||||||||||||||||||||||||
3262 | if (cell.isValid())
| 0 | ||||||||||||||||||||||||
3263 | pos += static_cast<QTextTableData *>(fd)->cellPosition(cell).toPointF(); never executed: pos += static_cast<QTextTableData *>(fd)->cellPosition(cell).toPointF(); | 0 | ||||||||||||||||||||||||
3264 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3265 | - | |||||||||||||||||||||||||
3266 | f = f->parentFrame(); | - | ||||||||||||||||||||||||
3267 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3268 | return QRectF(pos, data(frame)->size.toSizeF()); never executed: return QRectF(pos, data(frame)->size.toSizeF()); | 0 | ||||||||||||||||||||||||
3269 | } | - | ||||||||||||||||||||||||
3270 | - | |||||||||||||||||||||||||
3271 | QRectF QTextDocumentLayout::blockBoundingRect(const QTextBlock &block) const | - | ||||||||||||||||||||||||
3272 | { | - | ||||||||||||||||||||||||
3273 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3274 | if (d->docPrivate->pageSize.isNull() || !block.isValid() || !block.isVisible())
| 0 | ||||||||||||||||||||||||
3275 | return QRectF(); never executed: return QRectF(); | 0 | ||||||||||||||||||||||||
3276 | d->ensureLayoutedByPosition(block.position() + block.length()); | - | ||||||||||||||||||||||||
3277 | QTextFrame *frame = d->document->frameAt(block.position()); | - | ||||||||||||||||||||||||
3278 | QPointF offset; | - | ||||||||||||||||||||||||
3279 | const int blockPos = block.position(); | - | ||||||||||||||||||||||||
3280 | - | |||||||||||||||||||||||||
3281 | while (frame) {
| 0 | ||||||||||||||||||||||||
3282 | QTextFrameData *fd = data(frame); | - | ||||||||||||||||||||||||
3283 | offset += fd->position.toPointF(); | - | ||||||||||||||||||||||||
3284 | - | |||||||||||||||||||||||||
3285 | if (QTextTable *table = qobject_cast<QTextTable *>(frame)) {
| 0 | ||||||||||||||||||||||||
3286 | QTextTableCell cell = table->cellAt(blockPos); | - | ||||||||||||||||||||||||
3287 | if (cell.isValid())
| 0 | ||||||||||||||||||||||||
3288 | offset += static_cast<QTextTableData *>(fd)->cellPosition(cell).toPointF(); never executed: offset += static_cast<QTextTableData *>(fd)->cellPosition(cell).toPointF(); | 0 | ||||||||||||||||||||||||
3289 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3290 | - | |||||||||||||||||||||||||
3291 | frame = frame->parentFrame(); | - | ||||||||||||||||||||||||
3292 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3293 | - | |||||||||||||||||||||||||
3294 | const QTextLayout *layout = block.layout(); | - | ||||||||||||||||||||||||
3295 | QRectF rect = layout->boundingRect(); | - | ||||||||||||||||||||||||
3296 | rect.moveTopLeft(layout->position() + offset); | - | ||||||||||||||||||||||||
3297 | return rect; never executed: return rect; | 0 | ||||||||||||||||||||||||
3298 | } | - | ||||||||||||||||||||||||
3299 | - | |||||||||||||||||||||||||
3300 | int QTextDocumentLayout::layoutStatus() const | - | ||||||||||||||||||||||||
3301 | { | - | ||||||||||||||||||||||||
3302 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3303 | int pos = d->currentLazyLayoutPosition; | - | ||||||||||||||||||||||||
3304 | if (pos == -1)
| 0 | ||||||||||||||||||||||||
3305 | return 100; never executed: return 100; | 0 | ||||||||||||||||||||||||
3306 | return pos * 100 / d->document->docHandle()->length(); never executed: return pos * 100 / d->document->docHandle()->length(); | 0 | ||||||||||||||||||||||||
3307 | } | - | ||||||||||||||||||||||||
3308 | - | |||||||||||||||||||||||||
3309 | void QTextDocumentLayout::timerEvent(QTimerEvent *e) | - | ||||||||||||||||||||||||
3310 | { | - | ||||||||||||||||||||||||
3311 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
3312 | if (e->timerId() == d->layoutTimer.timerId()) {
| 0 | ||||||||||||||||||||||||
3313 | if (d->currentLazyLayoutPosition != -1)
| 0 | ||||||||||||||||||||||||
3314 | d->layoutStep(); never executed: d->layoutStep(); | 0 | ||||||||||||||||||||||||
3315 | } else if (e->timerId() == d->sizeChangedTimer.timerId()) { never executed: end of block
| 0 | ||||||||||||||||||||||||
3316 | d->lastReportedSize = dynamicDocumentSize(); | - | ||||||||||||||||||||||||
3317 | emit documentSizeChanged(d->lastReportedSize); | - | ||||||||||||||||||||||||
3318 | d->sizeChangedTimer.stop(); | - | ||||||||||||||||||||||||
3319 | - | |||||||||||||||||||||||||
3320 | if (d->currentLazyLayoutPosition == -1) {
| 0 | ||||||||||||||||||||||||
3321 | const int newCount = dynamicPageCount(); | - | ||||||||||||||||||||||||
3322 | if (newCount != d->lastPageCount) {
| 0 | ||||||||||||||||||||||||
3323 | d->lastPageCount = newCount; | - | ||||||||||||||||||||||||
3324 | emit pageCountChanged(newCount); | - | ||||||||||||||||||||||||
3325 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3326 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3327 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
3328 | QAbstractTextDocumentLayout::timerEvent(e); | - | ||||||||||||||||||||||||
3329 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3330 | } | - | ||||||||||||||||||||||||
3331 | - | |||||||||||||||||||||||||
3332 | void QTextDocumentLayout::layoutFinished() | - | ||||||||||||||||||||||||
3333 | { | - | ||||||||||||||||||||||||
3334 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
3335 | d->layoutTimer.stop(); | - | ||||||||||||||||||||||||
3336 | if (!d->insideDocumentChange)
| 0 | ||||||||||||||||||||||||
3337 | d->sizeChangedTimer.start(0, this); never executed: d->sizeChangedTimer.start(0, this); | 0 | ||||||||||||||||||||||||
3338 | // reset | - | ||||||||||||||||||||||||
3339 | d->showLayoutProgress = true; | - | ||||||||||||||||||||||||
3340 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3341 | - | |||||||||||||||||||||||||
3342 | void QTextDocumentLayout::ensureLayouted(qreal y) | - | ||||||||||||||||||||||||
3343 | { | - | ||||||||||||||||||||||||
3344 | d_func()->ensureLayouted(QFixed::fromReal(y)); | - | ||||||||||||||||||||||||
3345 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3346 | - | |||||||||||||||||||||||||
3347 | qreal QTextDocumentLayout::idealWidth() const | - | ||||||||||||||||||||||||
3348 | { | - | ||||||||||||||||||||||||
3349 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3350 | d->ensureLayoutFinished(); | - | ||||||||||||||||||||||||
3351 | return d->idealWidth; never executed: return d->idealWidth; | 0 | ||||||||||||||||||||||||
3352 | } | - | ||||||||||||||||||||||||
3353 | - | |||||||||||||||||||||||||
3354 | bool QTextDocumentLayout::contentHasAlignment() const | - | ||||||||||||||||||||||||
3355 | { | - | ||||||||||||||||||||||||
3356 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3357 | return d->contentHasAlignment; never executed: return d->contentHasAlignment; | 0 | ||||||||||||||||||||||||
3358 | } | - | ||||||||||||||||||||||||
3359 | - | |||||||||||||||||||||||||
3360 | qreal QTextDocumentLayoutPrivate::scaleToDevice(qreal value) const | - | ||||||||||||||||||||||||
3361 | { | - | ||||||||||||||||||||||||
3362 | if (!paintDevice)
| 0 | ||||||||||||||||||||||||
3363 | return value; never executed: return value; | 0 | ||||||||||||||||||||||||
3364 | return value * paintDevice->logicalDpiY() / qreal(qt_defaultDpi()); never executed: return value * paintDevice->logicalDpiY() / qreal(qt_defaultDpi()); | 0 | ||||||||||||||||||||||||
3365 | } | - | ||||||||||||||||||||||||
3366 | - | |||||||||||||||||||||||||
3367 | QFixed QTextDocumentLayoutPrivate::scaleToDevice(QFixed value) const | - | ||||||||||||||||||||||||
3368 | { | - | ||||||||||||||||||||||||
3369 | if (!paintDevice)
| 0 | ||||||||||||||||||||||||
3370 | return value; never executed: return value; | 0 | ||||||||||||||||||||||||
3371 | return value * QFixed(paintDevice->logicalDpiY()) / QFixed(qt_defaultDpi()); never executed: return value * QFixed(paintDevice->logicalDpiY()) / QFixed(qt_defaultDpi()); | 0 | ||||||||||||||||||||||||
3372 | } | - | ||||||||||||||||||||||||
3373 | - | |||||||||||||||||||||||||
3374 | QT_END_NAMESPACE | - | ||||||||||||||||||||||||
3375 | - | |||||||||||||||||||||||||
3376 | #include "moc_qtextdocumentlayout_p.cpp" | - | ||||||||||||||||||||||||
Source code | Switch to Preprocessed file |