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) 2015 The Qt Company Ltd. | - | ||||||||||||||||||||||||
4 | ** Contact: http://www.qt.io/licensing/ | - | ||||||||||||||||||||||||
5 | ** | - | ||||||||||||||||||||||||
6 | ** This file is part of the QtGui module of the Qt Toolkit. | - | ||||||||||||||||||||||||
7 | ** | - | ||||||||||||||||||||||||
8 | ** $QT_BEGIN_LICENSE:LGPL21$ | - | ||||||||||||||||||||||||
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 http://www.qt.io/terms-conditions. For further | - | ||||||||||||||||||||||||
15 | ** information use the contact form at http://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 2.1 or version 3 as published by the Free | - | ||||||||||||||||||||||||
20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and | - | ||||||||||||||||||||||||
21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the | - | ||||||||||||||||||||||||
22 | ** following information to ensure the GNU Lesser General Public License | - | ||||||||||||||||||||||||
23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and | - | ||||||||||||||||||||||||
24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | - | ||||||||||||||||||||||||
25 | ** | - | ||||||||||||||||||||||||
26 | ** As a special exception, The Qt Company gives you certain additional | - | ||||||||||||||||||||||||
27 | ** rights. These rights are described in The Qt Company LGPL Exception | - | ||||||||||||||||||||||||
28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | - | ||||||||||||||||||||||||
29 | ** | - | ||||||||||||||||||||||||
30 | ** $QT_END_LICENSE$ | - | ||||||||||||||||||||||||
31 | ** | - | ||||||||||||||||||||||||
32 | ****************************************************************************/ | - | ||||||||||||||||||||||||
33 | - | |||||||||||||||||||||||||
34 | #include "qtextdocumentlayout_p.h" | - | ||||||||||||||||||||||||
35 | #include "qtextdocument_p.h" | - | ||||||||||||||||||||||||
36 | #include "qtextimagehandler_p.h" | - | ||||||||||||||||||||||||
37 | #include "qtexttable.h" | - | ||||||||||||||||||||||||
38 | #include "qtextlist.h" | - | ||||||||||||||||||||||||
39 | #include "qtextengine_p.h" | - | ||||||||||||||||||||||||
40 | #include "private/qcssutil_p.h" | - | ||||||||||||||||||||||||
41 | #include "private/qguiapplication_p.h" | - | ||||||||||||||||||||||||
42 | - | |||||||||||||||||||||||||
43 | #include "qabstracttextdocumentlayout_p.h" | - | ||||||||||||||||||||||||
44 | #include "qcssparser_p.h" | - | ||||||||||||||||||||||||
45 | - | |||||||||||||||||||||||||
46 | #include <qpainter.h> | - | ||||||||||||||||||||||||
47 | #include <qmath.h> | - | ||||||||||||||||||||||||
48 | #include <qrect.h> | - | ||||||||||||||||||||||||
49 | #include <qpalette.h> | - | ||||||||||||||||||||||||
50 | #include <qdebug.h> | - | ||||||||||||||||||||||||
51 | #include <qvarlengtharray.h> | - | ||||||||||||||||||||||||
52 | #include <limits.h> | - | ||||||||||||||||||||||||
53 | #include <qbasictimer.h> | - | ||||||||||||||||||||||||
54 | #include "private/qfunctions_p.h" | - | ||||||||||||||||||||||||
55 | - | |||||||||||||||||||||||||
56 | #include <algorithm> | - | ||||||||||||||||||||||||
57 | - | |||||||||||||||||||||||||
58 | // #define LAYOUT_DEBUG | - | ||||||||||||||||||||||||
59 | - | |||||||||||||||||||||||||
60 | #ifdef LAYOUT_DEBUG | - | ||||||||||||||||||||||||
61 | #define LDEBUG qDebug() | - | ||||||||||||||||||||||||
62 | #define INC_INDENT debug_indent += " " | - | ||||||||||||||||||||||||
63 | #define DEC_INDENT debug_indent = debug_indent.left(debug_indent.length()-2) | - | ||||||||||||||||||||||||
64 | #else | - | ||||||||||||||||||||||||
65 | #define LDEBUG if(0) qDebug() | - | ||||||||||||||||||||||||
66 | #define INC_INDENT do {} while(0) | - | ||||||||||||||||||||||||
67 | #define DEC_INDENT do {} while(0) | - | ||||||||||||||||||||||||
68 | #endif | - | ||||||||||||||||||||||||
69 | - | |||||||||||||||||||||||||
70 | QT_BEGIN_NAMESPACE | - | ||||||||||||||||||||||||
71 | - | |||||||||||||||||||||||||
72 | // ################ should probably add frameFormatChange notification! | - | ||||||||||||||||||||||||
73 | - | |||||||||||||||||||||||||
74 | struct QTextLayoutStruct; | - | ||||||||||||||||||||||||
75 | - | |||||||||||||||||||||||||
76 | class QTextFrameData : public QTextFrameLayoutData | - | ||||||||||||||||||||||||
77 | { | - | ||||||||||||||||||||||||
78 | public: | - | ||||||||||||||||||||||||
79 | QTextFrameData(); | - | ||||||||||||||||||||||||
80 | - | |||||||||||||||||||||||||
81 | // relative to parent frame | - | ||||||||||||||||||||||||
82 | QFixedPoint position; | - | ||||||||||||||||||||||||
83 | QFixedSize size; | - | ||||||||||||||||||||||||
84 | - | |||||||||||||||||||||||||
85 | // contents starts at (margin+border/margin+border) | - | ||||||||||||||||||||||||
86 | QFixed topMargin; | - | ||||||||||||||||||||||||
87 | QFixed bottomMargin; | - | ||||||||||||||||||||||||
88 | QFixed leftMargin; | - | ||||||||||||||||||||||||
89 | QFixed rightMargin; | - | ||||||||||||||||||||||||
90 | QFixed border; | - | ||||||||||||||||||||||||
91 | QFixed padding; | - | ||||||||||||||||||||||||
92 | // contents width includes padding (as we need to treat this on a per cell basis for tables) | - | ||||||||||||||||||||||||
93 | QFixed contentsWidth; | - | ||||||||||||||||||||||||
94 | QFixed contentsHeight; | - | ||||||||||||||||||||||||
95 | QFixed oldContentsWidth; | - | ||||||||||||||||||||||||
96 | - | |||||||||||||||||||||||||
97 | // accumulated margins | - | ||||||||||||||||||||||||
98 | QFixed effectiveTopMargin; | - | ||||||||||||||||||||||||
99 | QFixed effectiveBottomMargin; | - | ||||||||||||||||||||||||
100 | - | |||||||||||||||||||||||||
101 | QFixed minimumWidth; | - | ||||||||||||||||||||||||
102 | QFixed maximumWidth; | - | ||||||||||||||||||||||||
103 | - | |||||||||||||||||||||||||
104 | QTextLayoutStruct *currentLayoutStruct; | - | ||||||||||||||||||||||||
105 | - | |||||||||||||||||||||||||
106 | bool sizeDirty; | - | ||||||||||||||||||||||||
107 | bool layoutDirty; | - | ||||||||||||||||||||||||
108 | - | |||||||||||||||||||||||||
109 | QVector<QPointer<QTextFrame> > floats; | - | ||||||||||||||||||||||||
110 | }; | - | ||||||||||||||||||||||||
111 | - | |||||||||||||||||||||||||
112 | QTextFrameData::QTextFrameData() | - | ||||||||||||||||||||||||
113 | : maximumWidth(QFIXED_MAX), | - | ||||||||||||||||||||||||
114 | currentLayoutStruct(0), sizeDirty(true), layoutDirty(true) | - | ||||||||||||||||||||||||
115 | { | - | ||||||||||||||||||||||||
116 | } never executed: end of block | 0 | ||||||||||||||||||||||||
117 | - | |||||||||||||||||||||||||
118 | struct QTextLayoutStruct { | - | ||||||||||||||||||||||||
119 | QTextLayoutStruct() : maximumWidth(QFIXED_MAX), fullLayout(false) | - | ||||||||||||||||||||||||
120 | {} never executed: end of block | 0 | ||||||||||||||||||||||||
121 | QTextFrame *frame; | - | ||||||||||||||||||||||||
122 | QFixed x_left; | - | ||||||||||||||||||||||||
123 | QFixed x_right; | - | ||||||||||||||||||||||||
124 | QFixed frameY; // absolute y position of the current frame | - | ||||||||||||||||||||||||
125 | QFixed y; // always relative to the current frame | - | ||||||||||||||||||||||||
126 | QFixed contentsWidth; | - | ||||||||||||||||||||||||
127 | QFixed minimumWidth; | - | ||||||||||||||||||||||||
128 | QFixed maximumWidth; | - | ||||||||||||||||||||||||
129 | bool fullLayout; | - | ||||||||||||||||||||||||
130 | QList<QTextFrame *> pendingFloats; | - | ||||||||||||||||||||||||
131 | QFixed pageHeight; | - | ||||||||||||||||||||||||
132 | QFixed pageBottom; | - | ||||||||||||||||||||||||
133 | QFixed pageTopMargin; | - | ||||||||||||||||||||||||
134 | QFixed pageBottomMargin; | - | ||||||||||||||||||||||||
135 | QRectF updateRect; | - | ||||||||||||||||||||||||
136 | QRectF updateRectForFloats; | - | ||||||||||||||||||||||||
137 | - | |||||||||||||||||||||||||
138 | inline void addUpdateRectForFloat(const QRectF &rect) { | - | ||||||||||||||||||||||||
139 | if (updateRectForFloats.isValid())
| 0 | ||||||||||||||||||||||||
140 | updateRectForFloats |= rect; never executed: updateRectForFloats |= rect; | 0 | ||||||||||||||||||||||||
141 | else | - | ||||||||||||||||||||||||
142 | updateRectForFloats = rect; never executed: updateRectForFloats = rect; | 0 | ||||||||||||||||||||||||
143 | } | - | ||||||||||||||||||||||||
144 | - | |||||||||||||||||||||||||
145 | inline QFixed absoluteY() const | - | ||||||||||||||||||||||||
146 | { return frameY + y; } never executed: return frameY + y; | 0 | ||||||||||||||||||||||||
147 | - | |||||||||||||||||||||||||
148 | inline int currentPage() const | - | ||||||||||||||||||||||||
149 | { return pageHeight == 0 ? 0 : (absoluteY() / pageHeight).truncate(); } never executed: return pageHeight == 0 ? 0 : (absoluteY() / pageHeight).truncate();
| 0 | ||||||||||||||||||||||||
150 | - | |||||||||||||||||||||||||
151 | inline void newPage() | - | ||||||||||||||||||||||||
152 | { if (pageHeight == QFIXED_MAX) return; pageBottom += pageHeight; y = pageBottom - pageHeight + pageBottomMargin + pageTopMargin - frameY; } never executed: return; never executed: end of block
| 0 | ||||||||||||||||||||||||
153 | }; | - | ||||||||||||||||||||||||
154 | - | |||||||||||||||||||||||||
155 | class QTextTableData : public QTextFrameData | - | ||||||||||||||||||||||||
156 | { | - | ||||||||||||||||||||||||
157 | public: | - | ||||||||||||||||||||||||
158 | QFixed cellSpacing, cellPadding; | - | ||||||||||||||||||||||||
159 | qreal deviceScale; | - | ||||||||||||||||||||||||
160 | QVector<QFixed> minWidths; | - | ||||||||||||||||||||||||
161 | QVector<QFixed> maxWidths; | - | ||||||||||||||||||||||||
162 | QVector<QFixed> widths; | - | ||||||||||||||||||||||||
163 | QVector<QFixed> heights; | - | ||||||||||||||||||||||||
164 | QVector<QFixed> columnPositions; | - | ||||||||||||||||||||||||
165 | QVector<QFixed> rowPositions; | - | ||||||||||||||||||||||||
166 | - | |||||||||||||||||||||||||
167 | QVector<QFixed> cellVerticalOffsets; | - | ||||||||||||||||||||||||
168 | - | |||||||||||||||||||||||||
169 | QFixed headerHeight; | - | ||||||||||||||||||||||||
170 | - | |||||||||||||||||||||||||
171 | // maps from cell index (row + col * rowCount) to child frames belonging to | - | ||||||||||||||||||||||||
172 | // the specific cell | - | ||||||||||||||||||||||||
173 | QMultiHash<int, QTextFrame *> childFrameMap; | - | ||||||||||||||||||||||||
174 | - | |||||||||||||||||||||||||
175 | inline QFixed cellWidth(int column, int colspan) const | - | ||||||||||||||||||||||||
176 | { 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 | ||||||||||||||||||||||||
177 | - columnPositions.at(column); } never executed: return columnPositions.at(column + colspan - 1) + widths.at(column + colspan - 1) - columnPositions.at(column); | 0 | ||||||||||||||||||||||||
178 | - | |||||||||||||||||||||||||
179 | inline void calcRowPosition(int row) | - | ||||||||||||||||||||||||
180 | { | - | ||||||||||||||||||||||||
181 | if (row > 0)
| 0 | ||||||||||||||||||||||||
182 | 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 | ||||||||||||||||||||||||
183 | } never executed: end of block | 0 | ||||||||||||||||||||||||
184 | - | |||||||||||||||||||||||||
185 | QRectF cellRect(const QTextTableCell &cell) const; | - | ||||||||||||||||||||||||
186 | - | |||||||||||||||||||||||||
187 | inline QFixed paddingProperty(const QTextFormat &format, QTextFormat::Property property) const | - | ||||||||||||||||||||||||
188 | { | - | ||||||||||||||||||||||||
189 | QVariant v = format.property(property); | - | ||||||||||||||||||||||||
190 | if (v.isNull()) {
| 0 | ||||||||||||||||||||||||
191 | return cellPadding; never executed: return cellPadding; | 0 | ||||||||||||||||||||||||
192 | } else { | - | ||||||||||||||||||||||||
193 | Q_ASSERT(v.userType() == QVariant::Double || v.userType() == QMetaType::Float); | - | ||||||||||||||||||||||||
194 | return QFixed::fromReal(v.toReal() * deviceScale); never executed: return QFixed::fromReal(v.toReal() * deviceScale); | 0 | ||||||||||||||||||||||||
195 | } | - | ||||||||||||||||||||||||
196 | } | - | ||||||||||||||||||||||||
197 | - | |||||||||||||||||||||||||
198 | inline QFixed topPadding(const QTextFormat &format) const | - | ||||||||||||||||||||||||
199 | { | - | ||||||||||||||||||||||||
200 | return paddingProperty(format, QTextFormat::TableCellTopPadding); never executed: return paddingProperty(format, QTextFormat::TableCellTopPadding); | 0 | ||||||||||||||||||||||||
201 | } | - | ||||||||||||||||||||||||
202 | - | |||||||||||||||||||||||||
203 | inline QFixed bottomPadding(const QTextFormat &format) const | - | ||||||||||||||||||||||||
204 | { | - | ||||||||||||||||||||||||
205 | return paddingProperty(format, QTextFormat::TableCellBottomPadding); never executed: return paddingProperty(format, QTextFormat::TableCellBottomPadding); | 0 | ||||||||||||||||||||||||
206 | } | - | ||||||||||||||||||||||||
207 | - | |||||||||||||||||||||||||
208 | inline QFixed leftPadding(const QTextFormat &format) const | - | ||||||||||||||||||||||||
209 | { | - | ||||||||||||||||||||||||
210 | return paddingProperty(format, QTextFormat::TableCellLeftPadding); never executed: return paddingProperty(format, QTextFormat::TableCellLeftPadding); | 0 | ||||||||||||||||||||||||
211 | } | - | ||||||||||||||||||||||||
212 | - | |||||||||||||||||||||||||
213 | inline QFixed rightPadding(const QTextFormat &format) const | - | ||||||||||||||||||||||||
214 | { | - | ||||||||||||||||||||||||
215 | return paddingProperty(format, QTextFormat::TableCellRightPadding); never executed: return paddingProperty(format, QTextFormat::TableCellRightPadding); | 0 | ||||||||||||||||||||||||
216 | } | - | ||||||||||||||||||||||||
217 | - | |||||||||||||||||||||||||
218 | inline QFixedPoint cellPosition(const QTextTableCell &cell) const | - | ||||||||||||||||||||||||
219 | { | - | ||||||||||||||||||||||||
220 | const QTextFormat fmt = cell.format(); | - | ||||||||||||||||||||||||
221 | 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 | ||||||||||||||||||||||||
222 | } | - | ||||||||||||||||||||||||
223 | - | |||||||||||||||||||||||||
224 | void updateTableSize(); | - | ||||||||||||||||||||||||
225 | - | |||||||||||||||||||||||||
226 | private: | - | ||||||||||||||||||||||||
227 | inline QFixedPoint cellPosition(int row, int col) const | - | ||||||||||||||||||||||||
228 | { 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 | ||||||||||||||||||||||||
229 | }; | - | ||||||||||||||||||||||||
230 | - | |||||||||||||||||||||||||
231 | static QTextFrameData *createData(QTextFrame *f) | - | ||||||||||||||||||||||||
232 | { | - | ||||||||||||||||||||||||
233 | QTextFrameData *data; | - | ||||||||||||||||||||||||
234 | if (qobject_cast<QTextTable *>(f))
| 0 | ||||||||||||||||||||||||
235 | data = new QTextTableData; never executed: data = new QTextTableData; | 0 | ||||||||||||||||||||||||
236 | else | - | ||||||||||||||||||||||||
237 | data = new QTextFrameData; never executed: data = new QTextFrameData; | 0 | ||||||||||||||||||||||||
238 | f->setLayoutData(data); | - | ||||||||||||||||||||||||
239 | return data; never executed: return data; | 0 | ||||||||||||||||||||||||
240 | } | - | ||||||||||||||||||||||||
241 | - | |||||||||||||||||||||||||
242 | static inline QTextFrameData *data(QTextFrame *f) | - | ||||||||||||||||||||||||
243 | { | - | ||||||||||||||||||||||||
244 | QTextFrameData *data = static_cast<QTextFrameData *>(f->layoutData()); | - | ||||||||||||||||||||||||
245 | if (!data)
| 0 | ||||||||||||||||||||||||
246 | data = createData(f); never executed: data = createData(f); | 0 | ||||||||||||||||||||||||
247 | return data; never executed: return data; | 0 | ||||||||||||||||||||||||
248 | } | - | ||||||||||||||||||||||||
249 | - | |||||||||||||||||||||||||
250 | static bool isFrameFromInlineObject(QTextFrame *f) | - | ||||||||||||||||||||||||
251 | { | - | ||||||||||||||||||||||||
252 | return f->firstPosition() > f->lastPosition(); never executed: return f->firstPosition() > f->lastPosition(); | 0 | ||||||||||||||||||||||||
253 | } | - | ||||||||||||||||||||||||
254 | - | |||||||||||||||||||||||||
255 | void QTextTableData::updateTableSize() | - | ||||||||||||||||||||||||
256 | { | - | ||||||||||||||||||||||||
257 | const QFixed effectiveTopMargin = this->topMargin + border + padding; | - | ||||||||||||||||||||||||
258 | const QFixed effectiveBottomMargin = this->bottomMargin + border + padding; | - | ||||||||||||||||||||||||
259 | const QFixed effectiveLeftMargin = this->leftMargin + border + padding; | - | ||||||||||||||||||||||||
260 | const QFixed effectiveRightMargin = this->rightMargin + border + padding; | - | ||||||||||||||||||||||||
261 | size.height = contentsHeight == -1
| 0 | ||||||||||||||||||||||||
262 | ? rowPositions.last() + heights.last() + padding + border + cellSpacing + effectiveBottomMargin | - | ||||||||||||||||||||||||
263 | : effectiveTopMargin + contentsHeight + effectiveBottomMargin; | - | ||||||||||||||||||||||||
264 | size.width = effectiveLeftMargin + contentsWidth + effectiveRightMargin; | - | ||||||||||||||||||||||||
265 | } never executed: end of block | 0 | ||||||||||||||||||||||||
266 | - | |||||||||||||||||||||||||
267 | QRectF QTextTableData::cellRect(const QTextTableCell &cell) const | - | ||||||||||||||||||||||||
268 | { | - | ||||||||||||||||||||||||
269 | const int row = cell.row(); | - | ||||||||||||||||||||||||
270 | const int rowSpan = cell.rowSpan(); | - | ||||||||||||||||||||||||
271 | const int column = cell.column(); | - | ||||||||||||||||||||||||
272 | const int colSpan = cell.columnSpan(); | - | ||||||||||||||||||||||||
273 | - | |||||||||||||||||||||||||
274 | 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 | ||||||||||||||||||||||||
275 | 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 | ||||||||||||||||||||||||
276 | (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 | ||||||||||||||||||||||||
277 | (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 | ||||||||||||||||||||||||
278 | } | - | ||||||||||||||||||||||||
279 | - | |||||||||||||||||||||||||
280 | static inline bool isEmptyBlockBeforeTable(const QTextBlock &block, const QTextBlockFormat &format, const QTextFrame::Iterator &nextIt) | - | ||||||||||||||||||||||||
281 | { | - | ||||||||||||||||||||||||
282 | 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 | ||||||||||||||||||||||||
283 | && 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 | ||||||||||||||||||||||||
284 | && 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 | ||||||||||||||||||||||||
285 | && 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 | ||||||||||||||||||||||||
286 | && !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 | ||||||||||||||||||||||||
287 | && !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 | ||||||||||||||||||||||||
288 | && 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 | ||||||||||||||||||||||||
289 | ; 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 | } | - | ||||||||||||||||||||||||
291 | - | |||||||||||||||||||||||||
292 | static inline bool isEmptyBlockBeforeTable(QTextFrame::Iterator it) | - | ||||||||||||||||||||||||
293 | { | - | ||||||||||||||||||||||||
294 | QTextFrame::Iterator next = it; ++next; | - | ||||||||||||||||||||||||
295 | if (it.currentFrame())
| 0 | ||||||||||||||||||||||||
296 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||
297 | QTextBlock block = it.currentBlock(); | - | ||||||||||||||||||||||||
298 | return isEmptyBlockBeforeTable(block, block.blockFormat(), next); never executed: return isEmptyBlockBeforeTable(block, block.blockFormat(), next); | 0 | ||||||||||||||||||||||||
299 | } | - | ||||||||||||||||||||||||
300 | - | |||||||||||||||||||||||||
301 | static inline bool isEmptyBlockAfterTable(const QTextBlock &block, const QTextFrame *previousFrame) | - | ||||||||||||||||||||||||
302 | { | - | ||||||||||||||||||||||||
303 | 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 | ||||||||||||||||||||||||
304 | && block.isValid() never executed: return qobject_cast<const QTextTable *>(previousFrame) && block.isValid() && block.length() == 1 && previousFrame->lastPosition() == block.position() - 1 ;
| 0 | ||||||||||||||||||||||||
305 | && block.length() == 1 never executed: return qobject_cast<const QTextTable *>(previousFrame) && block.isValid() && block.length() == 1 && previousFrame->lastPosition() == block.position() - 1 ;
| 0 | ||||||||||||||||||||||||
306 | && previousFrame->lastPosition() == block.position() - 1 never executed: return qobject_cast<const QTextTable *>(previousFrame) && block.isValid() && block.length() == 1 && previousFrame->lastPosition() == block.position() - 1 ;
| 0 | ||||||||||||||||||||||||
307 | ; never executed: return qobject_cast<const QTextTable *>(previousFrame) && block.isValid() && block.length() == 1 && previousFrame->lastPosition() == block.position() - 1 ; | 0 | ||||||||||||||||||||||||
308 | } | - | ||||||||||||||||||||||||
309 | - | |||||||||||||||||||||||||
310 | static inline bool isLineSeparatorBlockAfterTable(const QTextBlock &block, const QTextFrame *previousFrame) | - | ||||||||||||||||||||||||
311 | { | - | ||||||||||||||||||||||||
312 | 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 | ||||||||||||||||||||||||
313 | && 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 | ||||||||||||||||||||||||
314 | && 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 | ||||||||||||||||||||||||
315 | && 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 | ||||||||||||||||||||||||
316 | && 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 | ||||||||||||||||||||||||
317 | ; 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 | ||||||||||||||||||||||||
318 | } | - | ||||||||||||||||||||||||
319 | - | |||||||||||||||||||||||||
320 | /* | - | ||||||||||||||||||||||||
321 | - | |||||||||||||||||||||||||
322 | Optimization strategies: | - | ||||||||||||||||||||||||
323 | - | |||||||||||||||||||||||||
324 | HTML layout: | - | ||||||||||||||||||||||||
325 | - | |||||||||||||||||||||||||
326 | * Distinguish between normal and special flow. For normal flow the condition: | - | ||||||||||||||||||||||||
327 | y1 > y2 holds for all blocks with b1.key() > b2.key(). | - | ||||||||||||||||||||||||
328 | * Special flow is: floats, table cells | - | ||||||||||||||||||||||||
329 | - | |||||||||||||||||||||||||
330 | * Normal flow within table cells. Tables (not cells) are part of the normal flow. | - | ||||||||||||||||||||||||
331 | - | |||||||||||||||||||||||||
332 | - | |||||||||||||||||||||||||
333 | * If blocks grows/shrinks in height and extends over whole page width at the end, move following blocks. | - | ||||||||||||||||||||||||
334 | * If height doesn't change, no need to do anything | - | ||||||||||||||||||||||||
335 | - | |||||||||||||||||||||||||
336 | Table cells: | - | ||||||||||||||||||||||||
337 | - | |||||||||||||||||||||||||
338 | * If minWidth of cell changes, recalculate table width, relayout if needed. | - | ||||||||||||||||||||||||
339 | * What about maxWidth when doing auto layout? | - | ||||||||||||||||||||||||
340 | - | |||||||||||||||||||||||||
341 | Floats: | - | ||||||||||||||||||||||||
342 | * need fixed or proportional width, otherwise don't float! | - | ||||||||||||||||||||||||
343 | * On width/height change relayout surrounding paragraphs. | - | ||||||||||||||||||||||||
344 | - | |||||||||||||||||||||||||
345 | Document width change: | - | ||||||||||||||||||||||||
346 | * full relayout needed | - | ||||||||||||||||||||||||
347 | - | |||||||||||||||||||||||||
348 | - | |||||||||||||||||||||||||
349 | Float handling: | - | ||||||||||||||||||||||||
350 | - | |||||||||||||||||||||||||
351 | * Floats are specified by a special format object. | - | ||||||||||||||||||||||||
352 | * currently only floating images are implemented. | - | ||||||||||||||||||||||||
353 | - | |||||||||||||||||||||||||
354 | */ | - | ||||||||||||||||||||||||
355 | - | |||||||||||||||||||||||||
356 | /* | - | ||||||||||||||||||||||||
357 | - | |||||||||||||||||||||||||
358 | On the table layouting: | - | ||||||||||||||||||||||||
359 | - | |||||||||||||||||||||||||
360 | +---[ table border ]------------------------- | - | ||||||||||||||||||||||||
361 | | [ cell spacing ] | - | ||||||||||||||||||||||||
362 | | +------[ cell border ]-----+ +-------- | - | ||||||||||||||||||||||||
363 | | | | | | - | ||||||||||||||||||||||||
364 | | | | - | ||||||||||||||||||||||||
365 | | | | - | ||||||||||||||||||||||||
366 | | | | - | ||||||||||||||||||||||||
367 | | | - | ||||||||||||||||||||||||
368 | - | |||||||||||||||||||||||||
369 | rowPositions[i] and columnPositions[i] point at the cell content | - | ||||||||||||||||||||||||
370 | position. So for example the left border is drawn at | - | ||||||||||||||||||||||||
371 | x = columnPositions[i] - fd->border and similar for y. | - | ||||||||||||||||||||||||
372 | - | |||||||||||||||||||||||||
373 | */ | - | ||||||||||||||||||||||||
374 | - | |||||||||||||||||||||||||
375 | struct QCheckPoint | - | ||||||||||||||||||||||||
376 | { | - | ||||||||||||||||||||||||
377 | QFixed y; | - | ||||||||||||||||||||||||
378 | QFixed frameY; // absolute y position of the current frame | - | ||||||||||||||||||||||||
379 | int positionInFrame; | - | ||||||||||||||||||||||||
380 | QFixed minimumWidth; | - | ||||||||||||||||||||||||
381 | QFixed maximumWidth; | - | ||||||||||||||||||||||||
382 | QFixed contentsWidth; | - | ||||||||||||||||||||||||
383 | }; | - | ||||||||||||||||||||||||
384 | Q_DECLARE_TYPEINFO(QCheckPoint, Q_PRIMITIVE_TYPE); | - | ||||||||||||||||||||||||
385 | - | |||||||||||||||||||||||||
386 | static bool operator<(const QCheckPoint &checkPoint, QFixed y) | - | ||||||||||||||||||||||||
387 | { | - | ||||||||||||||||||||||||
388 | return checkPoint.y < y; never executed: return checkPoint.y < y; | 0 | ||||||||||||||||||||||||
389 | } | - | ||||||||||||||||||||||||
390 | - | |||||||||||||||||||||||||
391 | static bool operator<(const QCheckPoint &checkPoint, int pos) | - | ||||||||||||||||||||||||
392 | { | - | ||||||||||||||||||||||||
393 | return checkPoint.positionInFrame < pos; never executed: return checkPoint.positionInFrame < pos; | 0 | ||||||||||||||||||||||||
394 | } | - | ||||||||||||||||||||||||
395 | - | |||||||||||||||||||||||||
396 | #if defined(Q_CC_MSVC) && _MSC_VER < 1600 | - | ||||||||||||||||||||||||
397 | //The STL implementation of MSVC 2008 requires the definitions | - | ||||||||||||||||||||||||
398 | - | |||||||||||||||||||||||||
399 | static bool operator<(const QCheckPoint &checkPoint1, const QCheckPoint &checkPoint2) | - | ||||||||||||||||||||||||
400 | { | - | ||||||||||||||||||||||||
401 | return checkPoint1.y < checkPoint2.y; | - | ||||||||||||||||||||||||
402 | } | - | ||||||||||||||||||||||||
403 | - | |||||||||||||||||||||||||
404 | static bool operator<(QFixed y, const QCheckPoint &checkPoint) | - | ||||||||||||||||||||||||
405 | { | - | ||||||||||||||||||||||||
406 | return y < checkPoint.y; | - | ||||||||||||||||||||||||
407 | } | - | ||||||||||||||||||||||||
408 | - | |||||||||||||||||||||||||
409 | static bool operator<(int pos, const QCheckPoint &checkPoint) | - | ||||||||||||||||||||||||
410 | { | - | ||||||||||||||||||||||||
411 | return pos < checkPoint.positionInFrame; | - | ||||||||||||||||||||||||
412 | } | - | ||||||||||||||||||||||||
413 | - | |||||||||||||||||||||||||
414 | #endif | - | ||||||||||||||||||||||||
415 | - | |||||||||||||||||||||||||
416 | static void fillBackground(QPainter *p, const QRectF &rect, QBrush brush, const QPointF &origin, QRectF gradientRect = QRectF()) | - | ||||||||||||||||||||||||
417 | { | - | ||||||||||||||||||||||||
418 | p->save(); | - | ||||||||||||||||||||||||
419 | if (brush.style() >= Qt::LinearGradientPattern && brush.style() <= Qt::ConicalGradientPattern) {
| 0 | ||||||||||||||||||||||||
420 | if (!gradientRect.isNull()) {
| 0 | ||||||||||||||||||||||||
421 | QTransform m; | - | ||||||||||||||||||||||||
422 | m.translate(gradientRect.left(), gradientRect.top()); | - | ||||||||||||||||||||||||
423 | m.scale(gradientRect.width(), gradientRect.height()); | - | ||||||||||||||||||||||||
424 | brush.setTransform(m); | - | ||||||||||||||||||||||||
425 | const_cast<QGradient *>(brush.gradient())->setCoordinateMode(QGradient::LogicalMode); | - | ||||||||||||||||||||||||
426 | } never executed: end of block | 0 | ||||||||||||||||||||||||
427 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
428 | p->setBrushOrigin(origin); | - | ||||||||||||||||||||||||
429 | } never executed: end of block | 0 | ||||||||||||||||||||||||
430 | p->fillRect(rect, brush); | - | ||||||||||||||||||||||||
431 | p->restore(); | - | ||||||||||||||||||||||||
432 | } never executed: end of block | 0 | ||||||||||||||||||||||||
433 | - | |||||||||||||||||||||||||
434 | class QTextDocumentLayoutPrivate : public QAbstractTextDocumentLayoutPrivate | - | ||||||||||||||||||||||||
435 | { | - | ||||||||||||||||||||||||
436 | Q_DECLARE_PUBLIC(QTextDocumentLayout) | - | ||||||||||||||||||||||||
437 | public: | - | ||||||||||||||||||||||||
438 | QTextDocumentLayoutPrivate(); | - | ||||||||||||||||||||||||
439 | - | |||||||||||||||||||||||||
440 | QTextOption::WrapMode wordWrapMode; | - | ||||||||||||||||||||||||
441 | #ifdef LAYOUT_DEBUG | - | ||||||||||||||||||||||||
442 | mutable QString debug_indent; | - | ||||||||||||||||||||||||
443 | #endif | - | ||||||||||||||||||||||||
444 | - | |||||||||||||||||||||||||
445 | int fixedColumnWidth; | - | ||||||||||||||||||||||||
446 | int cursorWidth; | - | ||||||||||||||||||||||||
447 | - | |||||||||||||||||||||||||
448 | QSizeF lastReportedSize; | - | ||||||||||||||||||||||||
449 | QRectF viewportRect; | - | ||||||||||||||||||||||||
450 | QRectF clipRect; | - | ||||||||||||||||||||||||
451 | - | |||||||||||||||||||||||||
452 | mutable int currentLazyLayoutPosition; | - | ||||||||||||||||||||||||
453 | mutable int lazyLayoutStepSize; | - | ||||||||||||||||||||||||
454 | QBasicTimer layoutTimer; | - | ||||||||||||||||||||||||
455 | mutable QBasicTimer sizeChangedTimer; | - | ||||||||||||||||||||||||
456 | uint showLayoutProgress : 1; | - | ||||||||||||||||||||||||
457 | uint insideDocumentChange : 1; | - | ||||||||||||||||||||||||
458 | - | |||||||||||||||||||||||||
459 | int lastPageCount; | - | ||||||||||||||||||||||||
460 | qreal idealWidth; | - | ||||||||||||||||||||||||
461 | bool contentHasAlignment; | - | ||||||||||||||||||||||||
462 | - | |||||||||||||||||||||||||
463 | QFixed blockIndent(const QTextBlockFormat &blockFormat) const; | - | ||||||||||||||||||||||||
464 | - | |||||||||||||||||||||||||
465 | void drawFrame(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context, | - | ||||||||||||||||||||||||
466 | QTextFrame *f) const; | - | ||||||||||||||||||||||||
467 | void drawFlow(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context, | - | ||||||||||||||||||||||||
468 | QTextFrame::Iterator it, const QList<QTextFrame *> &floats, QTextBlock *cursorBlockNeedingRepaint) const; | - | ||||||||||||||||||||||||
469 | void drawBlock(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context, | - | ||||||||||||||||||||||||
470 | const QTextBlock &bl, bool inRootFrame) const; | - | ||||||||||||||||||||||||
471 | void drawListItem(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context, | - | ||||||||||||||||||||||||
472 | const QTextBlock &bl, const QTextCharFormat *selectionFormat) const; | - | ||||||||||||||||||||||||
473 | void drawTableCell(const QRectF &cellRect, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &cell_context, | - | ||||||||||||||||||||||||
474 | QTextTable *table, QTextTableData *td, int r, int c, | - | ||||||||||||||||||||||||
475 | QTextBlock *cursorBlockNeedingRepaint, QPointF *cursorBlockOffset) const; | - | ||||||||||||||||||||||||
476 | void drawBorder(QPainter *painter, const QRectF &rect, qreal topMargin, qreal bottomMargin, qreal border, | - | ||||||||||||||||||||||||
477 | const QBrush &brush, QTextFrameFormat::BorderStyle style) const; | - | ||||||||||||||||||||||||
478 | void drawFrameDecoration(QPainter *painter, QTextFrame *frame, QTextFrameData *fd, const QRectF &clip, const QRectF &rect) const; | - | ||||||||||||||||||||||||
479 | - | |||||||||||||||||||||||||
480 | enum HitPoint { | - | ||||||||||||||||||||||||
481 | PointBefore, | - | ||||||||||||||||||||||||
482 | PointAfter, | - | ||||||||||||||||||||||||
483 | PointInside, | - | ||||||||||||||||||||||||
484 | PointExact | - | ||||||||||||||||||||||||
485 | }; | - | ||||||||||||||||||||||||
486 | HitPoint hitTest(QTextFrame *frame, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; | - | ||||||||||||||||||||||||
487 | HitPoint hitTest(QTextFrame::Iterator it, HitPoint hit, const QFixedPoint &p, | - | ||||||||||||||||||||||||
488 | int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; | - | ||||||||||||||||||||||||
489 | HitPoint hitTest(QTextTable *table, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; | - | ||||||||||||||||||||||||
490 | HitPoint hitTest(const QTextBlock &bl, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; | - | ||||||||||||||||||||||||
491 | - | |||||||||||||||||||||||||
492 | QTextLayoutStruct layoutCell(QTextTable *t, const QTextTableCell &cell, QFixed width, | - | ||||||||||||||||||||||||
493 | int layoutFrom, int layoutTo, QTextTableData *tableData, QFixed absoluteTableY, | - | ||||||||||||||||||||||||
494 | bool withPageBreaks); | - | ||||||||||||||||||||||||
495 | void setCellPosition(QTextTable *t, const QTextTableCell &cell, const QPointF &pos); | - | ||||||||||||||||||||||||
496 | QRectF layoutTable(QTextTable *t, int layoutFrom, int layoutTo, QFixed parentY); | - | ||||||||||||||||||||||||
497 | - | |||||||||||||||||||||||||
498 | void positionFloat(QTextFrame *frame, QTextLine *currentLine = 0); | - | ||||||||||||||||||||||||
499 | - | |||||||||||||||||||||||||
500 | // calls the next one | - | ||||||||||||||||||||||||
501 | QRectF layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed parentY = 0); | - | ||||||||||||||||||||||||
502 | QRectF layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed frameWidth, QFixed frameHeight, QFixed parentY = 0); | - | ||||||||||||||||||||||||
503 | - | |||||||||||||||||||||||||
504 | void layoutBlock(const QTextBlock &bl, int blockPosition, const QTextBlockFormat &blockFormat, | - | ||||||||||||||||||||||||
505 | QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, const QTextBlockFormat *previousBlockFormat); | - | ||||||||||||||||||||||||
506 | void layoutFlow(QTextFrame::Iterator it, QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, QFixed width = 0); | - | ||||||||||||||||||||||||
507 | - | |||||||||||||||||||||||||
508 | void floatMargins(const QFixed &y, const QTextLayoutStruct *layoutStruct, QFixed *left, QFixed *right) const; | - | ||||||||||||||||||||||||
509 | QFixed findY(QFixed yFrom, const QTextLayoutStruct *layoutStruct, QFixed requiredWidth) const; | - | ||||||||||||||||||||||||
510 | - | |||||||||||||||||||||||||
511 | QVector<QCheckPoint> checkPoints; | - | ||||||||||||||||||||||||
512 | - | |||||||||||||||||||||||||
513 | QTextFrame::Iterator frameIteratorForYPosition(QFixed y) const; | - | ||||||||||||||||||||||||
514 | QTextFrame::Iterator frameIteratorForTextPosition(int position) const; | - | ||||||||||||||||||||||||
515 | - | |||||||||||||||||||||||||
516 | void ensureLayouted(QFixed y) const; | - | ||||||||||||||||||||||||
517 | void ensureLayoutedByPosition(int position) const; | - | ||||||||||||||||||||||||
518 | inline void ensureLayoutFinished() const | - | ||||||||||||||||||||||||
519 | { ensureLayoutedByPosition(INT_MAX); } never executed: end of block | 0 | ||||||||||||||||||||||||
520 | void layoutStep() const; | - | ||||||||||||||||||||||||
521 | - | |||||||||||||||||||||||||
522 | QRectF frameBoundingRectInternal(QTextFrame *frame) const; | - | ||||||||||||||||||||||||
523 | - | |||||||||||||||||||||||||
524 | qreal scaleToDevice(qreal value) const; | - | ||||||||||||||||||||||||
525 | QFixed scaleToDevice(QFixed value) const; | - | ||||||||||||||||||||||||
526 | }; | - | ||||||||||||||||||||||||
527 | - | |||||||||||||||||||||||||
528 | QTextDocumentLayoutPrivate::QTextDocumentLayoutPrivate() | - | ||||||||||||||||||||||||
529 | : fixedColumnWidth(-1), | - | ||||||||||||||||||||||||
530 | cursorWidth(1), | - | ||||||||||||||||||||||||
531 | currentLazyLayoutPosition(-1), | - | ||||||||||||||||||||||||
532 | lazyLayoutStepSize(1000), | - | ||||||||||||||||||||||||
533 | lastPageCount(-1) | - | ||||||||||||||||||||||||
534 | { | - | ||||||||||||||||||||||||
535 | showLayoutProgress = true; | - | ||||||||||||||||||||||||
536 | insideDocumentChange = false; | - | ||||||||||||||||||||||||
537 | idealWidth = 0; | - | ||||||||||||||||||||||||
538 | contentHasAlignment = false; | - | ||||||||||||||||||||||||
539 | } never executed: end of block | 0 | ||||||||||||||||||||||||
540 | - | |||||||||||||||||||||||||
541 | QTextFrame::Iterator QTextDocumentLayoutPrivate::frameIteratorForYPosition(QFixed y) const | - | ||||||||||||||||||||||||
542 | { | - | ||||||||||||||||||||||||
543 | QTextFrame *rootFrame = document->rootFrame(); | - | ||||||||||||||||||||||||
544 | - | |||||||||||||||||||||||||
545 | if (checkPoints.isEmpty()
| 0 | ||||||||||||||||||||||||
546 | || y < 0 || y > data(rootFrame)->size.height)
| 0 | ||||||||||||||||||||||||
547 | return rootFrame->begin(); never executed: return rootFrame->begin(); | 0 | ||||||||||||||||||||||||
548 | - | |||||||||||||||||||||||||
549 | QVector<QCheckPoint>::ConstIterator checkPoint = std::lower_bound(checkPoints.begin(), checkPoints.end(), y); | - | ||||||||||||||||||||||||
550 | if (checkPoint == checkPoints.end())
| 0 | ||||||||||||||||||||||||
551 | return rootFrame->begin(); never executed: return rootFrame->begin(); | 0 | ||||||||||||||||||||||||
552 | - | |||||||||||||||||||||||||
553 | if (checkPoint != checkPoints.begin())
| 0 | ||||||||||||||||||||||||
554 | --checkPoint; never executed: --checkPoint; | 0 | ||||||||||||||||||||||||
555 | - | |||||||||||||||||||||||||
556 | const int position = rootFrame->firstPosition() + checkPoint->positionInFrame; | - | ||||||||||||||||||||||||
557 | return frameIteratorForTextPosition(position); never executed: return frameIteratorForTextPosition(position); | 0 | ||||||||||||||||||||||||
558 | } | - | ||||||||||||||||||||||||
559 | - | |||||||||||||||||||||||||
560 | QTextFrame::Iterator QTextDocumentLayoutPrivate::frameIteratorForTextPosition(int position) const | - | ||||||||||||||||||||||||
561 | { | - | ||||||||||||||||||||||||
562 | QTextFrame *rootFrame = docPrivate->rootFrame(); | - | ||||||||||||||||||||||||
563 | - | |||||||||||||||||||||||||
564 | const QTextDocumentPrivate::BlockMap &map = docPrivate->blockMap(); | - | ||||||||||||||||||||||||
565 | const int begin = map.findNode(rootFrame->firstPosition()); | - | ||||||||||||||||||||||||
566 | const int end = map.findNode(rootFrame->lastPosition()+1); | - | ||||||||||||||||||||||||
567 | - | |||||||||||||||||||||||||
568 | const int block = map.findNode(position); | - | ||||||||||||||||||||||||
569 | const int blockPos = map.position(block); | - | ||||||||||||||||||||||||
570 | - | |||||||||||||||||||||||||
571 | QTextFrame::iterator it(rootFrame, block, begin, end); | - | ||||||||||||||||||||||||
572 | - | |||||||||||||||||||||||||
573 | QTextFrame *containingFrame = docPrivate->frameAt(blockPos); | - | ||||||||||||||||||||||||
574 | if (containingFrame != rootFrame) {
| 0 | ||||||||||||||||||||||||
575 | while (containingFrame->parentFrame() != rootFrame) {
| 0 | ||||||||||||||||||||||||
576 | containingFrame = containingFrame->parentFrame(); | - | ||||||||||||||||||||||||
577 | Q_ASSERT(containingFrame); | - | ||||||||||||||||||||||||
578 | } never executed: end of block | 0 | ||||||||||||||||||||||||
579 | - | |||||||||||||||||||||||||
580 | it.cf = containingFrame; | - | ||||||||||||||||||||||||
581 | it.cb = 0; | - | ||||||||||||||||||||||||
582 | } never executed: end of block | 0 | ||||||||||||||||||||||||
583 | - | |||||||||||||||||||||||||
584 | return it; never executed: return it; | 0 | ||||||||||||||||||||||||
585 | } | - | ||||||||||||||||||||||||
586 | - | |||||||||||||||||||||||||
587 | QTextDocumentLayoutPrivate::HitPoint | - | ||||||||||||||||||||||||
588 | QTextDocumentLayoutPrivate::hitTest(QTextFrame *frame, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const | - | ||||||||||||||||||||||||
589 | { | - | ||||||||||||||||||||||||
590 | QTextFrameData *fd = data(frame); | - | ||||||||||||||||||||||||
591 | // ######### | - | ||||||||||||||||||||||||
592 | if (fd->layoutDirty)
| 0 | ||||||||||||||||||||||||
593 | return PointAfter; never executed: return PointAfter; | 0 | ||||||||||||||||||||||||
594 | Q_ASSERT(!fd->layoutDirty); | - | ||||||||||||||||||||||||
595 | Q_ASSERT(!fd->sizeDirty); | - | ||||||||||||||||||||||||
596 | const QFixedPoint relativePoint(point.x - fd->position.x, point.y - fd->position.y); | - | ||||||||||||||||||||||||
597 | - | |||||||||||||||||||||||||
598 | QTextFrame *rootFrame = docPrivate->rootFrame(); | - | ||||||||||||||||||||||||
599 | - | |||||||||||||||||||||||||
600 | // LDEBUG << "checking frame" << frame->firstPosition() << "point=" << point | - | ||||||||||||||||||||||||
601 | // << "position" << fd->position << "size" << fd->size; | - | ||||||||||||||||||||||||
602 | if (frame != rootFrame) {
| 0 | ||||||||||||||||||||||||
603 | if (relativePoint.y < 0 || relativePoint.x < 0) {
| 0 | ||||||||||||||||||||||||
604 | *position = frame->firstPosition() - 1; | - | ||||||||||||||||||||||||
605 | // LDEBUG << "before pos=" << *position; | - | ||||||||||||||||||||||||
606 | return PointBefore; never executed: return PointBefore; | 0 | ||||||||||||||||||||||||
607 | } else if (relativePoint.y > fd->size.height || relativePoint.x > fd->size.width) {
| 0 | ||||||||||||||||||||||||
608 | *position = frame->lastPosition() + 1; | - | ||||||||||||||||||||||||
609 | // LDEBUG << "after pos=" << *position; | - | ||||||||||||||||||||||||
610 | return PointAfter; never executed: return PointAfter; | 0 | ||||||||||||||||||||||||
611 | } | - | ||||||||||||||||||||||||
612 | } never executed: end of block | 0 | ||||||||||||||||||||||||
613 | - | |||||||||||||||||||||||||
614 | if (isFrameFromInlineObject(frame)) {
| 0 | ||||||||||||||||||||||||
615 | *position = frame->firstPosition() - 1; | - | ||||||||||||||||||||||||
616 | return PointExact; never executed: return PointExact; | 0 | ||||||||||||||||||||||||
617 | } | - | ||||||||||||||||||||||||
618 | - | |||||||||||||||||||||||||
619 | if (QTextTable *table = qobject_cast<QTextTable *>(frame)) {
| 0 | ||||||||||||||||||||||||
620 | const int rows = table->rows(); | - | ||||||||||||||||||||||||
621 | const int columns = table->columns(); | - | ||||||||||||||||||||||||
622 | QTextTableData *td = static_cast<QTextTableData *>(data(table)); | - | ||||||||||||||||||||||||
623 | - | |||||||||||||||||||||||||
624 | if (!td->childFrameMap.isEmpty()) {
| 0 | ||||||||||||||||||||||||
625 | for (int r = 0; r < rows; ++r) {
| 0 | ||||||||||||||||||||||||
626 | for (int c = 0; c < columns; ++c) {
| 0 | ||||||||||||||||||||||||
627 | QTextTableCell cell = table->cellAt(r, c); | - | ||||||||||||||||||||||||
628 | if (cell.row() != r || cell.column() != c)
| 0 | ||||||||||||||||||||||||
629 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
630 | - | |||||||||||||||||||||||||
631 | QRectF cellRect = td->cellRect(cell); | - | ||||||||||||||||||||||||
632 | const QFixedPoint cellPos = QFixedPoint::fromPointF(cellRect.topLeft()); | - | ||||||||||||||||||||||||
633 | const QFixedPoint pointInCell = relativePoint - cellPos; | - | ||||||||||||||||||||||||
634 | - | |||||||||||||||||||||||||
635 | const QList<QTextFrame *> childFrames = td->childFrameMap.values(r + c * rows); | - | ||||||||||||||||||||||||
636 | for (int i = 0; i < childFrames.size(); ++i) {
| 0 | ||||||||||||||||||||||||
637 | QTextFrame *child = childFrames.at(i); | - | ||||||||||||||||||||||||
638 | if (isFrameFromInlineObject(child)
| 0 | ||||||||||||||||||||||||
639 | && child->frameFormat().position() != QTextFrameFormat::InFlow
| 0 | ||||||||||||||||||||||||
640 | && hitTest(child, pointInCell, position, l, accuracy) == PointExact)
| 0 | ||||||||||||||||||||||||
641 | { | - | ||||||||||||||||||||||||
642 | return PointExact; never executed: return PointExact; | 0 | ||||||||||||||||||||||||
643 | } | - | ||||||||||||||||||||||||
644 | } never executed: end of block | 0 | ||||||||||||||||||||||||
645 | } never executed: end of block | 0 | ||||||||||||||||||||||||
646 | } never executed: end of block | 0 | ||||||||||||||||||||||||
647 | } never executed: end of block | 0 | ||||||||||||||||||||||||
648 | - | |||||||||||||||||||||||||
649 | return hitTest(table, relativePoint, position, l, accuracy); never executed: return hitTest(table, relativePoint, position, l, accuracy); | 0 | ||||||||||||||||||||||||
650 | } | - | ||||||||||||||||||||||||
651 | - | |||||||||||||||||||||||||
652 | const QList<QTextFrame *> childFrames = frame->childFrames(); | - | ||||||||||||||||||||||||
653 | for (int i = 0; i < childFrames.size(); ++i) {
| 0 | ||||||||||||||||||||||||
654 | QTextFrame *child = childFrames.at(i); | - | ||||||||||||||||||||||||
655 | if (isFrameFromInlineObject(child)
| 0 | ||||||||||||||||||||||||
656 | && child->frameFormat().position() != QTextFrameFormat::InFlow
| 0 | ||||||||||||||||||||||||
657 | && hitTest(child, relativePoint, position, l, accuracy) == PointExact)
| 0 | ||||||||||||||||||||||||
658 | { | - | ||||||||||||||||||||||||
659 | return PointExact; never executed: return PointExact; | 0 | ||||||||||||||||||||||||
660 | } | - | ||||||||||||||||||||||||
661 | } never executed: end of block | 0 | ||||||||||||||||||||||||
662 | - | |||||||||||||||||||||||||
663 | QTextFrame::Iterator it = frame->begin(); | - | ||||||||||||||||||||||||
664 | - | |||||||||||||||||||||||||
665 | if (frame == rootFrame) {
| 0 | ||||||||||||||||||||||||
666 | it = frameIteratorForYPosition(relativePoint.y); | - | ||||||||||||||||||||||||
667 | - | |||||||||||||||||||||||||
668 | Q_ASSERT(it.parentFrame() == frame); | - | ||||||||||||||||||||||||
669 | } never executed: end of block | 0 | ||||||||||||||||||||||||
670 | - | |||||||||||||||||||||||||
671 | if (it.currentFrame())
| 0 | ||||||||||||||||||||||||
672 | *position = it.currentFrame()->firstPosition(); never executed: *position = it.currentFrame()->firstPosition(); | 0 | ||||||||||||||||||||||||
673 | else | - | ||||||||||||||||||||||||
674 | *position = it.currentBlock().position(); never executed: *position = it.currentBlock().position(); | 0 | ||||||||||||||||||||||||
675 | - | |||||||||||||||||||||||||
676 | return hitTest(it, PointBefore, relativePoint, position, l, accuracy); never executed: return hitTest(it, PointBefore, relativePoint, position, l, accuracy); | 0 | ||||||||||||||||||||||||
677 | } | - | ||||||||||||||||||||||||
678 | - | |||||||||||||||||||||||||
679 | QTextDocumentLayoutPrivate::HitPoint | - | ||||||||||||||||||||||||
680 | QTextDocumentLayoutPrivate::hitTest(QTextFrame::Iterator it, HitPoint hit, const QFixedPoint &p, | - | ||||||||||||||||||||||||
681 | int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const | - | ||||||||||||||||||||||||
682 | { | - | ||||||||||||||||||||||||
683 | INC_INDENT; | - | ||||||||||||||||||||||||
684 | - | |||||||||||||||||||||||||
685 | for (; !it.atEnd(); ++it) {
| 0 | ||||||||||||||||||||||||
686 | QTextFrame *c = it.currentFrame(); | - | ||||||||||||||||||||||||
687 | HitPoint hp; | - | ||||||||||||||||||||||||
688 | int pos = -1; | - | ||||||||||||||||||||||||
689 | if (c) {
| 0 | ||||||||||||||||||||||||
690 | hp = hitTest(c, p, &pos, l, accuracy); | - | ||||||||||||||||||||||||
691 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
692 | hp = hitTest(it.currentBlock(), p, &pos, l, accuracy); | - | ||||||||||||||||||||||||
693 | } never executed: end of block | 0 | ||||||||||||||||||||||||
694 | if (hp >= PointInside) {
| 0 | ||||||||||||||||||||||||
695 | if (isEmptyBlockBeforeTable(it))
| 0 | ||||||||||||||||||||||||
696 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
697 | hit = hp; | - | ||||||||||||||||||||||||
698 | *position = pos; | - | ||||||||||||||||||||||||
699 | break; never executed: break; | 0 | ||||||||||||||||||||||||
700 | } | - | ||||||||||||||||||||||||
701 | if (hp == PointBefore && pos < *position) {
| 0 | ||||||||||||||||||||||||
702 | *position = pos; | - | ||||||||||||||||||||||||
703 | hit = hp; | - | ||||||||||||||||||||||||
704 | } else if (hp == PointAfter && pos > *position) { never executed: end of block
| 0 | ||||||||||||||||||||||||
705 | *position = pos; | - | ||||||||||||||||||||||||
706 | hit = hp; | - | ||||||||||||||||||||||||
707 | } never executed: end of block | 0 | ||||||||||||||||||||||||
708 | } never executed: end of block | 0 | ||||||||||||||||||||||||
709 | - | |||||||||||||||||||||||||
710 | DEC_INDENT; | - | ||||||||||||||||||||||||
711 | // LDEBUG << "inside=" << hit << " pos=" << *position; | - | ||||||||||||||||||||||||
712 | return hit; never executed: return hit; | 0 | ||||||||||||||||||||||||
713 | } | - | ||||||||||||||||||||||||
714 | - | |||||||||||||||||||||||||
715 | QTextDocumentLayoutPrivate::HitPoint | - | ||||||||||||||||||||||||
716 | QTextDocumentLayoutPrivate::hitTest(QTextTable *table, const QFixedPoint &point, | - | ||||||||||||||||||||||||
717 | int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const | - | ||||||||||||||||||||||||
718 | { | - | ||||||||||||||||||||||||
719 | QTextTableData *td = static_cast<QTextTableData *>(data(table)); | - | ||||||||||||||||||||||||
720 | - | |||||||||||||||||||||||||
721 | QVector<QFixed>::ConstIterator rowIt = std::lower_bound(td->rowPositions.constBegin(), td->rowPositions.constEnd(), point.y); | - | ||||||||||||||||||||||||
722 | if (rowIt == td->rowPositions.constEnd()) {
| 0 | ||||||||||||||||||||||||
723 | rowIt = td->rowPositions.constEnd() - 1; | - | ||||||||||||||||||||||||
724 | } else if (rowIt != td->rowPositions.constBegin()) { never executed: end of block
| 0 | ||||||||||||||||||||||||
725 | --rowIt; | - | ||||||||||||||||||||||||
726 | } never executed: end of block | 0 | ||||||||||||||||||||||||
727 | - | |||||||||||||||||||||||||
728 | QVector<QFixed>::ConstIterator colIt = std::lower_bound(td->columnPositions.constBegin(), td->columnPositions.constEnd(), point.x); | - | ||||||||||||||||||||||||
729 | if (colIt == td->columnPositions.constEnd()) {
| 0 | ||||||||||||||||||||||||
730 | colIt = td->columnPositions.constEnd() - 1; | - | ||||||||||||||||||||||||
731 | } else if (colIt != td->columnPositions.constBegin()) { never executed: end of block
| 0 | ||||||||||||||||||||||||
732 | --colIt; | - | ||||||||||||||||||||||||
733 | } never executed: end of block | 0 | ||||||||||||||||||||||||
734 | - | |||||||||||||||||||||||||
735 | QTextTableCell cell = table->cellAt(rowIt - td->rowPositions.constBegin(), | - | ||||||||||||||||||||||||
736 | colIt - td->columnPositions.constBegin()); | - | ||||||||||||||||||||||||
737 | if (!cell.isValid())
| 0 | ||||||||||||||||||||||||
738 | return PointBefore; never executed: return PointBefore; | 0 | ||||||||||||||||||||||||
739 | - | |||||||||||||||||||||||||
740 | *position = cell.firstPosition(); | - | ||||||||||||||||||||||||
741 | - | |||||||||||||||||||||||||
742 | HitPoint hp = hitTest(cell.begin(), PointInside, point - td->cellPosition(cell), position, l, accuracy); | - | ||||||||||||||||||||||||
743 | - | |||||||||||||||||||||||||
744 | if (hp == PointExact)
| 0 | ||||||||||||||||||||||||
745 | return hp; never executed: return hp; | 0 | ||||||||||||||||||||||||
746 | if (hp == PointAfter)
| 0 | ||||||||||||||||||||||||
747 | *position = cell.lastPosition(); never executed: *position = cell.lastPosition(); | 0 | ||||||||||||||||||||||||
748 | return PointInside; never executed: return PointInside; | 0 | ||||||||||||||||||||||||
749 | } | - | ||||||||||||||||||||||||
750 | - | |||||||||||||||||||||||||
751 | QTextDocumentLayoutPrivate::HitPoint | - | ||||||||||||||||||||||||
752 | QTextDocumentLayoutPrivate::hitTest(const QTextBlock &bl, const QFixedPoint &point, int *position, QTextLayout **l, | - | ||||||||||||||||||||||||
753 | Qt::HitTestAccuracy accuracy) const | - | ||||||||||||||||||||||||
754 | { | - | ||||||||||||||||||||||||
755 | QTextLayout *tl = bl.layout(); | - | ||||||||||||||||||||||||
756 | QRectF textrect = tl->boundingRect(); | - | ||||||||||||||||||||||||
757 | textrect.translate(tl->position()); | - | ||||||||||||||||||||||||
758 | // LDEBUG << " checking block" << bl.position() << "point=" << point | - | ||||||||||||||||||||||||
759 | // << " tlrect" << textrect; | - | ||||||||||||||||||||||||
760 | *position = bl.position(); | - | ||||||||||||||||||||||||
761 | if (point.y.toReal() < textrect.top()) {
| 0 | ||||||||||||||||||||||||
762 | // LDEBUG << " before pos=" << *position; | - | ||||||||||||||||||||||||
763 | return PointBefore; never executed: return PointBefore; | 0 | ||||||||||||||||||||||||
764 | } else if (point.y.toReal() > textrect.bottom()) {
| 0 | ||||||||||||||||||||||||
765 | *position += bl.length(); | - | ||||||||||||||||||||||||
766 | // LDEBUG << " after pos=" << *position; | - | ||||||||||||||||||||||||
767 | return PointAfter; never executed: return PointAfter; | 0 | ||||||||||||||||||||||||
768 | } | - | ||||||||||||||||||||||||
769 | - | |||||||||||||||||||||||||
770 | QPointF pos = point.toPointF() - tl->position(); | - | ||||||||||||||||||||||||
771 | - | |||||||||||||||||||||||||
772 | // ### rtl? | - | ||||||||||||||||||||||||
773 | - | |||||||||||||||||||||||||
774 | HitPoint hit = PointInside; | - | ||||||||||||||||||||||||
775 | *l = tl; | - | ||||||||||||||||||||||||
776 | int off = 0; | - | ||||||||||||||||||||||||
777 | for (int i = 0; i < tl->lineCount(); ++i) {
| 0 | ||||||||||||||||||||||||
778 | QTextLine line = tl->lineAt(i); | - | ||||||||||||||||||||||||
779 | const QRectF lr = line.naturalTextRect(); | - | ||||||||||||||||||||||||
780 | if (lr.top() > pos.y()) {
| 0 | ||||||||||||||||||||||||
781 | off = qMin(off, line.textStart()); | - | ||||||||||||||||||||||||
782 | } else if (lr.bottom() <= pos.y()) { never executed: end of block
| 0 | ||||||||||||||||||||||||
783 | off = qMax(off, line.textStart() + line.textLength()); | - | ||||||||||||||||||||||||
784 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
785 | if (lr.left() <= pos.x() && lr.right() >= pos.x())
| 0 | ||||||||||||||||||||||||
786 | hit = PointExact; never executed: hit = PointExact; | 0 | ||||||||||||||||||||||||
787 | // when trying to hit an anchor we want it to hit not only in the left | - | ||||||||||||||||||||||||
788 | // half | - | ||||||||||||||||||||||||
789 | if (accuracy == Qt::ExactHit)
| 0 | ||||||||||||||||||||||||
790 | off = line.xToCursor(pos.x(), QTextLine::CursorOnCharacter); never executed: off = line.xToCursor(pos.x(), QTextLine::CursorOnCharacter); | 0 | ||||||||||||||||||||||||
791 | else | - | ||||||||||||||||||||||||
792 | off = line.xToCursor(pos.x(), QTextLine::CursorBetweenCharacters); never executed: off = line.xToCursor(pos.x(), QTextLine::CursorBetweenCharacters); | 0 | ||||||||||||||||||||||||
793 | break; never executed: break; | 0 | ||||||||||||||||||||||||
794 | } | - | ||||||||||||||||||||||||
795 | } | - | ||||||||||||||||||||||||
796 | *position += off; | - | ||||||||||||||||||||||||
797 | - | |||||||||||||||||||||||||
798 | // LDEBUG << " inside=" << hit << " pos=" << *position; | - | ||||||||||||||||||||||||
799 | return hit; never executed: return hit; | 0 | ||||||||||||||||||||||||
800 | } | - | ||||||||||||||||||||||||
801 | - | |||||||||||||||||||||||||
802 | // ### could be moved to QTextBlock | - | ||||||||||||||||||||||||
803 | QFixed QTextDocumentLayoutPrivate::blockIndent(const QTextBlockFormat &blockFormat) const | - | ||||||||||||||||||||||||
804 | { | - | ||||||||||||||||||||||||
805 | qreal indent = blockFormat.indent(); | - | ||||||||||||||||||||||||
806 | - | |||||||||||||||||||||||||
807 | QTextObject *object = document->objectForFormat(blockFormat); | - | ||||||||||||||||||||||||
808 | if (object)
| 0 | ||||||||||||||||||||||||
809 | indent += object->format().toListFormat().indent(); never executed: indent += object->format().toListFormat().indent(); | 0 | ||||||||||||||||||||||||
810 | - | |||||||||||||||||||||||||
811 | if (qIsNull(indent))
| 0 | ||||||||||||||||||||||||
812 | return 0; never executed: return 0; | 0 | ||||||||||||||||||||||||
813 | - | |||||||||||||||||||||||||
814 | qreal scale = 1; | - | ||||||||||||||||||||||||
815 | if (paintDevice) {
| 0 | ||||||||||||||||||||||||
816 | scale = qreal(paintDevice->logicalDpiY()) / qreal(qt_defaultDpi()); | - | ||||||||||||||||||||||||
817 | } never executed: end of block | 0 | ||||||||||||||||||||||||
818 | - | |||||||||||||||||||||||||
819 | return QFixed::fromReal(indent * scale * document->indentWidth()); never executed: return QFixed::fromReal(indent * scale * document->indentWidth()); | 0 | ||||||||||||||||||||||||
820 | } | - | ||||||||||||||||||||||||
821 | - | |||||||||||||||||||||||||
822 | void QTextDocumentLayoutPrivate::drawBorder(QPainter *painter, const QRectF &rect, qreal topMargin, qreal bottomMargin, | - | ||||||||||||||||||||||||
823 | qreal border, const QBrush &brush, QTextFrameFormat::BorderStyle style) const | - | ||||||||||||||||||||||||
824 | { | - | ||||||||||||||||||||||||
825 | const qreal pageHeight = document->pageSize().height(); | - | ||||||||||||||||||||||||
826 | const int topPage = pageHeight > 0 ? static_cast<int>(rect.top() / pageHeight) : 0;
| 0 | ||||||||||||||||||||||||
827 | const int bottomPage = pageHeight > 0 ? static_cast<int>((rect.bottom() + border) / pageHeight) : 0;
| 0 | ||||||||||||||||||||||||
828 | - | |||||||||||||||||||||||||
829 | #ifndef QT_NO_CSSPARSER | - | ||||||||||||||||||||||||
830 | QCss::BorderStyle cssStyle = static_cast<QCss::BorderStyle>(style + 1); | - | ||||||||||||||||||||||||
831 | #endif //QT_NO_CSSPARSER | - | ||||||||||||||||||||||||
832 | - | |||||||||||||||||||||||||
833 | bool turn_off_antialiasing = !(painter->renderHints() & QPainter::Antialiasing); | - | ||||||||||||||||||||||||
834 | painter->setRenderHint(QPainter::Antialiasing); | - | ||||||||||||||||||||||||
835 | - | |||||||||||||||||||||||||
836 | for (int i = topPage; i <= bottomPage; ++i) {
| 0 | ||||||||||||||||||||||||
837 | QRectF clipped = rect.toRect(); | - | ||||||||||||||||||||||||
838 | - | |||||||||||||||||||||||||
839 | if (topPage != bottomPage) {
| 0 | ||||||||||||||||||||||||
840 | clipped.setTop(qMax(clipped.top(), i * pageHeight + topMargin - border)); | - | ||||||||||||||||||||||||
841 | clipped.setBottom(qMin(clipped.bottom(), (i + 1) * pageHeight - bottomMargin)); | - | ||||||||||||||||||||||||
842 | - | |||||||||||||||||||||||||
843 | if (clipped.bottom() <= clipped.top())
| 0 | ||||||||||||||||||||||||
844 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
845 | } never executed: end of block | 0 | ||||||||||||||||||||||||
846 | #ifndef QT_NO_CSSPARSER | - | ||||||||||||||||||||||||
847 | qDrawEdge(painter, clipped.left(), clipped.top(), clipped.left() + border, clipped.bottom() + border, 0, 0, QCss::LeftEdge, cssStyle, brush); | - | ||||||||||||||||||||||||
848 | qDrawEdge(painter, clipped.left() + border, clipped.top(), clipped.right() + border, clipped.top() + border, 0, 0, QCss::TopEdge, cssStyle, brush); | - | ||||||||||||||||||||||||
849 | qDrawEdge(painter, clipped.right(), clipped.top() + border, clipped.right() + border, clipped.bottom(), 0, 0, QCss::RightEdge, cssStyle, brush); | - | ||||||||||||||||||||||||
850 | qDrawEdge(painter, clipped.left() + border, clipped.bottom(), clipped.right() + border, clipped.bottom() + border, 0, 0, QCss::BottomEdge, cssStyle, brush); | - | ||||||||||||||||||||||||
851 | #else | - | ||||||||||||||||||||||||
852 | painter->save(); | - | ||||||||||||||||||||||||
853 | painter->setPen(Qt::NoPen); | - | ||||||||||||||||||||||||
854 | painter->setBrush(brush); | - | ||||||||||||||||||||||||
855 | painter->drawRect(QRectF(clipped.left(), clipped.top(), clipped.left() + border, clipped.bottom() + border)); | - | ||||||||||||||||||||||||
856 | painter->drawRect(QRectF(clipped.left() + border, clipped.top(), clipped.right() + border, clipped.top() + border)); | - | ||||||||||||||||||||||||
857 | painter->drawRect(QRectF(clipped.right(), clipped.top() + border, clipped.right() + border, clipped.bottom())); | - | ||||||||||||||||||||||||
858 | painter->drawRect(QRectF(clipped.left() + border, clipped.bottom(), clipped.right() + border, clipped.bottom() + border)); | - | ||||||||||||||||||||||||
859 | painter->restore(); | - | ||||||||||||||||||||||||
860 | #endif //QT_NO_CSSPARSER | - | ||||||||||||||||||||||||
861 | } never executed: end of block | 0 | ||||||||||||||||||||||||
862 | if (turn_off_antialiasing)
| 0 | ||||||||||||||||||||||||
863 | painter->setRenderHint(QPainter::Antialiasing, false); never executed: painter->setRenderHint(QPainter::Antialiasing, false); | 0 | ||||||||||||||||||||||||
864 | } never executed: end of block | 0 | ||||||||||||||||||||||||
865 | - | |||||||||||||||||||||||||
866 | void QTextDocumentLayoutPrivate::drawFrameDecoration(QPainter *painter, QTextFrame *frame, QTextFrameData *fd, const QRectF &clip, const QRectF &rect) const | - | ||||||||||||||||||||||||
867 | { | - | ||||||||||||||||||||||||
868 | - | |||||||||||||||||||||||||
869 | const QBrush bg = frame->frameFormat().background(); | - | ||||||||||||||||||||||||
870 | if (bg != Qt::NoBrush) {
| 0 | ||||||||||||||||||||||||
871 | QRectF bgRect = rect; | - | ||||||||||||||||||||||||
872 | bgRect.adjust((fd->leftMargin + fd->border).toReal(), | - | ||||||||||||||||||||||||
873 | (fd->topMargin + fd->border).toReal(), | - | ||||||||||||||||||||||||
874 | - (fd->rightMargin + fd->border).toReal(), | - | ||||||||||||||||||||||||
875 | - (fd->bottomMargin + fd->border).toReal()); | - | ||||||||||||||||||||||||
876 | - | |||||||||||||||||||||||||
877 | QRectF gradientRect; // invalid makes it default to bgRect | - | ||||||||||||||||||||||||
878 | QPointF origin = bgRect.topLeft(); | - | ||||||||||||||||||||||||
879 | if (!frame->parentFrame()) {
| 0 | ||||||||||||||||||||||||
880 | bgRect = clip; | - | ||||||||||||||||||||||||
881 | gradientRect.setWidth(painter->device()->width()); | - | ||||||||||||||||||||||||
882 | gradientRect.setHeight(painter->device()->height()); | - | ||||||||||||||||||||||||
883 | } never executed: end of block | 0 | ||||||||||||||||||||||||
884 | fillBackground(painter, bgRect, bg, origin, gradientRect); | - | ||||||||||||||||||||||||
885 | } never executed: end of block | 0 | ||||||||||||||||||||||||
886 | if (fd->border != 0) {
| 0 | ||||||||||||||||||||||||
887 | painter->save(); | - | ||||||||||||||||||||||||
888 | painter->setBrush(Qt::lightGray); | - | ||||||||||||||||||||||||
889 | painter->setPen(Qt::NoPen); | - | ||||||||||||||||||||||||
890 | - | |||||||||||||||||||||||||
891 | const qreal leftEdge = rect.left() + fd->leftMargin.toReal(); | - | ||||||||||||||||||||||||
892 | const qreal border = fd->border.toReal(); | - | ||||||||||||||||||||||||
893 | const qreal topMargin = fd->topMargin.toReal(); | - | ||||||||||||||||||||||||
894 | const qreal leftMargin = fd->leftMargin.toReal(); | - | ||||||||||||||||||||||||
895 | const qreal bottomMargin = fd->bottomMargin.toReal(); | - | ||||||||||||||||||||||||
896 | const qreal rightMargin = fd->rightMargin.toReal(); | - | ||||||||||||||||||||||||
897 | const qreal w = rect.width() - 2 * border - leftMargin - rightMargin; | - | ||||||||||||||||||||||||
898 | const qreal h = rect.height() - 2 * border - topMargin - bottomMargin; | - | ||||||||||||||||||||||||
899 | - | |||||||||||||||||||||||||
900 | drawBorder(painter, QRectF(leftEdge, rect.top() + topMargin, w + border, h + border), | - | ||||||||||||||||||||||||
901 | fd->effectiveTopMargin.toReal(), fd->effectiveBottomMargin.toReal(), | - | ||||||||||||||||||||||||
902 | border, frame->frameFormat().borderBrush(), frame->frameFormat().borderStyle()); | - | ||||||||||||||||||||||||
903 | - | |||||||||||||||||||||||||
904 | painter->restore(); | - | ||||||||||||||||||||||||
905 | } never executed: end of block | 0 | ||||||||||||||||||||||||
906 | } never executed: end of block | 0 | ||||||||||||||||||||||||
907 | - | |||||||||||||||||||||||||
908 | static void adjustContextSelectionsForCell(QAbstractTextDocumentLayout::PaintContext &cell_context, | - | ||||||||||||||||||||||||
909 | const QTextTableCell &cell, | - | ||||||||||||||||||||||||
910 | int r, int c, | - | ||||||||||||||||||||||||
911 | const int *selectedTableCells) | - | ||||||||||||||||||||||||
912 | { | - | ||||||||||||||||||||||||
913 | for (int i = 0; i < cell_context.selections.size(); ++i) {
| 0 | ||||||||||||||||||||||||
914 | int row_start = selectedTableCells[i * 4]; | - | ||||||||||||||||||||||||
915 | int col_start = selectedTableCells[i * 4 + 1]; | - | ||||||||||||||||||||||||
916 | int num_rows = selectedTableCells[i * 4 + 2]; | - | ||||||||||||||||||||||||
917 | int num_cols = selectedTableCells[i * 4 + 3]; | - | ||||||||||||||||||||||||
918 | - | |||||||||||||||||||||||||
919 | if (row_start != -1) {
| 0 | ||||||||||||||||||||||||
920 | if (r >= row_start && r < row_start + num_rows
| 0 | ||||||||||||||||||||||||
921 | && c >= col_start && c < col_start + num_cols)
| 0 | ||||||||||||||||||||||||
922 | { | - | ||||||||||||||||||||||||
923 | int firstPosition = cell.firstPosition(); | - | ||||||||||||||||||||||||
924 | int lastPosition = cell.lastPosition(); | - | ||||||||||||||||||||||||
925 | - | |||||||||||||||||||||||||
926 | // make sure empty cells are still selected | - | ||||||||||||||||||||||||
927 | if (firstPosition == lastPosition)
| 0 | ||||||||||||||||||||||||
928 | ++lastPosition; never executed: ++lastPosition; | 0 | ||||||||||||||||||||||||
929 | - | |||||||||||||||||||||||||
930 | cell_context.selections[i].cursor.setPosition(firstPosition); | - | ||||||||||||||||||||||||
931 | cell_context.selections[i].cursor.setPosition(lastPosition, QTextCursor::KeepAnchor); | - | ||||||||||||||||||||||||
932 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
933 | cell_context.selections[i].cursor.clearSelection(); | - | ||||||||||||||||||||||||
934 | } never executed: end of block | 0 | ||||||||||||||||||||||||
935 | } | - | ||||||||||||||||||||||||
936 | - | |||||||||||||||||||||||||
937 | // FullWidthSelection is not useful for tables | - | ||||||||||||||||||||||||
938 | cell_context.selections[i].format.clearProperty(QTextFormat::FullWidthSelection); | - | ||||||||||||||||||||||||
939 | } never executed: end of block | 0 | ||||||||||||||||||||||||
940 | } never executed: end of block | 0 | ||||||||||||||||||||||||
941 | - | |||||||||||||||||||||||||
942 | void QTextDocumentLayoutPrivate::drawFrame(const QPointF &offset, QPainter *painter, | - | ||||||||||||||||||||||||
943 | const QAbstractTextDocumentLayout::PaintContext &context, | - | ||||||||||||||||||||||||
944 | QTextFrame *frame) const | - | ||||||||||||||||||||||||
945 | { | - | ||||||||||||||||||||||||
946 | QTextFrameData *fd = data(frame); | - | ||||||||||||||||||||||||
947 | // ####### | - | ||||||||||||||||||||||||
948 | if (fd->layoutDirty)
| 0 | ||||||||||||||||||||||||
949 | return; never executed: return; | 0 | ||||||||||||||||||||||||
950 | Q_ASSERT(!fd->sizeDirty); | - | ||||||||||||||||||||||||
951 | Q_ASSERT(!fd->layoutDirty); | - | ||||||||||||||||||||||||
952 | - | |||||||||||||||||||||||||
953 | const QPointF off = offset + fd->position.toPointF(); | - | ||||||||||||||||||||||||
954 | if (context.clip.isValid()
| 0 | ||||||||||||||||||||||||
955 | && (off.y() > context.clip.bottom() || off.y() + fd->size.height.toReal() < context.clip.top()
| 0 | ||||||||||||||||||||||||
956 | || off.x() > context.clip.right() || off.x() + fd->size.width.toReal() < context.clip.left()))
| 0 | ||||||||||||||||||||||||
957 | return; never executed: return; | 0 | ||||||||||||||||||||||||
958 | - | |||||||||||||||||||||||||
959 | // LDEBUG << debug_indent << "drawFrame" << frame->firstPosition() << "--" << frame->lastPosition() << "at" << offset; | - | ||||||||||||||||||||||||
960 | // INC_INDENT; | - | ||||||||||||||||||||||||
961 | - | |||||||||||||||||||||||||
962 | // if the cursor is /on/ a table border we may need to repaint it | - | ||||||||||||||||||||||||
963 | // afterwards, as we usually draw the decoration first | - | ||||||||||||||||||||||||
964 | QTextBlock cursorBlockNeedingRepaint; | - | ||||||||||||||||||||||||
965 | QPointF offsetOfRepaintedCursorBlock = off; | - | ||||||||||||||||||||||||
966 | - | |||||||||||||||||||||||||
967 | QTextTable *table = qobject_cast<QTextTable *>(frame); | - | ||||||||||||||||||||||||
968 | const QRectF frameRect(off, fd->size.toSizeF()); | - | ||||||||||||||||||||||||
969 | - | |||||||||||||||||||||||||
970 | if (table) {
| 0 | ||||||||||||||||||||||||
971 | const int rows = table->rows(); | - | ||||||||||||||||||||||||
972 | const int columns = table->columns(); | - | ||||||||||||||||||||||||
973 | QTextTableData *td = static_cast<QTextTableData *>(data(table)); | - | ||||||||||||||||||||||||
974 | - | |||||||||||||||||||||||||
975 | QVarLengthArray<int> selectedTableCells(context.selections.size() * 4); | - | ||||||||||||||||||||||||
976 | for (int i = 0; i < context.selections.size(); ++i) {
| 0 | ||||||||||||||||||||||||
977 | const QAbstractTextDocumentLayout::Selection &s = context.selections.at(i); | - | ||||||||||||||||||||||||
978 | int row_start = -1, col_start = -1, num_rows = -1, num_cols = -1; | - | ||||||||||||||||||||||||
979 | - | |||||||||||||||||||||||||
980 | if (s.cursor.currentTable() == table)
| 0 | ||||||||||||||||||||||||
981 | 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 | ||||||||||||||||||||||||
982 | - | |||||||||||||||||||||||||
983 | selectedTableCells[i * 4] = row_start; | - | ||||||||||||||||||||||||
984 | selectedTableCells[i * 4 + 1] = col_start; | - | ||||||||||||||||||||||||
985 | selectedTableCells[i * 4 + 2] = num_rows; | - | ||||||||||||||||||||||||
986 | selectedTableCells[i * 4 + 3] = num_cols; | - | ||||||||||||||||||||||||
987 | } never executed: end of block | 0 | ||||||||||||||||||||||||
988 | - | |||||||||||||||||||||||||
989 | QFixed pageHeight = QFixed::fromReal(document->pageSize().height()); | - | ||||||||||||||||||||||||
990 | if (pageHeight <= 0)
| 0 | ||||||||||||||||||||||||
991 | pageHeight = QFIXED_MAX; never executed: pageHeight = (2147483647/256); | 0 | ||||||||||||||||||||||||
992 | - | |||||||||||||||||||||||||
993 | const int tableStartPage = (td->position.y / pageHeight).truncate(); | - | ||||||||||||||||||||||||
994 | const int tableEndPage = ((td->position.y + td->size.height) / pageHeight).truncate(); | - | ||||||||||||||||||||||||
995 | - | |||||||||||||||||||||||||
996 | qreal border = td->border.toReal(); | - | ||||||||||||||||||||||||
997 | drawFrameDecoration(painter, frame, fd, context.clip, frameRect); | - | ||||||||||||||||||||||||
998 | - | |||||||||||||||||||||||||
999 | // draw the table headers | - | ||||||||||||||||||||||||
1000 | const int headerRowCount = qMin(table->format().headerRowCount(), rows - 1); | - | ||||||||||||||||||||||||
1001 | int page = tableStartPage + 1; | - | ||||||||||||||||||||||||
1002 | while (page <= tableEndPage) {
| 0 | ||||||||||||||||||||||||
1003 | const QFixed pageTop = page * pageHeight + td->effectiveTopMargin + td->cellSpacing + td->border; | - | ||||||||||||||||||||||||
1004 | const qreal headerOffset = (pageTop - td->rowPositions.at(0)).toReal(); | - | ||||||||||||||||||||||||
1005 | for (int r = 0; r < headerRowCount; ++r) {
| 0 | ||||||||||||||||||||||||
1006 | for (int c = 0; c < columns; ++c) {
| 0 | ||||||||||||||||||||||||
1007 | QTextTableCell cell = table->cellAt(r, c); | - | ||||||||||||||||||||||||
1008 | QAbstractTextDocumentLayout::PaintContext cell_context = context; | - | ||||||||||||||||||||||||
1009 | adjustContextSelectionsForCell(cell_context, cell, r, c, selectedTableCells.data()); | - | ||||||||||||||||||||||||
1010 | QRectF cellRect = td->cellRect(cell); | - | ||||||||||||||||||||||||
1011 | - | |||||||||||||||||||||||||
1012 | cellRect.translate(off.x(), headerOffset); | - | ||||||||||||||||||||||||
1013 | // we need to account for the cell border in the clipping test | - | ||||||||||||||||||||||||
1014 | int leftAdjust = qMin(qreal(0), 1 - border); | - | ||||||||||||||||||||||||
1015 | if (cell_context.clip.isValid() && !cellRect.adjusted(leftAdjust, leftAdjust, border, border).intersects(cell_context.clip))
| 0 | ||||||||||||||||||||||||
1016 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1017 | - | |||||||||||||||||||||||||
1018 | drawTableCell(cellRect, painter, cell_context, table, td, r, c, &cursorBlockNeedingRepaint, | - | ||||||||||||||||||||||||
1019 | &offsetOfRepaintedCursorBlock); | - | ||||||||||||||||||||||||
1020 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1021 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1022 | ++page; | - | ||||||||||||||||||||||||
1023 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1024 | - | |||||||||||||||||||||||||
1025 | int firstRow = 0; | - | ||||||||||||||||||||||||
1026 | int lastRow = rows; | - | ||||||||||||||||||||||||
1027 | - | |||||||||||||||||||||||||
1028 | if (context.clip.isValid()) {
| 0 | ||||||||||||||||||||||||
1029 | QVector<QFixed>::ConstIterator rowIt = std::lower_bound(td->rowPositions.constBegin(), td->rowPositions.constEnd(), QFixed::fromReal(context.clip.top() - off.y())); | - | ||||||||||||||||||||||||
1030 | if (rowIt != td->rowPositions.constEnd() && rowIt != td->rowPositions.constBegin()) {
| 0 | ||||||||||||||||||||||||
1031 | --rowIt; | - | ||||||||||||||||||||||||
1032 | firstRow = rowIt - td->rowPositions.constBegin(); | - | ||||||||||||||||||||||||
1033 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1034 | - | |||||||||||||||||||||||||
1035 | rowIt = std::upper_bound(td->rowPositions.constBegin(), td->rowPositions.constEnd(), QFixed::fromReal(context.clip.bottom() - off.y())); | - | ||||||||||||||||||||||||
1036 | if (rowIt != td->rowPositions.constEnd()) {
| 0 | ||||||||||||||||||||||||
1037 | ++rowIt; | - | ||||||||||||||||||||||||
1038 | lastRow = rowIt - td->rowPositions.constBegin(); | - | ||||||||||||||||||||||||
1039 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1040 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1041 | - | |||||||||||||||||||||||||
1042 | for (int c = 0; c < columns; ++c) {
| 0 | ||||||||||||||||||||||||
1043 | QTextTableCell cell = table->cellAt(firstRow, c); | - | ||||||||||||||||||||||||
1044 | firstRow = qMin(firstRow, cell.row()); | - | ||||||||||||||||||||||||
1045 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1046 | - | |||||||||||||||||||||||||
1047 | for (int r = firstRow; r < lastRow; ++r) {
| 0 | ||||||||||||||||||||||||
1048 | for (int c = 0; c < columns; ++c) {
| 0 | ||||||||||||||||||||||||
1049 | QTextTableCell cell = table->cellAt(r, c); | - | ||||||||||||||||||||||||
1050 | QAbstractTextDocumentLayout::PaintContext cell_context = context; | - | ||||||||||||||||||||||||
1051 | adjustContextSelectionsForCell(cell_context, cell, r, c, selectedTableCells.data()); | - | ||||||||||||||||||||||||
1052 | QRectF cellRect = td->cellRect(cell); | - | ||||||||||||||||||||||||
1053 | - | |||||||||||||||||||||||||
1054 | cellRect.translate(off); | - | ||||||||||||||||||||||||
1055 | // we need to account for the cell border in the clipping test | - | ||||||||||||||||||||||||
1056 | int leftAdjust = qMin(qreal(0), 1 - border); | - | ||||||||||||||||||||||||
1057 | if (cell_context.clip.isValid() && !cellRect.adjusted(leftAdjust, leftAdjust, border, border).intersects(cell_context.clip))
| 0 | ||||||||||||||||||||||||
1058 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1059 | - | |||||||||||||||||||||||||
1060 | drawTableCell(cellRect, painter, cell_context, table, td, r, c, &cursorBlockNeedingRepaint, | - | ||||||||||||||||||||||||
1061 | &offsetOfRepaintedCursorBlock); | - | ||||||||||||||||||||||||
1062 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1063 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1064 | - | |||||||||||||||||||||||||
1065 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
1066 | drawFrameDecoration(painter, frame, fd, context.clip, frameRect); | - | ||||||||||||||||||||||||
1067 | - | |||||||||||||||||||||||||
1068 | QTextFrame::Iterator it = frame->begin(); | - | ||||||||||||||||||||||||
1069 | - | |||||||||||||||||||||||||
1070 | if (frame == docPrivate->rootFrame())
| 0 | ||||||||||||||||||||||||
1071 | it = frameIteratorForYPosition(QFixed::fromReal(context.clip.top())); never executed: it = frameIteratorForYPosition(QFixed::fromReal(context.clip.top())); | 0 | ||||||||||||||||||||||||
1072 | - | |||||||||||||||||||||||||
1073 | QList<QTextFrame *> floats; | - | ||||||||||||||||||||||||
1074 | const int numFloats = fd->floats.count(); | - | ||||||||||||||||||||||||
1075 | floats.reserve(numFloats); | - | ||||||||||||||||||||||||
1076 | for (int i = 0; i < numFloats; ++i)
| 0 | ||||||||||||||||||||||||
1077 | floats.append(fd->floats.at(i)); never executed: floats.append(fd->floats.at(i)); | 0 | ||||||||||||||||||||||||
1078 | - | |||||||||||||||||||||||||
1079 | drawFlow(off, painter, context, it, floats, &cursorBlockNeedingRepaint); | - | ||||||||||||||||||||||||
1080 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1081 | - | |||||||||||||||||||||||||
1082 | if (cursorBlockNeedingRepaint.isValid()) {
| 0 | ||||||||||||||||||||||||
1083 | const QPen oldPen = painter->pen(); | - | ||||||||||||||||||||||||
1084 | painter->setPen(context.palette.color(QPalette::Text)); | - | ||||||||||||||||||||||||
1085 | const int cursorPos = context.cursorPosition - cursorBlockNeedingRepaint.position(); | - | ||||||||||||||||||||||||
1086 | cursorBlockNeedingRepaint.layout()->drawCursor(painter, offsetOfRepaintedCursorBlock, | - | ||||||||||||||||||||||||
1087 | cursorPos, cursorWidth); | - | ||||||||||||||||||||||||
1088 | painter->setPen(oldPen); | - | ||||||||||||||||||||||||
1089 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1090 | - | |||||||||||||||||||||||||
1091 | // DEC_INDENT; | - | ||||||||||||||||||||||||
1092 | - | |||||||||||||||||||||||||
1093 | return; never executed: return; | 0 | ||||||||||||||||||||||||
1094 | } | - | ||||||||||||||||||||||||
1095 | - | |||||||||||||||||||||||||
1096 | void QTextDocumentLayoutPrivate::drawTableCell(const QRectF &cellRect, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &cell_context, | - | ||||||||||||||||||||||||
1097 | QTextTable *table, QTextTableData *td, int r, int c, | - | ||||||||||||||||||||||||
1098 | QTextBlock *cursorBlockNeedingRepaint, QPointF *cursorBlockOffset) const | - | ||||||||||||||||||||||||
1099 | { | - | ||||||||||||||||||||||||
1100 | QTextTableCell cell = table->cellAt(r, c); | - | ||||||||||||||||||||||||
1101 | int rspan = cell.rowSpan(); | - | ||||||||||||||||||||||||
1102 | int cspan = cell.columnSpan(); | - | ||||||||||||||||||||||||
1103 | if (rspan != 1) {
| 0 | ||||||||||||||||||||||||
1104 | int cr = cell.row(); | - | ||||||||||||||||||||||||
1105 | if (cr != r)
| 0 | ||||||||||||||||||||||||
1106 | return; never executed: return; | 0 | ||||||||||||||||||||||||
1107 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1108 | if (cspan != 1) {
| 0 | ||||||||||||||||||||||||
1109 | int cc = cell.column(); | - | ||||||||||||||||||||||||
1110 | if (cc != c)
| 0 | ||||||||||||||||||||||||
1111 | return; never executed: return; | 0 | ||||||||||||||||||||||||
1112 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1113 | - | |||||||||||||||||||||||||
1114 | QTextFormat fmt = cell.format(); | - | ||||||||||||||||||||||||
1115 | const QFixed leftPadding = td->leftPadding(fmt); | - | ||||||||||||||||||||||||
1116 | const QFixed topPadding = td->topPadding(fmt); | - | ||||||||||||||||||||||||
1117 | - | |||||||||||||||||||||||||
1118 | qreal topMargin = (td->effectiveTopMargin + td->cellSpacing + td->border).toReal(); | - | ||||||||||||||||||||||||
1119 | qreal bottomMargin = (td->effectiveBottomMargin + td->cellSpacing + td->border).toReal(); | - | ||||||||||||||||||||||||
1120 | - | |||||||||||||||||||||||||
1121 | const int headerRowCount = qMin(table->format().headerRowCount(), table->rows() - 1); | - | ||||||||||||||||||||||||
1122 | if (r >= headerRowCount)
| 0 | ||||||||||||||||||||||||
1123 | topMargin += td->headerHeight.toReal(); never executed: topMargin += td->headerHeight.toReal(); | 0 | ||||||||||||||||||||||||
1124 | - | |||||||||||||||||||||||||
1125 | if (td->border != 0) {
| 0 | ||||||||||||||||||||||||
1126 | const QBrush oldBrush = painter->brush(); | - | ||||||||||||||||||||||||
1127 | const QPen oldPen = painter->pen(); | - | ||||||||||||||||||||||||
1128 | - | |||||||||||||||||||||||||
1129 | const qreal border = td->border.toReal(); | - | ||||||||||||||||||||||||
1130 | - | |||||||||||||||||||||||||
1131 | QRectF borderRect(cellRect.left() - border, cellRect.top() - border, cellRect.width() + border, cellRect.height() + border); | - | ||||||||||||||||||||||||
1132 | - | |||||||||||||||||||||||||
1133 | // invert the border style for cells | - | ||||||||||||||||||||||||
1134 | QTextFrameFormat::BorderStyle cellBorder = table->format().borderStyle(); | - | ||||||||||||||||||||||||
1135 | switch (cellBorder) { | - | ||||||||||||||||||||||||
1136 | case QTextFrameFormat::BorderStyle_Inset: never executed: case QTextFrameFormat::BorderStyle_Inset: | 0 | ||||||||||||||||||||||||
1137 | cellBorder = QTextFrameFormat::BorderStyle_Outset; | - | ||||||||||||||||||||||||
1138 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1139 | case QTextFrameFormat::BorderStyle_Outset: never executed: case QTextFrameFormat::BorderStyle_Outset: | 0 | ||||||||||||||||||||||||
1140 | cellBorder = QTextFrameFormat::BorderStyle_Inset; | - | ||||||||||||||||||||||||
1141 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1142 | case QTextFrameFormat::BorderStyle_Groove: never executed: case QTextFrameFormat::BorderStyle_Groove: | 0 | ||||||||||||||||||||||||
1143 | cellBorder = QTextFrameFormat::BorderStyle_Ridge; | - | ||||||||||||||||||||||||
1144 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1145 | case QTextFrameFormat::BorderStyle_Ridge: never executed: case QTextFrameFormat::BorderStyle_Ridge: | 0 | ||||||||||||||||||||||||
1146 | cellBorder = QTextFrameFormat::BorderStyle_Groove; | - | ||||||||||||||||||||||||
1147 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1148 | default: never executed: default: | 0 | ||||||||||||||||||||||||
1149 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1150 | } | - | ||||||||||||||||||||||||
1151 | - | |||||||||||||||||||||||||
1152 | drawBorder(painter, borderRect, topMargin, bottomMargin, | - | ||||||||||||||||||||||||
1153 | border, table->format().borderBrush(), cellBorder); | - | ||||||||||||||||||||||||
1154 | - | |||||||||||||||||||||||||
1155 | painter->setBrush(oldBrush); | - | ||||||||||||||||||||||||
1156 | painter->setPen(oldPen); | - | ||||||||||||||||||||||||
1157 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1158 | - | |||||||||||||||||||||||||
1159 | const QBrush bg = cell.format().background(); | - | ||||||||||||||||||||||||
1160 | const QPointF brushOrigin = painter->brushOrigin(); | - | ||||||||||||||||||||||||
1161 | if (bg.style() != Qt::NoBrush) {
| 0 | ||||||||||||||||||||||||
1162 | const qreal pageHeight = document->pageSize().height(); | - | ||||||||||||||||||||||||
1163 | const int topPage = pageHeight > 0 ? static_cast<int>(cellRect.top() / pageHeight) : 0;
| 0 | ||||||||||||||||||||||||
1164 | const int bottomPage = pageHeight > 0 ? static_cast<int>((cellRect.bottom()) / pageHeight) : 0;
| 0 | ||||||||||||||||||||||||
1165 | - | |||||||||||||||||||||||||
1166 | if (topPage == bottomPage)
| 0 | ||||||||||||||||||||||||
1167 | fillBackground(painter, cellRect, bg, cellRect.topLeft()); never executed: fillBackground(painter, cellRect, bg, cellRect.topLeft()); | 0 | ||||||||||||||||||||||||
1168 | else { | - | ||||||||||||||||||||||||
1169 | for (int i = topPage; i <= bottomPage; ++i) {
| 0 | ||||||||||||||||||||||||
1170 | QRectF clipped = cellRect.toRect(); | - | ||||||||||||||||||||||||
1171 | - | |||||||||||||||||||||||||
1172 | if (topPage != bottomPage) {
| 0 | ||||||||||||||||||||||||
1173 | const qreal top = qMax(i * pageHeight + topMargin, cell_context.clip.top()); | - | ||||||||||||||||||||||||
1174 | const qreal bottom = qMin((i + 1) * pageHeight - bottomMargin, cell_context.clip.bottom()); | - | ||||||||||||||||||||||||
1175 | - | |||||||||||||||||||||||||
1176 | clipped.setTop(qMax(clipped.top(), top)); | - | ||||||||||||||||||||||||
1177 | clipped.setBottom(qMin(clipped.bottom(), bottom)); | - | ||||||||||||||||||||||||
1178 | - | |||||||||||||||||||||||||
1179 | if (clipped.bottom() <= clipped.top())
| 0 | ||||||||||||||||||||||||
1180 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1181 | - | |||||||||||||||||||||||||
1182 | fillBackground(painter, clipped, bg, cellRect.topLeft()); | - | ||||||||||||||||||||||||
1183 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1184 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1185 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1186 | - | |||||||||||||||||||||||||
1187 | if (bg.style() > Qt::SolidPattern)
| 0 | ||||||||||||||||||||||||
1188 | painter->setBrushOrigin(cellRect.topLeft()); never executed: painter->setBrushOrigin(cellRect.topLeft()); | 0 | ||||||||||||||||||||||||
1189 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1190 | - | |||||||||||||||||||||||||
1191 | const QFixed verticalOffset = td->cellVerticalOffsets.at(c + r * table->columns()); | - | ||||||||||||||||||||||||
1192 | - | |||||||||||||||||||||||||
1193 | const QPointF cellPos = QPointF(cellRect.left() + leftPadding.toReal(), | - | ||||||||||||||||||||||||
1194 | cellRect.top() + (topPadding + verticalOffset).toReal()); | - | ||||||||||||||||||||||||
1195 | - | |||||||||||||||||||||||||
1196 | QTextBlock repaintBlock; | - | ||||||||||||||||||||||||
1197 | drawFlow(cellPos, painter, cell_context, cell.begin(), | - | ||||||||||||||||||||||||
1198 | td->childFrameMap.values(r + c * table->rows()), | - | ||||||||||||||||||||||||
1199 | &repaintBlock); | - | ||||||||||||||||||||||||
1200 | if (repaintBlock.isValid()) {
| 0 | ||||||||||||||||||||||||
1201 | *cursorBlockNeedingRepaint = repaintBlock; | - | ||||||||||||||||||||||||
1202 | *cursorBlockOffset = cellPos; | - | ||||||||||||||||||||||||
1203 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1204 | - | |||||||||||||||||||||||||
1205 | if (bg.style() > Qt::SolidPattern)
| 0 | ||||||||||||||||||||||||
1206 | painter->setBrushOrigin(brushOrigin); never executed: painter->setBrushOrigin(brushOrigin); | 0 | ||||||||||||||||||||||||
1207 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1208 | - | |||||||||||||||||||||||||
1209 | void QTextDocumentLayoutPrivate::drawFlow(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context, | - | ||||||||||||||||||||||||
1210 | QTextFrame::Iterator it, const QList<QTextFrame *> &floats, QTextBlock *cursorBlockNeedingRepaint) const | - | ||||||||||||||||||||||||
1211 | { | - | ||||||||||||||||||||||||
1212 | Q_Q(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
1213 | const bool inRootFrame = (!it.atEnd() && it.parentFrame() && it.parentFrame()->parentFrame() == 0);
| 0 | ||||||||||||||||||||||||
1214 | - | |||||||||||||||||||||||||
1215 | QVector<QCheckPoint>::ConstIterator lastVisibleCheckPoint = checkPoints.end(); | - | ||||||||||||||||||||||||
1216 | if (inRootFrame && context.clip.isValid()) {
| 0 | ||||||||||||||||||||||||
1217 | lastVisibleCheckPoint = std::lower_bound(checkPoints.begin(), checkPoints.end(), QFixed::fromReal(context.clip.bottom())); | - | ||||||||||||||||||||||||
1218 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1219 | - | |||||||||||||||||||||||||
1220 | QTextBlock previousBlock; | - | ||||||||||||||||||||||||
1221 | QTextFrame *previousFrame = 0; | - | ||||||||||||||||||||||||
1222 | - | |||||||||||||||||||||||||
1223 | for (; !it.atEnd(); ++it) {
| 0 | ||||||||||||||||||||||||
1224 | QTextFrame *c = it.currentFrame(); | - | ||||||||||||||||||||||||
1225 | - | |||||||||||||||||||||||||
1226 | if (inRootFrame && !checkPoints.isEmpty()) {
| 0 | ||||||||||||||||||||||||
1227 | int currentPosInDoc; | - | ||||||||||||||||||||||||
1228 | if (c)
| 0 | ||||||||||||||||||||||||
1229 | currentPosInDoc = c->firstPosition(); never executed: currentPosInDoc = c->firstPosition(); | 0 | ||||||||||||||||||||||||
1230 | else | - | ||||||||||||||||||||||||
1231 | currentPosInDoc = it.currentBlock().position(); never executed: currentPosInDoc = it.currentBlock().position(); | 0 | ||||||||||||||||||||||||
1232 | - | |||||||||||||||||||||||||
1233 | // if we're past what is already laid out then we're better off | - | ||||||||||||||||||||||||
1234 | // not trying to draw things that may not be positioned correctly yet | - | ||||||||||||||||||||||||
1235 | if (currentPosInDoc >= checkPoints.last().positionInFrame)
| 0 | ||||||||||||||||||||||||
1236 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1237 | - | |||||||||||||||||||||||||
1238 | if (lastVisibleCheckPoint != checkPoints.end()
| 0 | ||||||||||||||||||||||||
1239 | && context.clip.isValid()
| 0 | ||||||||||||||||||||||||
1240 | && currentPosInDoc >= lastVisibleCheckPoint->positionInFrame
| 0 | ||||||||||||||||||||||||
1241 | ) | - | ||||||||||||||||||||||||
1242 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1243 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1244 | - | |||||||||||||||||||||||||
1245 | if (c)
| 0 | ||||||||||||||||||||||||
1246 | drawFrame(offset, painter, context, c); never executed: drawFrame(offset, painter, context, c); | 0 | ||||||||||||||||||||||||
1247 | else { | - | ||||||||||||||||||||||||
1248 | QAbstractTextDocumentLayout::PaintContext pc = context; | - | ||||||||||||||||||||||||
1249 | if (isEmptyBlockAfterTable(it.currentBlock(), previousFrame))
| 0 | ||||||||||||||||||||||||
1250 | pc.selections.clear(); never executed: pc.selections.clear(); | 0 | ||||||||||||||||||||||||
1251 | drawBlock(offset, painter, pc, it.currentBlock(), inRootFrame); | - | ||||||||||||||||||||||||
1252 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1253 | - | |||||||||||||||||||||||||
1254 | // when entering a table and the previous block is empty | - | ||||||||||||||||||||||||
1255 | // then layoutFlow 'hides' the block that just causes a | - | ||||||||||||||||||||||||
1256 | // new line by positioning it /on/ the table border. as we | - | ||||||||||||||||||||||||
1257 | // draw that block before the table itself the decoration | - | ||||||||||||||||||||||||
1258 | // 'overpaints' the cursor and we need to paint it afterwards | - | ||||||||||||||||||||||||
1259 | // again | - | ||||||||||||||||||||||||
1260 | if (isEmptyBlockBeforeTable(previousBlock, previousBlock.blockFormat(), it)
| 0 | ||||||||||||||||||||||||
1261 | && previousBlock.contains(context.cursorPosition)
| 0 | ||||||||||||||||||||||||
1262 | ) { | - | ||||||||||||||||||||||||
1263 | *cursorBlockNeedingRepaint = previousBlock; | - | ||||||||||||||||||||||||
1264 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1265 | - | |||||||||||||||||||||||||
1266 | previousBlock = it.currentBlock(); | - | ||||||||||||||||||||||||
1267 | previousFrame = c; | - | ||||||||||||||||||||||||
1268 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1269 | - | |||||||||||||||||||||||||
1270 | for (int i = 0; i < floats.count(); ++i) {
| 0 | ||||||||||||||||||||||||
1271 | QTextFrame *frame = floats.at(i); | - | ||||||||||||||||||||||||
1272 | if (!isFrameFromInlineObject(frame)
| 0 | ||||||||||||||||||||||||
1273 | || frame->frameFormat().position() == QTextFrameFormat::InFlow)
| 0 | ||||||||||||||||||||||||
1274 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1275 | - | |||||||||||||||||||||||||
1276 | const int pos = frame->firstPosition() - 1; | - | ||||||||||||||||||||||||
1277 | QTextCharFormat format = const_cast<QTextDocumentLayout *>(q)->format(pos); | - | ||||||||||||||||||||||||
1278 | QTextObjectInterface *handler = q->handlerForObject(format.objectType()); | - | ||||||||||||||||||||||||
1279 | if (handler) {
| 0 | ||||||||||||||||||||||||
1280 | QRectF rect = frameBoundingRectInternal(frame); | - | ||||||||||||||||||||||||
1281 | handler->drawObject(painter, rect, document, pos, format); | - | ||||||||||||||||||||||||
1282 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1283 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1284 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1285 | - | |||||||||||||||||||||||||
1286 | void QTextDocumentLayoutPrivate::drawBlock(const QPointF &offset, QPainter *painter, | - | ||||||||||||||||||||||||
1287 | const QAbstractTextDocumentLayout::PaintContext &context, | - | ||||||||||||||||||||||||
1288 | const QTextBlock &bl, bool inRootFrame) const | - | ||||||||||||||||||||||||
1289 | { | - | ||||||||||||||||||||||||
1290 | const QTextLayout *tl = bl.layout(); | - | ||||||||||||||||||||||||
1291 | QRectF r = tl->boundingRect(); | - | ||||||||||||||||||||||||
1292 | r.translate(offset + tl->position()); | - | ||||||||||||||||||||||||
1293 | if (!bl.isVisible() || (context.clip.isValid() && (r.bottom() < context.clip.y() || r.top() > context.clip.bottom())))
| 0 | ||||||||||||||||||||||||
1294 | return; never executed: return; | 0 | ||||||||||||||||||||||||
1295 | // LDEBUG << debug_indent << "drawBlock" << bl.position() << "at" << offset << "br" << tl->boundingRect(); | - | ||||||||||||||||||||||||
1296 | - | |||||||||||||||||||||||||
1297 | QTextBlockFormat blockFormat = bl.blockFormat(); | - | ||||||||||||||||||||||||
1298 | - | |||||||||||||||||||||||||
1299 | QBrush bg = blockFormat.background(); | - | ||||||||||||||||||||||||
1300 | if (bg != Qt::NoBrush) {
| 0 | ||||||||||||||||||||||||
1301 | QRectF rect = r; | - | ||||||||||||||||||||||||
1302 | - | |||||||||||||||||||||||||
1303 | // extend the background rectangle if we're in the root frame with NoWrap, | - | ||||||||||||||||||||||||
1304 | // as the rect of the text block will then be only the width of the text | - | ||||||||||||||||||||||||
1305 | // instead of the full page width | - | ||||||||||||||||||||||||
1306 | if (inRootFrame && document->pageSize().width() <= 0) {
| 0 | ||||||||||||||||||||||||
1307 | const QTextFrameData *fd = data(document->rootFrame()); | - | ||||||||||||||||||||||||
1308 | rect.setRight((fd->size.width - fd->rightMargin).toReal()); | - | ||||||||||||||||||||||||
1309 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1310 | - | |||||||||||||||||||||||||
1311 | fillBackground(painter, rect, bg, r.topLeft()); | - | ||||||||||||||||||||||||
1312 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1313 | - | |||||||||||||||||||||||||
1314 | QVector<QTextLayout::FormatRange> selections; | - | ||||||||||||||||||||||||
1315 | int blpos = bl.position(); | - | ||||||||||||||||||||||||
1316 | int bllen = bl.length(); | - | ||||||||||||||||||||||||
1317 | const QTextCharFormat *selFormat = 0; | - | ||||||||||||||||||||||||
1318 | for (int i = 0; i < context.selections.size(); ++i) {
| 0 | ||||||||||||||||||||||||
1319 | const QAbstractTextDocumentLayout::Selection &range = context.selections.at(i); | - | ||||||||||||||||||||||||
1320 | const int selStart = range.cursor.selectionStart() - blpos; | - | ||||||||||||||||||||||||
1321 | const int selEnd = range.cursor.selectionEnd() - blpos; | - | ||||||||||||||||||||||||
1322 | if (selStart < bllen && selEnd > 0
| 0 | ||||||||||||||||||||||||
1323 | && selEnd > selStart) {
| 0 | ||||||||||||||||||||||||
1324 | QTextLayout::FormatRange o; | - | ||||||||||||||||||||||||
1325 | o.start = selStart; | - | ||||||||||||||||||||||||
1326 | o.length = selEnd - selStart; | - | ||||||||||||||||||||||||
1327 | o.format = range.format; | - | ||||||||||||||||||||||||
1328 | selections.append(o); | - | ||||||||||||||||||||||||
1329 | } else if (! range.cursor.hasSelection() && range.format.hasProperty(QTextFormat::FullWidthSelection) never executed: end of block
| 0 | ||||||||||||||||||||||||
1330 | && bl.contains(range.cursor.position())) {
| 0 | ||||||||||||||||||||||||
1331 | // for full width selections we don't require an actual selection, just | - | ||||||||||||||||||||||||
1332 | // a position to specify the line. that's more convenience in usage. | - | ||||||||||||||||||||||||
1333 | QTextLayout::FormatRange o; | - | ||||||||||||||||||||||||
1334 | QTextLine l = tl->lineForTextPosition(range.cursor.position() - blpos); | - | ||||||||||||||||||||||||
1335 | o.start = l.textStart(); | - | ||||||||||||||||||||||||
1336 | o.length = l.textLength(); | - | ||||||||||||||||||||||||
1337 | if (o.start + o.length == bllen - 1)
| 0 | ||||||||||||||||||||||||
1338 | ++o.length; // include newline never executed: ++o.length; | 0 | ||||||||||||||||||||||||
1339 | o.format = range.format; | - | ||||||||||||||||||||||||
1340 | selections.append(o); | - | ||||||||||||||||||||||||
1341 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1342 | if (selStart < 0 && selEnd >= 1)
| 0 | ||||||||||||||||||||||||
1343 | selFormat = &range.format; never executed: selFormat = &range.format; | 0 | ||||||||||||||||||||||||
1344 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1345 | - | |||||||||||||||||||||||||
1346 | QTextObject *object = document->objectForFormat(bl.blockFormat()); | - | ||||||||||||||||||||||||
1347 | if (object && object->format().toListFormat().style() != QTextListFormat::ListStyleUndefined)
| 0 | ||||||||||||||||||||||||
1348 | drawListItem(offset, painter, context, bl, selFormat); never executed: drawListItem(offset, painter, context, bl, selFormat); | 0 | ||||||||||||||||||||||||
1349 | - | |||||||||||||||||||||||||
1350 | QPen oldPen = painter->pen(); | - | ||||||||||||||||||||||||
1351 | painter->setPen(context.palette.color(QPalette::Text)); | - | ||||||||||||||||||||||||
1352 | - | |||||||||||||||||||||||||
1353 | tl->draw(painter, offset, selections, context.clip.isValid() ? (context.clip & clipRect) : clipRect); | - | ||||||||||||||||||||||||
1354 | - | |||||||||||||||||||||||||
1355 | if ((context.cursorPosition >= blpos && context.cursorPosition < blpos + bllen)
| 0 | ||||||||||||||||||||||||
1356 | || (context.cursorPosition < -1 && !tl->preeditAreaText().isEmpty())) {
| 0 | ||||||||||||||||||||||||
1357 | int cpos = context.cursorPosition; | - | ||||||||||||||||||||||||
1358 | if (cpos < -1)
| 0 | ||||||||||||||||||||||||
1359 | cpos = tl->preeditAreaPosition() - (cpos + 2); never executed: cpos = tl->preeditAreaPosition() - (cpos + 2); | 0 | ||||||||||||||||||||||||
1360 | else | - | ||||||||||||||||||||||||
1361 | cpos -= blpos; never executed: cpos -= blpos; | 0 | ||||||||||||||||||||||||
1362 | tl->drawCursor(painter, offset, cpos, cursorWidth); | - | ||||||||||||||||||||||||
1363 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1364 | - | |||||||||||||||||||||||||
1365 | if (blockFormat.hasProperty(QTextFormat::BlockTrailingHorizontalRulerWidth)) {
| 0 | ||||||||||||||||||||||||
1366 | const qreal width = blockFormat.lengthProperty(QTextFormat::BlockTrailingHorizontalRulerWidth).value(r.width()); | - | ||||||||||||||||||||||||
1367 | painter->setPen(context.palette.color(QPalette::Dark)); | - | ||||||||||||||||||||||||
1368 | qreal y = r.bottom(); | - | ||||||||||||||||||||||||
1369 | if (bl.length() == 1)
| 0 | ||||||||||||||||||||||||
1370 | y = r.top() + r.height() / 2; never executed: y = r.top() + r.height() / 2; | 0 | ||||||||||||||||||||||||
1371 | - | |||||||||||||||||||||||||
1372 | const qreal middleX = r.left() + r.width() / 2; | - | ||||||||||||||||||||||||
1373 | painter->drawLine(QLineF(middleX - width / 2, y, middleX + width / 2, y)); | - | ||||||||||||||||||||||||
1374 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1375 | - | |||||||||||||||||||||||||
1376 | painter->setPen(oldPen); | - | ||||||||||||||||||||||||
1377 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1378 | - | |||||||||||||||||||||||||
1379 | - | |||||||||||||||||||||||||
1380 | void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *painter, | - | ||||||||||||||||||||||||
1381 | const QAbstractTextDocumentLayout::PaintContext &context, | - | ||||||||||||||||||||||||
1382 | const QTextBlock &bl, const QTextCharFormat *selectionFormat) const | - | ||||||||||||||||||||||||
1383 | { | - | ||||||||||||||||||||||||
1384 | Q_Q(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
1385 | const QTextBlockFormat blockFormat = bl.blockFormat(); | - | ||||||||||||||||||||||||
1386 | const QTextCharFormat charFormat = QTextCursor(bl).charFormat(); | - | ||||||||||||||||||||||||
1387 | QFont font(charFormat.font()); | - | ||||||||||||||||||||||||
1388 | if (q->paintDevice())
| 0 | ||||||||||||||||||||||||
1389 | font = QFont(font, q->paintDevice()); never executed: font = QFont(font, q->paintDevice()); | 0 | ||||||||||||||||||||||||
1390 | - | |||||||||||||||||||||||||
1391 | const QFontMetrics fontMetrics(font); | - | ||||||||||||||||||||||||
1392 | QTextObject * const object = document->objectForFormat(blockFormat); | - | ||||||||||||||||||||||||
1393 | const QTextListFormat lf = object->format().toListFormat(); | - | ||||||||||||||||||||||||
1394 | int style = lf.style(); | - | ||||||||||||||||||||||||
1395 | QString itemText; | - | ||||||||||||||||||||||||
1396 | QSizeF size; | - | ||||||||||||||||||||||||
1397 | - | |||||||||||||||||||||||||
1398 | if (blockFormat.hasProperty(QTextFormat::ListStyle))
| 0 | ||||||||||||||||||||||||
1399 | style = QTextListFormat::Style(blockFormat.intProperty(QTextFormat::ListStyle)); never executed: style = QTextListFormat::Style(blockFormat.intProperty(QTextFormat::ListStyle)); | 0 | ||||||||||||||||||||||||
1400 | - | |||||||||||||||||||||||||
1401 | QTextLayout *layout = bl.layout(); | - | ||||||||||||||||||||||||
1402 | if (layout->lineCount() == 0)
| 0 | ||||||||||||||||||||||||
1403 | return; never executed: return; | 0 | ||||||||||||||||||||||||
1404 | QTextLine firstLine = layout->lineAt(0); | - | ||||||||||||||||||||||||
1405 | Q_ASSERT(firstLine.isValid()); | - | ||||||||||||||||||||||||
1406 | QPointF pos = (offset + layout->position()).toPoint(); | - | ||||||||||||||||||||||||
1407 | Qt::LayoutDirection dir = bl.textDirection(); | - | ||||||||||||||||||||||||
1408 | { | - | ||||||||||||||||||||||||
1409 | QRectF textRect = firstLine.naturalTextRect(); | - | ||||||||||||||||||||||||
1410 | pos += textRect.topLeft().toPoint(); | - | ||||||||||||||||||||||||
1411 | if (dir == Qt::RightToLeft)
| 0 | ||||||||||||||||||||||||
1412 | pos.rx() += textRect.width(); never executed: pos.rx() += textRect.width(); | 0 | ||||||||||||||||||||||||
1413 | } | - | ||||||||||||||||||||||||
1414 | - | |||||||||||||||||||||||||
1415 | switch (style) { | - | ||||||||||||||||||||||||
1416 | case QTextListFormat::ListDecimal: never executed: case QTextListFormat::ListDecimal: | 0 | ||||||||||||||||||||||||
1417 | case QTextListFormat::ListLowerAlpha: never executed: case QTextListFormat::ListLowerAlpha: | 0 | ||||||||||||||||||||||||
1418 | case QTextListFormat::ListUpperAlpha: never executed: case QTextListFormat::ListUpperAlpha: | 0 | ||||||||||||||||||||||||
1419 | case QTextListFormat::ListLowerRoman: never executed: case QTextListFormat::ListLowerRoman: | 0 | ||||||||||||||||||||||||
1420 | case QTextListFormat::ListUpperRoman: never executed: case QTextListFormat::ListUpperRoman: | 0 | ||||||||||||||||||||||||
1421 | itemText = static_cast<QTextList *>(object)->itemText(bl); | - | ||||||||||||||||||||||||
1422 | size.setWidth(fontMetrics.width(itemText)); | - | ||||||||||||||||||||||||
1423 | size.setHeight(fontMetrics.height()); | - | ||||||||||||||||||||||||
1424 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1425 | - | |||||||||||||||||||||||||
1426 | case QTextListFormat::ListSquare: never executed: case QTextListFormat::ListSquare: | 0 | ||||||||||||||||||||||||
1427 | case QTextListFormat::ListCircle: never executed: case QTextListFormat::ListCircle: | 0 | ||||||||||||||||||||||||
1428 | case QTextListFormat::ListDisc: never executed: case QTextListFormat::ListDisc: | 0 | ||||||||||||||||||||||||
1429 | size.setWidth(fontMetrics.lineSpacing() / 3); | - | ||||||||||||||||||||||||
1430 | size.setHeight(size.width()); | - | ||||||||||||||||||||||||
1431 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1432 | - | |||||||||||||||||||||||||
1433 | case QTextListFormat::ListStyleUndefined: never executed: case QTextListFormat::ListStyleUndefined: | 0 | ||||||||||||||||||||||||
1434 | return; never executed: return; | 0 | ||||||||||||||||||||||||
1435 | default: return; never executed: return; never executed: default: | 0 | ||||||||||||||||||||||||
1436 | } | - | ||||||||||||||||||||||||
1437 | - | |||||||||||||||||||||||||
1438 | QRectF r(pos, size); | - | ||||||||||||||||||||||||
1439 | - | |||||||||||||||||||||||||
1440 | qreal xoff = fontMetrics.width(QLatin1Char(' ')); | - | ||||||||||||||||||||||||
1441 | if (dir == Qt::LeftToRight)
| 0 | ||||||||||||||||||||||||
1442 | xoff = -xoff - size.width(); never executed: xoff = -xoff - size.width(); | 0 | ||||||||||||||||||||||||
1443 | r.translate( xoff, (fontMetrics.height() / 2) - (size.height() / 2)); | - | ||||||||||||||||||||||||
1444 | - | |||||||||||||||||||||||||
1445 | painter->save(); | - | ||||||||||||||||||||||||
1446 | - | |||||||||||||||||||||||||
1447 | painter->setRenderHint(QPainter::Antialiasing); | - | ||||||||||||||||||||||||
1448 | - | |||||||||||||||||||||||||
1449 | if (selectionFormat) {
| 0 | ||||||||||||||||||||||||
1450 | painter->setPen(QPen(selectionFormat->foreground(), 0)); | - | ||||||||||||||||||||||||
1451 | painter->fillRect(r, selectionFormat->background()); | - | ||||||||||||||||||||||||
1452 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
1453 | QBrush fg = charFormat.foreground(); | - | ||||||||||||||||||||||||
1454 | if (fg == Qt::NoBrush)
| 0 | ||||||||||||||||||||||||
1455 | fg = context.palette.text(); never executed: fg = context.palette.text(); | 0 | ||||||||||||||||||||||||
1456 | painter->setPen(QPen(fg, 0)); | - | ||||||||||||||||||||||||
1457 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1458 | - | |||||||||||||||||||||||||
1459 | QBrush brush = context.palette.brush(QPalette::Text); | - | ||||||||||||||||||||||||
1460 | - | |||||||||||||||||||||||||
1461 | switch (style) { | - | ||||||||||||||||||||||||
1462 | case QTextListFormat::ListDecimal: never executed: case QTextListFormat::ListDecimal: | 0 | ||||||||||||||||||||||||
1463 | case QTextListFormat::ListLowerAlpha: never executed: case QTextListFormat::ListLowerAlpha: | 0 | ||||||||||||||||||||||||
1464 | case QTextListFormat::ListUpperAlpha: never executed: case QTextListFormat::ListUpperAlpha: | 0 | ||||||||||||||||||||||||
1465 | case QTextListFormat::ListLowerRoman: never executed: case QTextListFormat::ListLowerRoman: | 0 | ||||||||||||||||||||||||
1466 | case QTextListFormat::ListUpperRoman: { never executed: case QTextListFormat::ListUpperRoman: | 0 | ||||||||||||||||||||||||
1467 | QTextLayout layout(itemText, font, q->paintDevice()); | - | ||||||||||||||||||||||||
1468 | layout.setCacheEnabled(true); | - | ||||||||||||||||||||||||
1469 | QTextOption option(Qt::AlignLeft | Qt::AlignAbsolute); | - | ||||||||||||||||||||||||
1470 | option.setTextDirection(dir); | - | ||||||||||||||||||||||||
1471 | layout.setTextOption(option); | - | ||||||||||||||||||||||||
1472 | layout.beginLayout(); | - | ||||||||||||||||||||||||
1473 | QTextLine line = layout.createLine(); | - | ||||||||||||||||||||||||
1474 | if (line.isValid())
| 0 | ||||||||||||||||||||||||
1475 | line.setLeadingIncluded(true); never executed: line.setLeadingIncluded(true); | 0 | ||||||||||||||||||||||||
1476 | layout.endLayout(); | - | ||||||||||||||||||||||||
1477 | layout.draw(painter, QPointF(r.left(), pos.y())); | - | ||||||||||||||||||||||||
1478 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1479 | } | - | ||||||||||||||||||||||||
1480 | case QTextListFormat::ListSquare: never executed: case QTextListFormat::ListSquare: | 0 | ||||||||||||||||||||||||
1481 | painter->fillRect(r, brush); | - | ||||||||||||||||||||||||
1482 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1483 | case QTextListFormat::ListCircle: never executed: case QTextListFormat::ListCircle: | 0 | ||||||||||||||||||||||||
1484 | painter->setPen(QPen(brush, 0)); | - | ||||||||||||||||||||||||
1485 | painter->drawEllipse(r.translated(0.5, 0.5)); // pixel align for sharper rendering | - | ||||||||||||||||||||||||
1486 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1487 | case QTextListFormat::ListDisc: never executed: case QTextListFormat::ListDisc: | 0 | ||||||||||||||||||||||||
1488 | painter->setBrush(brush); | - | ||||||||||||||||||||||||
1489 | painter->setPen(Qt::NoPen); | - | ||||||||||||||||||||||||
1490 | painter->drawEllipse(r); | - | ||||||||||||||||||||||||
1491 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1492 | case QTextListFormat::ListStyleUndefined: never executed: case QTextListFormat::ListStyleUndefined: | 0 | ||||||||||||||||||||||||
1493 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1494 | default: never executed: default: | 0 | ||||||||||||||||||||||||
1495 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1496 | } | - | ||||||||||||||||||||||||
1497 | - | |||||||||||||||||||||||||
1498 | painter->restore(); | - | ||||||||||||||||||||||||
1499 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1500 | - | |||||||||||||||||||||||||
1501 | static QFixed flowPosition(const QTextFrame::iterator it) | - | ||||||||||||||||||||||||
1502 | { | - | ||||||||||||||||||||||||
1503 | if (it.atEnd())
| 0 | ||||||||||||||||||||||||
1504 | return 0; never executed: return 0; | 0 | ||||||||||||||||||||||||
1505 | - | |||||||||||||||||||||||||
1506 | if (it.currentFrame()) {
| 0 | ||||||||||||||||||||||||
1507 | return data(it.currentFrame())->position.y; never executed: return data(it.currentFrame())->position.y; | 0 | ||||||||||||||||||||||||
1508 | } else { | - | ||||||||||||||||||||||||
1509 | QTextBlock block = it.currentBlock(); | - | ||||||||||||||||||||||||
1510 | QTextLayout *layout = block.layout(); | - | ||||||||||||||||||||||||
1511 | if (layout->lineCount() == 0)
| 0 | ||||||||||||||||||||||||
1512 | return QFixed::fromReal(layout->position().y()); never executed: return QFixed::fromReal(layout->position().y()); | 0 | ||||||||||||||||||||||||
1513 | else | - | ||||||||||||||||||||||||
1514 | return QFixed::fromReal(layout->position().y() + layout->lineAt(0).y()); never executed: return QFixed::fromReal(layout->position().y() + layout->lineAt(0).y()); | 0 | ||||||||||||||||||||||||
1515 | } | - | ||||||||||||||||||||||||
1516 | } | - | ||||||||||||||||||||||||
1517 | - | |||||||||||||||||||||||||
1518 | static QFixed firstChildPos(const QTextFrame *f) | - | ||||||||||||||||||||||||
1519 | { | - | ||||||||||||||||||||||||
1520 | return flowPosition(f->begin()); never executed: return flowPosition(f->begin()); | 0 | ||||||||||||||||||||||||
1521 | } | - | ||||||||||||||||||||||||
1522 | - | |||||||||||||||||||||||||
1523 | QTextLayoutStruct QTextDocumentLayoutPrivate::layoutCell(QTextTable *t, const QTextTableCell &cell, QFixed width, | - | ||||||||||||||||||||||||
1524 | int layoutFrom, int layoutTo, QTextTableData *td, | - | ||||||||||||||||||||||||
1525 | QFixed absoluteTableY, bool withPageBreaks) | - | ||||||||||||||||||||||||
1526 | { | - | ||||||||||||||||||||||||
1527 | LDEBUG << "layoutCell"; dead code: QMessageLogger(__FILE__, 1527, __PRETTY_FUNCTION__).debug() << "layoutCell"; | - | ||||||||||||||||||||||||
1528 | QTextLayoutStruct layoutStruct; | - | ||||||||||||||||||||||||
1529 | layoutStruct.frame = t; | - | ||||||||||||||||||||||||
1530 | layoutStruct.minimumWidth = 0; | - | ||||||||||||||||||||||||
1531 | layoutStruct.maximumWidth = QFIXED_MAX; | - | ||||||||||||||||||||||||
1532 | layoutStruct.y = 0; | - | ||||||||||||||||||||||||
1533 | - | |||||||||||||||||||||||||
1534 | const QTextFormat fmt = cell.format(); | - | ||||||||||||||||||||||||
1535 | const QFixed topPadding = td->topPadding(fmt); | - | ||||||||||||||||||||||||
1536 | if (withPageBreaks) {
| 0 | ||||||||||||||||||||||||
1537 | layoutStruct.frameY = absoluteTableY + td->rowPositions.at(cell.row()) + topPadding; | - | ||||||||||||||||||||||||
1538 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1539 | layoutStruct.x_left = 0; | - | ||||||||||||||||||||||||
1540 | layoutStruct.x_right = width; | - | ||||||||||||||||||||||||
1541 | // we get called with different widths all the time (for example for figuring | - | ||||||||||||||||||||||||
1542 | // out the min/max widths), so we always have to do the full layout ;( | - | ||||||||||||||||||||||||
1543 | // also when for example in a table layoutFrom/layoutTo affect only one cell, | - | ||||||||||||||||||||||||
1544 | // making that one cell grow the available width of the other cells may change | - | ||||||||||||||||||||||||
1545 | // (shrink) and therefore when layoutCell gets called for them they have to | - | ||||||||||||||||||||||||
1546 | // be re-laid out, even if layoutFrom/layoutTo is not in their range. Hence | - | ||||||||||||||||||||||||
1547 | // this line: | - | ||||||||||||||||||||||||
1548 | - | |||||||||||||||||||||||||
1549 | layoutStruct.pageHeight = QFixed::fromReal(document->pageSize().height()); | - | ||||||||||||||||||||||||
1550 | if (layoutStruct.pageHeight < 0 || !withPageBreaks)
| 0 | ||||||||||||||||||||||||
1551 | layoutStruct.pageHeight = QFIXED_MAX; never executed: layoutStruct.pageHeight = (2147483647/256); | 0 | ||||||||||||||||||||||||
1552 | const int currentPage = layoutStruct.currentPage(); | - | ||||||||||||||||||||||||
1553 | layoutStruct.pageTopMargin = td->effectiveTopMargin + td->cellSpacing + td->border + topPadding; | - | ||||||||||||||||||||||||
1554 | layoutStruct.pageBottomMargin = td->effectiveBottomMargin + td->cellSpacing + td->border + td->bottomPadding(fmt); | - | ||||||||||||||||||||||||
1555 | layoutStruct.pageBottom = (currentPage + 1) * layoutStruct.pageHeight - layoutStruct.pageBottomMargin; | - | ||||||||||||||||||||||||
1556 | - | |||||||||||||||||||||||||
1557 | layoutStruct.fullLayout = true; | - | ||||||||||||||||||||||||
1558 | - | |||||||||||||||||||||||||
1559 | QFixed pageTop = currentPage * layoutStruct.pageHeight + layoutStruct.pageTopMargin - layoutStruct.frameY; | - | ||||||||||||||||||||||||
1560 | layoutStruct.y = qMax(layoutStruct.y, pageTop); | - | ||||||||||||||||||||||||
1561 | - | |||||||||||||||||||||||||
1562 | const QList<QTextFrame *> childFrames = td->childFrameMap.values(cell.row() + cell.column() * t->rows()); | - | ||||||||||||||||||||||||
1563 | for (int i = 0; i < childFrames.size(); ++i) {
| 0 | ||||||||||||||||||||||||
1564 | QTextFrame *frame = childFrames.at(i); | - | ||||||||||||||||||||||||
1565 | QTextFrameData *cd = data(frame); | - | ||||||||||||||||||||||||
1566 | cd->sizeDirty = true; | - | ||||||||||||||||||||||||
1567 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1568 | - | |||||||||||||||||||||||||
1569 | layoutFlow(cell.begin(), &layoutStruct, layoutFrom, layoutTo, width); | - | ||||||||||||||||||||||||
1570 | - | |||||||||||||||||||||||||
1571 | QFixed floatMinWidth; | - | ||||||||||||||||||||||||
1572 | - | |||||||||||||||||||||||||
1573 | // floats that are located inside the text (like inline images) aren't taken into account by | - | ||||||||||||||||||||||||
1574 | // layoutFlow with regards to the cell height (layoutStruct->y), so for a safety measure we | - | ||||||||||||||||||||||||
1575 | // do that here. For example with <td><img align="right" src="..." />blah</td> | - | ||||||||||||||||||||||||
1576 | // when the image happens to be higher than the text | - | ||||||||||||||||||||||||
1577 | for (int i = 0; i < childFrames.size(); ++i) {
| 0 | ||||||||||||||||||||||||
1578 | QTextFrame *frame = childFrames.at(i); | - | ||||||||||||||||||||||||
1579 | QTextFrameData *cd = data(frame); | - | ||||||||||||||||||||||||
1580 | - | |||||||||||||||||||||||||
1581 | if (frame->frameFormat().position() != QTextFrameFormat::InFlow)
| 0 | ||||||||||||||||||||||||
1582 | 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 | ||||||||||||||||||||||||
1583 | - | |||||||||||||||||||||||||
1584 | floatMinWidth = qMax(floatMinWidth, cd->minimumWidth); | - | ||||||||||||||||||||||||
1585 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1586 | - | |||||||||||||||||||||||||
1587 | // constraint the maximumWidth by the minimum width of the fixed size floats, to | - | ||||||||||||||||||||||||
1588 | // keep them visible | - | ||||||||||||||||||||||||
1589 | layoutStruct.maximumWidth = qMax(layoutStruct.maximumWidth, floatMinWidth); | - | ||||||||||||||||||||||||
1590 | - | |||||||||||||||||||||||||
1591 | // as floats in cells get added to the table's float list but must not affect | - | ||||||||||||||||||||||||
1592 | // floats in other cells we must clear the list here. | - | ||||||||||||||||||||||||
1593 | data(t)->floats.clear(); | - | ||||||||||||||||||||||||
1594 | - | |||||||||||||||||||||||||
1595 | // qDebug() << "layoutCell done"; | - | ||||||||||||||||||||||||
1596 | - | |||||||||||||||||||||||||
1597 | return layoutStruct; never executed: return layoutStruct; | 0 | ||||||||||||||||||||||||
1598 | } | - | ||||||||||||||||||||||||
1599 | - | |||||||||||||||||||||||||
1600 | QRectF QTextDocumentLayoutPrivate::layoutTable(QTextTable *table, int layoutFrom, int layoutTo, QFixed parentY) | - | ||||||||||||||||||||||||
1601 | { | - | ||||||||||||||||||||||||
1602 | LDEBUG << "layoutTable"; dead code: QMessageLogger(__FILE__, 1602, __PRETTY_FUNCTION__).debug() << "layoutTable"; | - | ||||||||||||||||||||||||
1603 | QTextTableData *td = static_cast<QTextTableData *>(data(table)); | - | ||||||||||||||||||||||||
1604 | Q_ASSERT(td->sizeDirty); | - | ||||||||||||||||||||||||
1605 | const int rows = table->rows(); | - | ||||||||||||||||||||||||
1606 | const int columns = table->columns(); | - | ||||||||||||||||||||||||
1607 | - | |||||||||||||||||||||||||
1608 | const QTextTableFormat fmt = table->format(); | - | ||||||||||||||||||||||||
1609 | - | |||||||||||||||||||||||||
1610 | td->childFrameMap.clear(); | - | ||||||||||||||||||||||||
1611 | { | - | ||||||||||||||||||||||||
1612 | const QList<QTextFrame *> children = table->childFrames(); | - | ||||||||||||||||||||||||
1613 | for (int i = 0; i < children.count(); ++i) {
| 0 | ||||||||||||||||||||||||
1614 | QTextFrame *frame = children.at(i); | - | ||||||||||||||||||||||||
1615 | QTextTableCell cell = table->cellAt(frame->firstPosition()); | - | ||||||||||||||||||||||||
1616 | td->childFrameMap.insertMulti(cell.row() + cell.column() * rows, frame); | - | ||||||||||||||||||||||||
1617 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1618 | } | - | ||||||||||||||||||||||||
1619 | - | |||||||||||||||||||||||||
1620 | QVector<QTextLength> columnWidthConstraints = fmt.columnWidthConstraints(); | - | ||||||||||||||||||||||||
1621 | if (columnWidthConstraints.size() != columns)
| 0 | ||||||||||||||||||||||||
1622 | columnWidthConstraints.resize(columns); never executed: columnWidthConstraints.resize(columns); | 0 | ||||||||||||||||||||||||
1623 | Q_ASSERT(columnWidthConstraints.count() == columns); | - | ||||||||||||||||||||||||
1624 | - | |||||||||||||||||||||||||
1625 | const QFixed cellSpacing = td->cellSpacing = QFixed::fromReal(scaleToDevice(fmt.cellSpacing())); | - | ||||||||||||||||||||||||
1626 | td->deviceScale = scaleToDevice(qreal(1)); | - | ||||||||||||||||||||||||
1627 | td->cellPadding = QFixed::fromReal(scaleToDevice(fmt.cellPadding())); | - | ||||||||||||||||||||||||
1628 | const QFixed leftMargin = td->leftMargin + td->border + td->padding; | - | ||||||||||||||||||||||||
1629 | const QFixed rightMargin = td->rightMargin + td->border + td->padding; | - | ||||||||||||||||||||||||
1630 | const QFixed topMargin = td->topMargin + td->border + td->padding; | - | ||||||||||||||||||||||||
1631 | - | |||||||||||||||||||||||||
1632 | const QFixed absoluteTableY = parentY + td->position.y; | - | ||||||||||||||||||||||||
1633 | - | |||||||||||||||||||||||||
1634 | const QTextOption::WrapMode oldDefaultWrapMode = docPrivate->defaultTextOption.wrapMode(); | - | ||||||||||||||||||||||||
1635 | - | |||||||||||||||||||||||||
1636 | recalc_minmax_widths: code before this statement never executed: recalc_minmax_widths: | 0 | ||||||||||||||||||||||||
1637 | - | |||||||||||||||||||||||||
1638 | QFixed remainingWidth = td->contentsWidth; | - | ||||||||||||||||||||||||
1639 | // two (vertical) borders per cell per column | - | ||||||||||||||||||||||||
1640 | remainingWidth -= columns * 2 * td->border; | - | ||||||||||||||||||||||||
1641 | // inter-cell spacing | - | ||||||||||||||||||||||||
1642 | remainingWidth -= (columns - 1) * cellSpacing; | - | ||||||||||||||||||||||||
1643 | // cell spacing at the left and right hand side | - | ||||||||||||||||||||||||
1644 | remainingWidth -= 2 * cellSpacing; | - | ||||||||||||||||||||||||
1645 | // remember the width used to distribute to percentaged columns | - | ||||||||||||||||||||||||
1646 | const QFixed initialTotalWidth = remainingWidth; | - | ||||||||||||||||||||||||
1647 | - | |||||||||||||||||||||||||
1648 | td->widths.resize(columns); | - | ||||||||||||||||||||||||
1649 | td->widths.fill(0); | - | ||||||||||||||||||||||||
1650 | - | |||||||||||||||||||||||||
1651 | td->minWidths.resize(columns); | - | ||||||||||||||||||||||||
1652 | // start with a minimum width of 0. totally empty | - | ||||||||||||||||||||||||
1653 | // cells of default created tables are invisible otherwise | - | ||||||||||||||||||||||||
1654 | // and therefore hardly editable | - | ||||||||||||||||||||||||
1655 | td->minWidths.fill(1); | - | ||||||||||||||||||||||||
1656 | - | |||||||||||||||||||||||||
1657 | td->maxWidths.resize(columns); | - | ||||||||||||||||||||||||
1658 | td->maxWidths.fill(QFIXED_MAX); | - | ||||||||||||||||||||||||
1659 | - | |||||||||||||||||||||||||
1660 | // calculate minimum and maximum sizes of the columns | - | ||||||||||||||||||||||||
1661 | for (int i = 0; i < columns; ++i) {
| 0 | ||||||||||||||||||||||||
1662 | for (int row = 0; row < rows; ++row) {
| 0 | ||||||||||||||||||||||||
1663 | const QTextTableCell cell = table->cellAt(row, i); | - | ||||||||||||||||||||||||
1664 | const int cspan = cell.columnSpan(); | - | ||||||||||||||||||||||||
1665 | - | |||||||||||||||||||||||||
1666 | if (cspan > 1 && i != cell.column())
| 0 | ||||||||||||||||||||||||
1667 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1668 | - | |||||||||||||||||||||||||
1669 | const QTextFormat fmt = cell.format(); | - | ||||||||||||||||||||||||
1670 | const QFixed leftPadding = td->leftPadding(fmt); | - | ||||||||||||||||||||||||
1671 | const QFixed rightPadding = td->rightPadding(fmt); | - | ||||||||||||||||||||||||
1672 | const QFixed widthPadding = leftPadding + rightPadding; | - | ||||||||||||||||||||||||
1673 | - | |||||||||||||||||||||||||
1674 | // to figure out the min and the max width lay out the cell at | - | ||||||||||||||||||||||||
1675 | // maximum width. otherwise the maxwidth calculation sometimes | - | ||||||||||||||||||||||||
1676 | // returns wrong values | - | ||||||||||||||||||||||||
1677 | QTextLayoutStruct layoutStruct = layoutCell(table, cell, QFIXED_MAX, layoutFrom, | - | ||||||||||||||||||||||||
1678 | layoutTo, td, absoluteTableY, | - | ||||||||||||||||||||||||
1679 | /*withPageBreaks =*/false); | - | ||||||||||||||||||||||||
1680 | - | |||||||||||||||||||||||||
1681 | // distribute the minimum width over all columns the cell spans | - | ||||||||||||||||||||||||
1682 | QFixed widthToDistribute = layoutStruct.minimumWidth + widthPadding; | - | ||||||||||||||||||||||||
1683 | for (int n = 0; n < cspan; ++n) {
| 0 | ||||||||||||||||||||||||
1684 | const int col = i + n; | - | ||||||||||||||||||||||||
1685 | QFixed w = widthToDistribute / (cspan - n); | - | ||||||||||||||||||||||||
1686 | td->minWidths[col] = qMax(td->minWidths.at(col), w); | - | ||||||||||||||||||||||||
1687 | widthToDistribute -= td->minWidths.at(col); | - | ||||||||||||||||||||||||
1688 | if (widthToDistribute <= 0)
| 0 | ||||||||||||||||||||||||
1689 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1690 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1691 | - | |||||||||||||||||||||||||
1692 | QFixed maxW = td->maxWidths.at(i); | - | ||||||||||||||||||||||||
1693 | if (layoutStruct.maximumWidth != QFIXED_MAX) {
| 0 | ||||||||||||||||||||||||
1694 | if (maxW == QFIXED_MAX)
| 0 | ||||||||||||||||||||||||
1695 | maxW = layoutStruct.maximumWidth + widthPadding; never executed: maxW = layoutStruct.maximumWidth + widthPadding; | 0 | ||||||||||||||||||||||||
1696 | else | - | ||||||||||||||||||||||||
1697 | maxW = qMax(maxW, layoutStruct.maximumWidth + widthPadding); never executed: maxW = qMax(maxW, layoutStruct.maximumWidth + widthPadding); | 0 | ||||||||||||||||||||||||
1698 | } | - | ||||||||||||||||||||||||
1699 | if (maxW == QFIXED_MAX)
| 0 | ||||||||||||||||||||||||
1700 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1701 | - | |||||||||||||||||||||||||
1702 | widthToDistribute = maxW; | - | ||||||||||||||||||||||||
1703 | for (int n = 0; n < cspan; ++n) {
| 0 | ||||||||||||||||||||||||
1704 | const int col = i + n; | - | ||||||||||||||||||||||||
1705 | QFixed w = widthToDistribute / (cspan - n); | - | ||||||||||||||||||||||||
1706 | td->maxWidths[col] = qMax(td->minWidths.at(col), w); | - | ||||||||||||||||||||||||
1707 | widthToDistribute -= td->maxWidths.at(col); | - | ||||||||||||||||||||||||
1708 | if (widthToDistribute <= 0)
| 0 | ||||||||||||||||||||||||
1709 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1710 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1711 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1712 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1713 | - | |||||||||||||||||||||||||
1714 | // set fixed values, figure out total percentages used and number of | - | ||||||||||||||||||||||||
1715 | // variable length cells. Also assign the minimum width for variable columns. | - | ||||||||||||||||||||||||
1716 | QFixed totalPercentage; | - | ||||||||||||||||||||||||
1717 | int variableCols = 0; | - | ||||||||||||||||||||||||
1718 | QFixed totalMinWidth = 0; | - | ||||||||||||||||||||||||
1719 | for (int i = 0; i < columns; ++i) {
| 0 | ||||||||||||||||||||||||
1720 | const QTextLength &length = columnWidthConstraints.at(i); | - | ||||||||||||||||||||||||
1721 | if (length.type() == QTextLength::FixedLength) {
| 0 | ||||||||||||||||||||||||
1722 | td->minWidths[i] = td->widths[i] = qMax(scaleToDevice(QFixed::fromReal(length.rawValue())), td->minWidths.at(i)); | - | ||||||||||||||||||||||||
1723 | remainingWidth -= td->widths.at(i); | - | ||||||||||||||||||||||||
1724 | } else if (length.type() == QTextLength::PercentageLength) { never executed: end of block
| 0 | ||||||||||||||||||||||||
1725 | totalPercentage += QFixed::fromReal(length.rawValue()); | - | ||||||||||||||||||||||||
1726 | } else if (length.type() == QTextLength::VariableLength) { never executed: end of block
| 0 | ||||||||||||||||||||||||
1727 | variableCols++; | - | ||||||||||||||||||||||||
1728 | - | |||||||||||||||||||||||||
1729 | td->widths[i] = td->minWidths.at(i); | - | ||||||||||||||||||||||||
1730 | remainingWidth -= td->minWidths.at(i); | - | ||||||||||||||||||||||||
1731 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1732 | totalMinWidth += td->minWidths.at(i); | - | ||||||||||||||||||||||||
1733 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1734 | - | |||||||||||||||||||||||||
1735 | // set percentage values | - | ||||||||||||||||||||||||
1736 | { | - | ||||||||||||||||||||||||
1737 | const QFixed totalPercentagedWidth = initialTotalWidth * totalPercentage / 100; | - | ||||||||||||||||||||||||
1738 | QFixed remainingMinWidths = totalMinWidth; | - | ||||||||||||||||||||||||
1739 | for (int i = 0; i < columns; ++i) {
| 0 | ||||||||||||||||||||||||
1740 | remainingMinWidths -= td->minWidths.at(i); | - | ||||||||||||||||||||||||
1741 | if (columnWidthConstraints.at(i).type() == QTextLength::PercentageLength) {
| 0 | ||||||||||||||||||||||||
1742 | const QFixed allottedPercentage = QFixed::fromReal(columnWidthConstraints.at(i).rawValue()); | - | ||||||||||||||||||||||||
1743 | - | |||||||||||||||||||||||||
1744 | const QFixed percentWidth = totalPercentagedWidth * allottedPercentage / totalPercentage; | - | ||||||||||||||||||||||||
1745 | if (percentWidth >= td->minWidths.at(i)) {
| 0 | ||||||||||||||||||||||||
1746 | td->widths[i] = qBound(td->minWidths.at(i), percentWidth, remainingWidth - remainingMinWidths); | - | ||||||||||||||||||||||||
1747 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
1748 | td->widths[i] = td->minWidths.at(i); | - | ||||||||||||||||||||||||
1749 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1750 | remainingWidth -= td->widths.at(i); | - | ||||||||||||||||||||||||
1751 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1752 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1753 | } | - | ||||||||||||||||||||||||
1754 | - | |||||||||||||||||||||||||
1755 | // for variable columns distribute the remaining space | - | ||||||||||||||||||||||||
1756 | if (variableCols > 0 && remainingWidth > 0) {
| 0 | ||||||||||||||||||||||||
1757 | QVarLengthArray<int> columnsWithProperMaxSize; | - | ||||||||||||||||||||||||
1758 | for (int i = 0; i < columns; ++i)
| 0 | ||||||||||||||||||||||||
1759 | if (columnWidthConstraints.at(i).type() == QTextLength::VariableLength
| 0 | ||||||||||||||||||||||||
1760 | && td->maxWidths.at(i) != QFIXED_MAX)
| 0 | ||||||||||||||||||||||||
1761 | columnsWithProperMaxSize.append(i); never executed: columnsWithProperMaxSize.append(i); | 0 | ||||||||||||||||||||||||
1762 | - | |||||||||||||||||||||||||
1763 | QFixed lastRemainingWidth = remainingWidth; | - | ||||||||||||||||||||||||
1764 | while (remainingWidth > 0) {
| 0 | ||||||||||||||||||||||||
1765 | for (int k = 0; k < columnsWithProperMaxSize.count(); ++k) {
| 0 | ||||||||||||||||||||||||
1766 | const int col = columnsWithProperMaxSize[k]; | - | ||||||||||||||||||||||||
1767 | const int colsLeft = columnsWithProperMaxSize.count() - k; | - | ||||||||||||||||||||||||
1768 | const QFixed w = qMin(td->maxWidths.at(col) - td->widths.at(col), remainingWidth / colsLeft); | - | ||||||||||||||||||||||||
1769 | td->widths[col] += w; | - | ||||||||||||||||||||||||
1770 | remainingWidth -= w; | - | ||||||||||||||||||||||||
1771 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1772 | if (remainingWidth == lastRemainingWidth)
| 0 | ||||||||||||||||||||||||
1773 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1774 | lastRemainingWidth = remainingWidth; | - | ||||||||||||||||||||||||
1775 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1776 | - | |||||||||||||||||||||||||
1777 | if (remainingWidth > 0
| 0 | ||||||||||||||||||||||||
1778 | // don't unnecessarily grow variable length sized tables | - | ||||||||||||||||||||||||
1779 | && fmt.width().type() != QTextLength::VariableLength) {
| 0 | ||||||||||||||||||||||||
1780 | const QFixed widthPerAnySizedCol = remainingWidth / variableCols; | - | ||||||||||||||||||||||||
1781 | for (int col = 0; col < columns; ++col) {
| 0 | ||||||||||||||||||||||||
1782 | if (columnWidthConstraints.at(col).type() == QTextLength::VariableLength)
| 0 | ||||||||||||||||||||||||
1783 | td->widths[col] += widthPerAnySizedCol; never executed: td->widths[col] += widthPerAnySizedCol; | 0 | ||||||||||||||||||||||||
1784 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1785 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1786 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1787 | - | |||||||||||||||||||||||||
1788 | td->columnPositions.resize(columns); | - | ||||||||||||||||||||||||
1789 | td->columnPositions[0] = leftMargin /*includes table border*/ + cellSpacing + td->border; | - | ||||||||||||||||||||||||
1790 | - | |||||||||||||||||||||||||
1791 | for (int i = 1; i < columns; ++i)
| 0 | ||||||||||||||||||||||||
1792 | 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 | ||||||||||||||||||||||||
1793 | - | |||||||||||||||||||||||||
1794 | // - margin to compensate the + margin in columnPositions[0] | - | ||||||||||||||||||||||||
1795 | const QFixed contentsWidth = td->columnPositions.last() + td->widths.last() + td->padding + td->border + cellSpacing - leftMargin; | - | ||||||||||||||||||||||||
1796 | - | |||||||||||||||||||||||||
1797 | // if the table is too big and causes an overflow re-do the layout with WrapAnywhere as wrap | - | ||||||||||||||||||||||||
1798 | // mode | - | ||||||||||||||||||||||||
1799 | if (docPrivate->defaultTextOption.wrapMode() == QTextOption::WrapAtWordBoundaryOrAnywhere
| 0 | ||||||||||||||||||||||||
1800 | && contentsWidth > td->contentsWidth) {
| 0 | ||||||||||||||||||||||||
1801 | docPrivate->defaultTextOption.setWrapMode(QTextOption::WrapAnywhere); | - | ||||||||||||||||||||||||
1802 | // go back to the top of the function | - | ||||||||||||||||||||||||
1803 | goto recalc_minmax_widths; never executed: goto recalc_minmax_widths; | 0 | ||||||||||||||||||||||||
1804 | } | - | ||||||||||||||||||||||||
1805 | - | |||||||||||||||||||||||||
1806 | td->contentsWidth = contentsWidth; | - | ||||||||||||||||||||||||
1807 | - | |||||||||||||||||||||||||
1808 | docPrivate->defaultTextOption.setWrapMode(oldDefaultWrapMode); | - | ||||||||||||||||||||||||
1809 | - | |||||||||||||||||||||||||
1810 | td->heights.resize(rows); | - | ||||||||||||||||||||||||
1811 | td->heights.fill(0); | - | ||||||||||||||||||||||||
1812 | - | |||||||||||||||||||||||||
1813 | td->rowPositions.resize(rows); | - | ||||||||||||||||||||||||
1814 | td->rowPositions[0] = topMargin /*includes table border*/ + cellSpacing + td->border; | - | ||||||||||||||||||||||||
1815 | - | |||||||||||||||||||||||||
1816 | bool haveRowSpannedCells = false; | - | ||||||||||||||||||||||||
1817 | - | |||||||||||||||||||||||||
1818 | // need to keep track of cell heights for vertical alignment | - | ||||||||||||||||||||||||
1819 | QVector<QFixed> cellHeights; | - | ||||||||||||||||||||||||
1820 | cellHeights.reserve(rows * columns); | - | ||||||||||||||||||||||||
1821 | - | |||||||||||||||||||||||||
1822 | QFixed pageHeight = QFixed::fromReal(document->pageSize().height()); | - | ||||||||||||||||||||||||
1823 | if (pageHeight <= 0)
| 0 | ||||||||||||||||||||||||
1824 | pageHeight = QFIXED_MAX; never executed: pageHeight = (2147483647/256); | 0 | ||||||||||||||||||||||||
1825 | - | |||||||||||||||||||||||||
1826 | QVector<QFixed> heightToDistribute; | - | ||||||||||||||||||||||||
1827 | heightToDistribute.resize(columns); | - | ||||||||||||||||||||||||
1828 | - | |||||||||||||||||||||||||
1829 | td->headerHeight = 0; | - | ||||||||||||||||||||||||
1830 | const int headerRowCount = qMin(table->format().headerRowCount(), rows - 1); | - | ||||||||||||||||||||||||
1831 | const QFixed originalTopMargin = td->effectiveTopMargin; | - | ||||||||||||||||||||||||
1832 | bool hasDroppedTable = false; | - | ||||||||||||||||||||||||
1833 | - | |||||||||||||||||||||||||
1834 | // now that we have the column widths we can lay out all cells with the right width. | - | ||||||||||||||||||||||||
1835 | // spanning cells are only allowed to grow the last row spanned by the cell. | - | ||||||||||||||||||||||||
1836 | // | - | ||||||||||||||||||||||||
1837 | // ### this could be made faster by iterating over the cells array of QTextTable | - | ||||||||||||||||||||||||
1838 | for (int r = 0; r < rows; ++r) {
| 0 | ||||||||||||||||||||||||
1839 | td->calcRowPosition(r); | - | ||||||||||||||||||||||||
1840 | - | |||||||||||||||||||||||||
1841 | const int tableStartPage = (absoluteTableY / pageHeight).truncate(); | - | ||||||||||||||||||||||||
1842 | const int currentPage = ((td->rowPositions[r] + absoluteTableY) / pageHeight).truncate(); | - | ||||||||||||||||||||||||
1843 | const QFixed pageBottom = (currentPage + 1) * pageHeight - td->effectiveBottomMargin - absoluteTableY - cellSpacing - td->border; | - | ||||||||||||||||||||||||
1844 | const QFixed pageTop = currentPage * pageHeight + td->effectiveTopMargin - absoluteTableY + cellSpacing + td->border; | - | ||||||||||||||||||||||||
1845 | const QFixed nextPageTop = pageTop + pageHeight; | - | ||||||||||||||||||||||||
1846 | - | |||||||||||||||||||||||||
1847 | if (td->rowPositions[r] > pageBottom)
| 0 | ||||||||||||||||||||||||
1848 | td->rowPositions[r] = nextPageTop; never executed: td->rowPositions[r] = nextPageTop; | 0 | ||||||||||||||||||||||||
1849 | else if (td->rowPositions[r] < pageTop)
| 0 | ||||||||||||||||||||||||
1850 | td->rowPositions[r] = pageTop; never executed: td->rowPositions[r] = pageTop; | 0 | ||||||||||||||||||||||||
1851 | - | |||||||||||||||||||||||||
1852 | bool dropRowToNextPage = true; | - | ||||||||||||||||||||||||
1853 | int cellCountBeforeRow = cellHeights.size(); | - | ||||||||||||||||||||||||
1854 | - | |||||||||||||||||||||||||
1855 | // if we drop the row to the next page we need to subtract the drop | - | ||||||||||||||||||||||||
1856 | // distance from any row spanning cells | - | ||||||||||||||||||||||||
1857 | QFixed dropDistance = 0; | - | ||||||||||||||||||||||||
1858 | - | |||||||||||||||||||||||||
1859 | relayout: code before this statement never executed: relayout: | 0 | ||||||||||||||||||||||||
1860 | const int rowStartPage = ((td->rowPositions[r] + absoluteTableY) / pageHeight).truncate(); | - | ||||||||||||||||||||||||
1861 | // if any of the header rows or the first non-header row start on the next page | - | ||||||||||||||||||||||||
1862 | // then the entire header should be dropped | - | ||||||||||||||||||||||||
1863 | if (r <= headerRowCount && rowStartPage > tableStartPage && !hasDroppedTable) {
| 0 | ||||||||||||||||||||||||
1864 | td->rowPositions[0] = nextPageTop; | - | ||||||||||||||||||||||||
1865 | cellHeights.clear(); | - | ||||||||||||||||||||||||
1866 | td->effectiveTopMargin = originalTopMargin; | - | ||||||||||||||||||||||||
1867 | hasDroppedTable = true; | - | ||||||||||||||||||||||||
1868 | r = -1; | - | ||||||||||||||||||||||||
1869 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1870 | } | - | ||||||||||||||||||||||||
1871 | - | |||||||||||||||||||||||||
1872 | int rowCellCount = 0; | - | ||||||||||||||||||||||||
1873 | for (int c = 0; c < columns; ++c) {
| 0 | ||||||||||||||||||||||||
1874 | QTextTableCell cell = table->cellAt(r, c); | - | ||||||||||||||||||||||||
1875 | const int rspan = cell.rowSpan(); | - | ||||||||||||||||||||||||
1876 | const int cspan = cell.columnSpan(); | - | ||||||||||||||||||||||||
1877 | - | |||||||||||||||||||||||||
1878 | if (cspan > 1 && cell.column() != c)
| 0 | ||||||||||||||||||||||||
1879 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1880 | - | |||||||||||||||||||||||||
1881 | if (rspan > 1) {
| 0 | ||||||||||||||||||||||||
1882 | haveRowSpannedCells = true; | - | ||||||||||||||||||||||||
1883 | - | |||||||||||||||||||||||||
1884 | const int cellRow = cell.row(); | - | ||||||||||||||||||||||||
1885 | if (cellRow != r) {
| 0 | ||||||||||||||||||||||||
1886 | // the last row gets all the remaining space | - | ||||||||||||||||||||||||
1887 | if (cellRow + rspan - 1 == r)
| 0 | ||||||||||||||||||||||||
1888 | 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 | ||||||||||||||||||||||||
1889 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1890 | } | - | ||||||||||||||||||||||||
1891 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1892 | - | |||||||||||||||||||||||||
1893 | const QTextFormat fmt = cell.format(); | - | ||||||||||||||||||||||||
1894 | - | |||||||||||||||||||||||||
1895 | const QFixed topPadding = td->topPadding(fmt); | - | ||||||||||||||||||||||||
1896 | const QFixed bottomPadding = td->bottomPadding(fmt); | - | ||||||||||||||||||||||||
1897 | const QFixed leftPadding = td->leftPadding(fmt); | - | ||||||||||||||||||||||||
1898 | const QFixed rightPadding = td->rightPadding(fmt); | - | ||||||||||||||||||||||||
1899 | const QFixed widthPadding = leftPadding + rightPadding; | - | ||||||||||||||||||||||||
1900 | - | |||||||||||||||||||||||||
1901 | ++rowCellCount; | - | ||||||||||||||||||||||||
1902 | - | |||||||||||||||||||||||||
1903 | const QFixed width = td->cellWidth(c, cspan) - widthPadding; | - | ||||||||||||||||||||||||
1904 | QTextLayoutStruct layoutStruct = layoutCell(table, cell, width, | - | ||||||||||||||||||||||||
1905 | layoutFrom, layoutTo, | - | ||||||||||||||||||||||||
1906 | td, absoluteTableY, | - | ||||||||||||||||||||||||
1907 | /*withPageBreaks =*/true); | - | ||||||||||||||||||||||||
1908 | - | |||||||||||||||||||||||||
1909 | const QFixed height = layoutStruct.y + bottomPadding + topPadding; | - | ||||||||||||||||||||||||
1910 | - | |||||||||||||||||||||||||
1911 | if (rspan > 1)
| 0 | ||||||||||||||||||||||||
1912 | heightToDistribute[c] = height + dropDistance; never executed: heightToDistribute[c] = height + dropDistance; | 0 | ||||||||||||||||||||||||
1913 | else | - | ||||||||||||||||||||||||
1914 | td->heights[r] = qMax(td->heights.at(r), height); never executed: td->heights[r] = qMax(td->heights.at(r), height); | 0 | ||||||||||||||||||||||||
1915 | - | |||||||||||||||||||||||||
1916 | cellHeights.append(layoutStruct.y); | - | ||||||||||||||||||||||||
1917 | - | |||||||||||||||||||||||||
1918 | QFixed childPos = td->rowPositions.at(r) + topPadding + flowPosition(cell.begin()); | - | ||||||||||||||||||||||||
1919 | if (childPos < pageBottom)
| 0 | ||||||||||||||||||||||||
1920 | dropRowToNextPage = false; never executed: dropRowToNextPage = false; | 0 | ||||||||||||||||||||||||
1921 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1922 | - | |||||||||||||||||||||||||
1923 | if (rowCellCount > 0 && dropRowToNextPage) {
| 0 | ||||||||||||||||||||||||
1924 | dropDistance = nextPageTop - td->rowPositions[r]; | - | ||||||||||||||||||||||||
1925 | td->rowPositions[r] = nextPageTop; | - | ||||||||||||||||||||||||
1926 | td->heights[r] = 0; | - | ||||||||||||||||||||||||
1927 | dropRowToNextPage = false; | - | ||||||||||||||||||||||||
1928 | cellHeights.resize(cellCountBeforeRow); | - | ||||||||||||||||||||||||
1929 | if (r > headerRowCount)
| 0 | ||||||||||||||||||||||||
1930 | td->heights[r-1] = pageBottom - td->rowPositions[r-1]; never executed: td->heights[r-1] = pageBottom - td->rowPositions[r-1]; | 0 | ||||||||||||||||||||||||
1931 | goto relayout; never executed: goto relayout; | 0 | ||||||||||||||||||||||||
1932 | } | - | ||||||||||||||||||||||||
1933 | - | |||||||||||||||||||||||||
1934 | if (haveRowSpannedCells) {
| 0 | ||||||||||||||||||||||||
1935 | const QFixed effectiveHeight = td->heights.at(r) + td->border + cellSpacing + td->border; | - | ||||||||||||||||||||||||
1936 | for (int c = 0; c < columns; ++c)
| 0 | ||||||||||||||||||||||||
1937 | heightToDistribute[c] = qMax(heightToDistribute.at(c) - effectiveHeight - dropDistance, QFixed(0)); never executed: heightToDistribute[c] = qMax(heightToDistribute.at(c) - effectiveHeight - dropDistance, QFixed(0)); | 0 | ||||||||||||||||||||||||
1938 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1939 | - | |||||||||||||||||||||||||
1940 | if (r == headerRowCount - 1) {
| 0 | ||||||||||||||||||||||||
1941 | td->headerHeight = td->rowPositions[r] + td->heights[r] - td->rowPositions[0] + td->cellSpacing + 2 * td->border; | - | ||||||||||||||||||||||||
1942 | td->headerHeight -= td->headerHeight * (td->headerHeight / pageHeight).truncate(); | - | ||||||||||||||||||||||||
1943 | td->effectiveTopMargin += td->headerHeight; | - | ||||||||||||||||||||||||
1944 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1945 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1946 | - | |||||||||||||||||||||||||
1947 | td->effectiveTopMargin = originalTopMargin; | - | ||||||||||||||||||||||||
1948 | - | |||||||||||||||||||||||||
1949 | // now that all cells have been properly laid out, we can compute the | - | ||||||||||||||||||||||||
1950 | // vertical offsets for vertical alignment | - | ||||||||||||||||||||||||
1951 | td->cellVerticalOffsets.resize(rows * columns); | - | ||||||||||||||||||||||||
1952 | int cellIndex = 0; | - | ||||||||||||||||||||||||
1953 | for (int r = 0; r < rows; ++r) {
| 0 | ||||||||||||||||||||||||
1954 | for (int c = 0; c < columns; ++c) {
| 0 | ||||||||||||||||||||||||
1955 | QTextTableCell cell = table->cellAt(r, c); | - | ||||||||||||||||||||||||
1956 | if (cell.row() != r || cell.column() != c)
| 0 | ||||||||||||||||||||||||
1957 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||
1958 | - | |||||||||||||||||||||||||
1959 | const int rowSpan = cell.rowSpan(); | - | ||||||||||||||||||||||||
1960 | const QFixed availableHeight = td->rowPositions.at(r + rowSpan - 1) + td->heights.at(r + rowSpan - 1) - td->rowPositions.at(r); | - | ||||||||||||||||||||||||
1961 | - | |||||||||||||||||||||||||
1962 | const QTextCharFormat cellFormat = cell.format(); | - | ||||||||||||||||||||||||
1963 | const QFixed cellHeight = cellHeights.at(cellIndex++) + td->topPadding(cellFormat) + td->bottomPadding(cellFormat); | - | ||||||||||||||||||||||||
1964 | - | |||||||||||||||||||||||||
1965 | QFixed offset = 0; | - | ||||||||||||||||||||||||
1966 | switch (cellFormat.verticalAlignment()) { | - | ||||||||||||||||||||||||
1967 | case QTextCharFormat::AlignMiddle: never executed: case QTextCharFormat::AlignMiddle: | 0 | ||||||||||||||||||||||||
1968 | offset = (availableHeight - cellHeight) / 2; | - | ||||||||||||||||||||||||
1969 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1970 | case QTextCharFormat::AlignBottom: never executed: case QTextCharFormat::AlignBottom: | 0 | ||||||||||||||||||||||||
1971 | offset = availableHeight - cellHeight; | - | ||||||||||||||||||||||||
1972 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1973 | default: never executed: default: | 0 | ||||||||||||||||||||||||
1974 | break; never executed: break; | 0 | ||||||||||||||||||||||||
1975 | }; | - | ||||||||||||||||||||||||
1976 | - | |||||||||||||||||||||||||
1977 | for (int rd = 0; rd < cell.rowSpan(); ++rd) {
| 0 | ||||||||||||||||||||||||
1978 | for (int cd = 0; cd < cell.columnSpan(); ++cd) {
| 0 | ||||||||||||||||||||||||
1979 | const int index = (c + cd) + (r + rd) * columns; | - | ||||||||||||||||||||||||
1980 | td->cellVerticalOffsets[index] = offset; | - | ||||||||||||||||||||||||
1981 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1982 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1983 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1984 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1985 | - | |||||||||||||||||||||||||
1986 | td->minimumWidth = td->columnPositions.at(0); | - | ||||||||||||||||||||||||
1987 | for (int i = 0; i < columns; ++i) {
| 0 | ||||||||||||||||||||||||
1988 | td->minimumWidth += td->minWidths.at(i) + 2 * td->border + cellSpacing; | - | ||||||||||||||||||||||||
1989 | } never executed: end of block | 0 | ||||||||||||||||||||||||
1990 | td->minimumWidth += rightMargin - td->border; | - | ||||||||||||||||||||||||
1991 | - | |||||||||||||||||||||||||
1992 | td->maximumWidth = td->columnPositions.at(0); | - | ||||||||||||||||||||||||
1993 | for (int i = 0; i < columns; ++i)
| 0 | ||||||||||||||||||||||||
1994 | if (td->maxWidths.at(i) != QFIXED_MAX)
| 0 | ||||||||||||||||||||||||
1995 | td->maximumWidth += td->maxWidths.at(i) + 2 * td->border + cellSpacing; never executed: td->maximumWidth += td->maxWidths.at(i) + 2 * td->border + cellSpacing; | 0 | ||||||||||||||||||||||||
1996 | td->maximumWidth += rightMargin - td->border; | - | ||||||||||||||||||||||||
1997 | - | |||||||||||||||||||||||||
1998 | td->updateTableSize(); | - | ||||||||||||||||||||||||
1999 | td->sizeDirty = false; | - | ||||||||||||||||||||||||
2000 | return QRectF(); // invalid rect -> update everything never executed: return QRectF(); | 0 | ||||||||||||||||||||||||
2001 | } | - | ||||||||||||||||||||||||
2002 | - | |||||||||||||||||||||||||
2003 | void QTextDocumentLayoutPrivate::positionFloat(QTextFrame *frame, QTextLine *currentLine) | - | ||||||||||||||||||||||||
2004 | { | - | ||||||||||||||||||||||||
2005 | QTextFrameData *fd = data(frame); | - | ||||||||||||||||||||||||
2006 | - | |||||||||||||||||||||||||
2007 | QTextFrame *parent = frame->parentFrame(); | - | ||||||||||||||||||||||||
2008 | Q_ASSERT(parent); | - | ||||||||||||||||||||||||
2009 | QTextFrameData *pd = data(parent); | - | ||||||||||||||||||||||||
2010 | Q_ASSERT(pd && pd->currentLayoutStruct); | - | ||||||||||||||||||||||||
2011 | - | |||||||||||||||||||||||||
2012 | QTextLayoutStruct *layoutStruct = pd->currentLayoutStruct; | - | ||||||||||||||||||||||||
2013 | - | |||||||||||||||||||||||||
2014 | if (!pd->floats.contains(frame))
| 0 | ||||||||||||||||||||||||
2015 | pd->floats.append(frame); never executed: pd->floats.append(frame); | 0 | ||||||||||||||||||||||||
2016 | fd->layoutDirty = true; | - | ||||||||||||||||||||||||
2017 | Q_ASSERT(!fd->sizeDirty); | - | ||||||||||||||||||||||||
2018 | - | |||||||||||||||||||||||||
2019 | // qDebug() << "positionFloat:" << frame << "width=" << fd->size.width; | - | ||||||||||||||||||||||||
2020 | QFixed y = layoutStruct->y; | - | ||||||||||||||||||||||||
2021 | if (currentLine) {
| 0 | ||||||||||||||||||||||||
2022 | QFixed left, right; | - | ||||||||||||||||||||||||
2023 | floatMargins(y, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2024 | // qDebug() << "have line: right=" << right << "left=" << left << "textWidth=" << currentLine->width(); | - | ||||||||||||||||||||||||
2025 | if (right - left < QFixed::fromReal(currentLine->naturalTextWidth()) + fd->size.width) {
| 0 | ||||||||||||||||||||||||
2026 | layoutStruct->pendingFloats.append(frame); | - | ||||||||||||||||||||||||
2027 | // qDebug() << " adding to pending list"; | - | ||||||||||||||||||||||||
2028 | return; never executed: return; | 0 | ||||||||||||||||||||||||
2029 | } | - | ||||||||||||||||||||||||
2030 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2031 | - | |||||||||||||||||||||||||
2032 | bool frameSpansIntoNextPage = (y + layoutStruct->frameY + fd->size.height > layoutStruct->pageBottom); | - | ||||||||||||||||||||||||
2033 | if (frameSpansIntoNextPage && fd->size.height <= layoutStruct->pageHeight) {
| 0 | ||||||||||||||||||||||||
2034 | layoutStruct->newPage(); | - | ||||||||||||||||||||||||
2035 | y = layoutStruct->y; | - | ||||||||||||||||||||||||
2036 | - | |||||||||||||||||||||||||
2037 | frameSpansIntoNextPage = false; | - | ||||||||||||||||||||||||
2038 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2039 | - | |||||||||||||||||||||||||
2040 | y = findY(y, layoutStruct, fd->size.width); | - | ||||||||||||||||||||||||
2041 | - | |||||||||||||||||||||||||
2042 | QFixed left, right; | - | ||||||||||||||||||||||||
2043 | floatMargins(y, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2044 | - | |||||||||||||||||||||||||
2045 | if (frame->frameFormat().position() == QTextFrameFormat::FloatLeft) {
| 0 | ||||||||||||||||||||||||
2046 | fd->position.x = left; | - | ||||||||||||||||||||||||
2047 | fd->position.y = y; | - | ||||||||||||||||||||||||
2048 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2049 | fd->position.x = right - fd->size.width; | - | ||||||||||||||||||||||||
2050 | fd->position.y = y; | - | ||||||||||||||||||||||||
2051 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2052 | - | |||||||||||||||||||||||||
2053 | layoutStruct->minimumWidth = qMax(layoutStruct->minimumWidth, fd->minimumWidth); | - | ||||||||||||||||||||||||
2054 | layoutStruct->maximumWidth = qMin(layoutStruct->maximumWidth, fd->maximumWidth); | - | ||||||||||||||||||||||||
2055 | - | |||||||||||||||||||||||||
2056 | // qDebug()<< "float positioned at " << fd->position.x << fd->position.y; | - | ||||||||||||||||||||||||
2057 | fd->layoutDirty = false; | - | ||||||||||||||||||||||||
2058 | - | |||||||||||||||||||||||||
2059 | // If the frame is a table, then positioning it will affect the size if it covers more than | - | ||||||||||||||||||||||||
2060 | // one page, because of page breaks and repeating the header. | - | ||||||||||||||||||||||||
2061 | if (qobject_cast<QTextTable *>(frame) != 0)
| 0 | ||||||||||||||||||||||||
2062 | fd->sizeDirty = frameSpansIntoNextPage; never executed: fd->sizeDirty = frameSpansIntoNextPage; | 0 | ||||||||||||||||||||||||
2063 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2064 | - | |||||||||||||||||||||||||
2065 | QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed parentY) | - | ||||||||||||||||||||||||
2066 | { | - | ||||||||||||||||||||||||
2067 | LDEBUG << "layoutFrame (pre)"; dead code: QMessageLogger(__FILE__, 2067, __PRETTY_FUNCTION__).debug() << "layoutFrame (pre)"; | - | ||||||||||||||||||||||||
2068 | Q_ASSERT(data(f)->sizeDirty); | - | ||||||||||||||||||||||||
2069 | // qDebug("layouting frame (%d--%d), parent=%p", f->firstPosition(), f->lastPosition(), f->parentFrame()); | - | ||||||||||||||||||||||||
2070 | - | |||||||||||||||||||||||||
2071 | QTextFrameFormat fformat = f->frameFormat(); | - | ||||||||||||||||||||||||
2072 | - | |||||||||||||||||||||||||
2073 | QTextFrame *parent = f->parentFrame(); | - | ||||||||||||||||||||||||
2074 | const QTextFrameData *pd = parent ? data(parent) : 0;
| 0 | ||||||||||||||||||||||||
2075 | - | |||||||||||||||||||||||||
2076 | const qreal maximumWidth = qMax(qreal(0), pd ? pd->contentsWidth.toReal() : document->pageSize().width()); | - | ||||||||||||||||||||||||
2077 | QFixed width = QFixed::fromReal(fformat.width().value(maximumWidth)); | - | ||||||||||||||||||||||||
2078 | if (fformat.width().type() == QTextLength::FixedLength)
| 0 | ||||||||||||||||||||||||
2079 | width = scaleToDevice(width); never executed: width = scaleToDevice(width); | 0 | ||||||||||||||||||||||||
2080 | - | |||||||||||||||||||||||||
2081 | const QFixed maximumHeight = pd ? pd->contentsHeight : -1;
| 0 | ||||||||||||||||||||||||
2082 | const QFixed height = (maximumHeight != -1 || fformat.height().type() != QTextLength::PercentageLength)
| 0 | ||||||||||||||||||||||||
2083 | ? QFixed::fromReal(fformat.height().value(maximumHeight.toReal())) | - | ||||||||||||||||||||||||
2084 | : -1; | - | ||||||||||||||||||||||||
2085 | - | |||||||||||||||||||||||||
2086 | return layoutFrame(f, layoutFrom, layoutTo, width, height, parentY); never executed: return layoutFrame(f, layoutFrom, layoutTo, width, height, parentY); | 0 | ||||||||||||||||||||||||
2087 | } | - | ||||||||||||||||||||||||
2088 | - | |||||||||||||||||||||||||
2089 | QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed frameWidth, QFixed frameHeight, QFixed parentY) | - | ||||||||||||||||||||||||
2090 | { | - | ||||||||||||||||||||||||
2091 | LDEBUG << "layoutFrame from=" << layoutFrom << "to=" << layoutTo; dead code: QMessageLogger(__FILE__, 2091, __PRETTY_FUNCTION__).debug() << "layoutFrame from=" << layoutFrom << "to=" << layoutTo; | - | ||||||||||||||||||||||||
2092 | Q_ASSERT(data(f)->sizeDirty); | - | ||||||||||||||||||||||||
2093 | // qDebug("layouting frame (%d--%d), parent=%p", f->firstPosition(), f->lastPosition(), f->parentFrame()); | - | ||||||||||||||||||||||||
2094 | - | |||||||||||||||||||||||||
2095 | QTextFrameData *fd = data(f); | - | ||||||||||||||||||||||||
2096 | QFixed newContentsWidth; | - | ||||||||||||||||||||||||
2097 | - | |||||||||||||||||||||||||
2098 | bool fullLayout = false; | - | ||||||||||||||||||||||||
2099 | { | - | ||||||||||||||||||||||||
2100 | QTextFrameFormat fformat = f->frameFormat(); | - | ||||||||||||||||||||||||
2101 | // set sizes of this frame from the format | - | ||||||||||||||||||||||||
2102 | QFixed tm = QFixed::fromReal(fformat.topMargin()); | - | ||||||||||||||||||||||||
2103 | if (tm != fd->topMargin) {
| 0 | ||||||||||||||||||||||||
2104 | fd->topMargin = tm; | - | ||||||||||||||||||||||||
2105 | fullLayout = true; | - | ||||||||||||||||||||||||
2106 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2107 | QFixed bm = QFixed::fromReal(fformat.bottomMargin()); | - | ||||||||||||||||||||||||
2108 | if (bm != fd->bottomMargin) {
| 0 | ||||||||||||||||||||||||
2109 | fd->bottomMargin = bm; | - | ||||||||||||||||||||||||
2110 | fullLayout = true; | - | ||||||||||||||||||||||||
2111 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2112 | fd->leftMargin = QFixed::fromReal(fformat.leftMargin()); | - | ||||||||||||||||||||||||
2113 | fd->rightMargin = QFixed::fromReal(fformat.rightMargin()); | - | ||||||||||||||||||||||||
2114 | QFixed b = QFixed::fromReal(fformat.border()); | - | ||||||||||||||||||||||||
2115 | if (b != fd->border) {
| 0 | ||||||||||||||||||||||||
2116 | fd->border = b; | - | ||||||||||||||||||||||||
2117 | fullLayout = true; | - | ||||||||||||||||||||||||
2118 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2119 | QFixed p = QFixed::fromReal(fformat.padding()); | - | ||||||||||||||||||||||||
2120 | if (p != fd->padding) {
| 0 | ||||||||||||||||||||||||
2121 | fd->padding = p; | - | ||||||||||||||||||||||||
2122 | fullLayout = true; | - | ||||||||||||||||||||||||
2123 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2124 | - | |||||||||||||||||||||||||
2125 | QTextFrame *parent = f->parentFrame(); | - | ||||||||||||||||||||||||
2126 | const QTextFrameData *pd = parent ? data(parent) : 0;
| 0 | ||||||||||||||||||||||||
2127 | - | |||||||||||||||||||||||||
2128 | // accumulate top and bottom margins | - | ||||||||||||||||||||||||
2129 | if (parent) {
| 0 | ||||||||||||||||||||||||
2130 | fd->effectiveTopMargin = pd->effectiveTopMargin + fd->topMargin + fd->border + fd->padding; | - | ||||||||||||||||||||||||
2131 | fd->effectiveBottomMargin = pd->effectiveBottomMargin + fd->topMargin + fd->border + fd->padding; | - | ||||||||||||||||||||||||
2132 | - | |||||||||||||||||||||||||
2133 | if (qobject_cast<QTextTable *>(parent)) {
| 0 | ||||||||||||||||||||||||
2134 | const QTextTableData *td = static_cast<const QTextTableData *>(pd); | - | ||||||||||||||||||||||||
2135 | fd->effectiveTopMargin += td->cellSpacing + td->border + td->cellPadding; | - | ||||||||||||||||||||||||
2136 | fd->effectiveBottomMargin += td->cellSpacing + td->border + td->cellPadding; | - | ||||||||||||||||||||||||
2137 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2138 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2139 | fd->effectiveTopMargin = fd->topMargin + fd->border + fd->padding; | - | ||||||||||||||||||||||||
2140 | fd->effectiveBottomMargin = fd->bottomMargin + fd->border + fd->padding; | - | ||||||||||||||||||||||||
2141 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2142 | - | |||||||||||||||||||||||||
2143 | newContentsWidth = frameWidth - 2*(fd->border + fd->padding) | - | ||||||||||||||||||||||||
2144 | - fd->leftMargin - fd->rightMargin; | - | ||||||||||||||||||||||||
2145 | - | |||||||||||||||||||||||||
2146 | if (frameHeight != -1) {
| 0 | ||||||||||||||||||||||||
2147 | fd->contentsHeight = frameHeight - 2*(fd->border + fd->padding) | - | ||||||||||||||||||||||||
2148 | - fd->topMargin - fd->bottomMargin; | - | ||||||||||||||||||||||||
2149 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2150 | fd->contentsHeight = frameHeight; | - | ||||||||||||||||||||||||
2151 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2152 | } | - | ||||||||||||||||||||||||
2153 | - | |||||||||||||||||||||||||
2154 | if (isFrameFromInlineObject(f)) {
| 0 | ||||||||||||||||||||||||
2155 | // never reached, handled in resizeInlineObject/positionFloat instead | - | ||||||||||||||||||||||||
2156 | return QRectF(); never executed: return QRectF(); | 0 | ||||||||||||||||||||||||
2157 | } | - | ||||||||||||||||||||||||
2158 | - | |||||||||||||||||||||||||
2159 | if (QTextTable *table = qobject_cast<QTextTable *>(f)) {
| 0 | ||||||||||||||||||||||||
2160 | fd->contentsWidth = newContentsWidth; | - | ||||||||||||||||||||||||
2161 | return layoutTable(table, layoutFrom, layoutTo, parentY); never executed: return layoutTable(table, layoutFrom, layoutTo, parentY); | 0 | ||||||||||||||||||||||||
2162 | } | - | ||||||||||||||||||||||||
2163 | - | |||||||||||||||||||||||||
2164 | // set fd->contentsWidth temporarily, so that layoutFrame for the children | - | ||||||||||||||||||||||||
2165 | // picks the right width. We'll initialize it properly at the end of this | - | ||||||||||||||||||||||||
2166 | // function. | - | ||||||||||||||||||||||||
2167 | fd->contentsWidth = newContentsWidth; | - | ||||||||||||||||||||||||
2168 | - | |||||||||||||||||||||||||
2169 | QTextLayoutStruct layoutStruct; | - | ||||||||||||||||||||||||
2170 | layoutStruct.frame = f; | - | ||||||||||||||||||||||||
2171 | layoutStruct.x_left = fd->leftMargin + fd->border + fd->padding; | - | ||||||||||||||||||||||||
2172 | layoutStruct.x_right = layoutStruct.x_left + newContentsWidth; | - | ||||||||||||||||||||||||
2173 | layoutStruct.y = fd->topMargin + fd->border + fd->padding; | - | ||||||||||||||||||||||||
2174 | layoutStruct.frameY = parentY + fd->position.y; | - | ||||||||||||||||||||||||
2175 | layoutStruct.contentsWidth = 0; | - | ||||||||||||||||||||||||
2176 | layoutStruct.minimumWidth = 0; | - | ||||||||||||||||||||||||
2177 | layoutStruct.maximumWidth = QFIXED_MAX; | - | ||||||||||||||||||||||||
2178 | layoutStruct.fullLayout = fullLayout || (fd->oldContentsWidth != newContentsWidth);
| 0 | ||||||||||||||||||||||||
2179 | layoutStruct.updateRect = QRectF(QPointF(0, 0), QSizeF(qreal(INT_MAX), qreal(INT_MAX))); | - | ||||||||||||||||||||||||
2180 | LDEBUG << "layoutStruct: x_left" << layoutStruct.x_left << "x_right" << layoutStruct.x_right dead code: QMessageLogger(__FILE__, 2180, __PRETTY_FUNCTION__).debug() << "layoutStruct: x_left" << layoutStruct.x_left << "x_right" << layoutStruct.x_right << "fullLayout" << layoutStruct.fullLayout; | - | ||||||||||||||||||||||||
2181 | << "fullLayout" << layoutStruct.fullLayout; dead code: QMessageLogger(__FILE__, 2180, __PRETTY_FUNCTION__).debug() << "layoutStruct: x_left" << layoutStruct.x_left << "x_right" << layoutStruct.x_right << "fullLayout" << layoutStruct.fullLayout; | - | ||||||||||||||||||||||||
2182 | fd->oldContentsWidth = newContentsWidth; | - | ||||||||||||||||||||||||
2183 | - | |||||||||||||||||||||||||
2184 | layoutStruct.pageHeight = QFixed::fromReal(document->pageSize().height()); | - | ||||||||||||||||||||||||
2185 | if (layoutStruct.pageHeight < 0)
| 0 | ||||||||||||||||||||||||
2186 | layoutStruct.pageHeight = QFIXED_MAX; never executed: layoutStruct.pageHeight = (2147483647/256); | 0 | ||||||||||||||||||||||||
2187 | - | |||||||||||||||||||||||||
2188 | const int currentPage = layoutStruct.pageHeight == 0 ? 0 : (layoutStruct.frameY / layoutStruct.pageHeight).truncate();
| 0 | ||||||||||||||||||||||||
2189 | layoutStruct.pageTopMargin = fd->effectiveTopMargin; | - | ||||||||||||||||||||||||
2190 | layoutStruct.pageBottomMargin = fd->effectiveBottomMargin; | - | ||||||||||||||||||||||||
2191 | layoutStruct.pageBottom = (currentPage + 1) * layoutStruct.pageHeight - layoutStruct.pageBottomMargin; | - | ||||||||||||||||||||||||
2192 | - | |||||||||||||||||||||||||
2193 | if (!f->parentFrame())
| 0 | ||||||||||||||||||||||||
2194 | idealWidth = 0; // reset never executed: idealWidth = 0; | 0 | ||||||||||||||||||||||||
2195 | - | |||||||||||||||||||||||||
2196 | QTextFrame::Iterator it = f->begin(); | - | ||||||||||||||||||||||||
2197 | layoutFlow(it, &layoutStruct, layoutFrom, layoutTo); | - | ||||||||||||||||||||||||
2198 | - | |||||||||||||||||||||||||
2199 | QFixed maxChildFrameWidth = 0; | - | ||||||||||||||||||||||||
2200 | QList<QTextFrame *> children = f->childFrames(); | - | ||||||||||||||||||||||||
2201 | for (int i = 0; i < children.size(); ++i) {
| 0 | ||||||||||||||||||||||||
2202 | QTextFrame *c = children.at(i); | - | ||||||||||||||||||||||||
2203 | QTextFrameData *cd = data(c); | - | ||||||||||||||||||||||||
2204 | maxChildFrameWidth = qMax(maxChildFrameWidth, cd->size.width); | - | ||||||||||||||||||||||||
2205 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2206 | - | |||||||||||||||||||||||||
2207 | const QFixed marginWidth = 2*(fd->border + fd->padding) + fd->leftMargin + fd->rightMargin; | - | ||||||||||||||||||||||||
2208 | if (!f->parentFrame()) {
| 0 | ||||||||||||||||||||||||
2209 | idealWidth = qMax(maxChildFrameWidth, layoutStruct.contentsWidth).toReal(); | - | ||||||||||||||||||||||||
2210 | idealWidth += marginWidth.toReal(); | - | ||||||||||||||||||||||||
2211 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2212 | - | |||||||||||||||||||||||||
2213 | QFixed actualWidth = qMax(newContentsWidth, qMax(maxChildFrameWidth, layoutStruct.contentsWidth)); | - | ||||||||||||||||||||||||
2214 | fd->contentsWidth = actualWidth; | - | ||||||||||||||||||||||||
2215 | if (newContentsWidth <= 0) { // nowrap layout?
| 0 | ||||||||||||||||||||||||
2216 | fd->contentsWidth = newContentsWidth; | - | ||||||||||||||||||||||||
2217 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2218 | - | |||||||||||||||||||||||||
2219 | fd->minimumWidth = layoutStruct.minimumWidth; | - | ||||||||||||||||||||||||
2220 | fd->maximumWidth = layoutStruct.maximumWidth; | - | ||||||||||||||||||||||||
2221 | - | |||||||||||||||||||||||||
2222 | fd->size.height = fd->contentsHeight == -1
| 0 | ||||||||||||||||||||||||
2223 | ? layoutStruct.y + fd->border + fd->padding + fd->bottomMargin | - | ||||||||||||||||||||||||
2224 | : fd->contentsHeight + 2*(fd->border + fd->padding) + fd->topMargin + fd->bottomMargin; | - | ||||||||||||||||||||||||
2225 | fd->size.width = actualWidth + marginWidth; | - | ||||||||||||||||||||||||
2226 | fd->sizeDirty = false; | - | ||||||||||||||||||||||||
2227 | if (layoutStruct.updateRectForFloats.isValid())
| 0 | ||||||||||||||||||||||||
2228 | layoutStruct.updateRect |= layoutStruct.updateRectForFloats; never executed: layoutStruct.updateRect |= layoutStruct.updateRectForFloats; | 0 | ||||||||||||||||||||||||
2229 | return layoutStruct.updateRect; never executed: return layoutStruct.updateRect; | 0 | ||||||||||||||||||||||||
2230 | } | - | ||||||||||||||||||||||||
2231 | - | |||||||||||||||||||||||||
2232 | void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QTextLayoutStruct *layoutStruct, | - | ||||||||||||||||||||||||
2233 | int layoutFrom, int layoutTo, QFixed width) | - | ||||||||||||||||||||||||
2234 | { | - | ||||||||||||||||||||||||
2235 | LDEBUG << "layoutFlow from=" << layoutFrom << "to=" << layoutTo; dead code: QMessageLogger(__FILE__, 2235, __PRETTY_FUNCTION__).debug() << "layoutFlow from=" << layoutFrom << "to=" << layoutTo; | - | ||||||||||||||||||||||||
2236 | QTextFrameData *fd = data(layoutStruct->frame); | - | ||||||||||||||||||||||||
2237 | - | |||||||||||||||||||||||||
2238 | fd->currentLayoutStruct = layoutStruct; | - | ||||||||||||||||||||||||
2239 | - | |||||||||||||||||||||||||
2240 | QTextFrame::Iterator previousIt; | - | ||||||||||||||||||||||||
2241 | - | |||||||||||||||||||||||||
2242 | const bool inRootFrame = (it.parentFrame() == document->rootFrame()); | - | ||||||||||||||||||||||||
2243 | if (inRootFrame) {
| 0 | ||||||||||||||||||||||||
2244 | bool redoCheckPoints = layoutStruct->fullLayout || checkPoints.isEmpty();
| 0 | ||||||||||||||||||||||||
2245 | - | |||||||||||||||||||||||||
2246 | if (!redoCheckPoints) {
| 0 | ||||||||||||||||||||||||
2247 | QVector<QCheckPoint>::Iterator checkPoint = std::lower_bound(checkPoints.begin(), checkPoints.end(), layoutFrom); | - | ||||||||||||||||||||||||
2248 | if (checkPoint != checkPoints.end()) {
| 0 | ||||||||||||||||||||||||
2249 | if (checkPoint != checkPoints.begin())
| 0 | ||||||||||||||||||||||||
2250 | --checkPoint; never executed: --checkPoint; | 0 | ||||||||||||||||||||||||
2251 | - | |||||||||||||||||||||||||
2252 | layoutStruct->y = checkPoint->y; | - | ||||||||||||||||||||||||
2253 | layoutStruct->frameY = checkPoint->frameY; | - | ||||||||||||||||||||||||
2254 | layoutStruct->minimumWidth = checkPoint->minimumWidth; | - | ||||||||||||||||||||||||
2255 | layoutStruct->maximumWidth = checkPoint->maximumWidth; | - | ||||||||||||||||||||||||
2256 | layoutStruct->contentsWidth = checkPoint->contentsWidth; | - | ||||||||||||||||||||||||
2257 | - | |||||||||||||||||||||||||
2258 | if (layoutStruct->pageHeight > 0) {
| 0 | ||||||||||||||||||||||||
2259 | int page = layoutStruct->currentPage(); | - | ||||||||||||||||||||||||
2260 | layoutStruct->pageBottom = (page + 1) * layoutStruct->pageHeight - layoutStruct->pageBottomMargin; | - | ||||||||||||||||||||||||
2261 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2262 | - | |||||||||||||||||||||||||
2263 | it = frameIteratorForTextPosition(checkPoint->positionInFrame); | - | ||||||||||||||||||||||||
2264 | checkPoints.resize(checkPoint - checkPoints.begin() + 1); | - | ||||||||||||||||||||||||
2265 | - | |||||||||||||||||||||||||
2266 | if (checkPoint != checkPoints.begin()) {
| 0 | ||||||||||||||||||||||||
2267 | previousIt = it; | - | ||||||||||||||||||||||||
2268 | --previousIt; | - | ||||||||||||||||||||||||
2269 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2270 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2271 | redoCheckPoints = true; | - | ||||||||||||||||||||||||
2272 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2273 | } | - | ||||||||||||||||||||||||
2274 | - | |||||||||||||||||||||||||
2275 | if (redoCheckPoints) {
| 0 | ||||||||||||||||||||||||
2276 | checkPoints.clear(); | - | ||||||||||||||||||||||||
2277 | QCheckPoint cp; | - | ||||||||||||||||||||||||
2278 | cp.y = layoutStruct->y; | - | ||||||||||||||||||||||||
2279 | cp.frameY = layoutStruct->frameY; | - | ||||||||||||||||||||||||
2280 | cp.positionInFrame = 0; | - | ||||||||||||||||||||||||
2281 | cp.minimumWidth = layoutStruct->minimumWidth; | - | ||||||||||||||||||||||||
2282 | cp.maximumWidth = layoutStruct->maximumWidth; | - | ||||||||||||||||||||||||
2283 | cp.contentsWidth = layoutStruct->contentsWidth; | - | ||||||||||||||||||||||||
2284 | checkPoints.append(cp); | - | ||||||||||||||||||||||||
2285 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2286 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2287 | - | |||||||||||||||||||||||||
2288 | QTextBlockFormat previousBlockFormat = previousIt.currentBlock().blockFormat(); | - | ||||||||||||||||||||||||
2289 | - | |||||||||||||||||||||||||
2290 | QFixed maximumBlockWidth = 0; | - | ||||||||||||||||||||||||
2291 | while (!it.atEnd()) {
| 0 | ||||||||||||||||||||||||
2292 | QTextFrame *c = it.currentFrame(); | - | ||||||||||||||||||||||||
2293 | - | |||||||||||||||||||||||||
2294 | int docPos; | - | ||||||||||||||||||||||||
2295 | if (it.currentFrame())
| 0 | ||||||||||||||||||||||||
2296 | docPos = it.currentFrame()->firstPosition(); never executed: docPos = it.currentFrame()->firstPosition(); | 0 | ||||||||||||||||||||||||
2297 | else | - | ||||||||||||||||||||||||
2298 | docPos = it.currentBlock().position(); never executed: docPos = it.currentBlock().position(); | 0 | ||||||||||||||||||||||||
2299 | - | |||||||||||||||||||||||||
2300 | if (inRootFrame) {
| 0 | ||||||||||||||||||||||||
2301 | if (qAbs(layoutStruct->y - checkPoints.last().y) > 2000) {
| 0 | ||||||||||||||||||||||||
2302 | QFixed left, right; | - | ||||||||||||||||||||||||
2303 | floatMargins(layoutStruct->y, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2304 | if (left == layoutStruct->x_left && right == layoutStruct->x_right) {
| 0 | ||||||||||||||||||||||||
2305 | QCheckPoint p; | - | ||||||||||||||||||||||||
2306 | p.y = layoutStruct->y; | - | ||||||||||||||||||||||||
2307 | p.frameY = layoutStruct->frameY; | - | ||||||||||||||||||||||||
2308 | p.positionInFrame = docPos; | - | ||||||||||||||||||||||||
2309 | p.minimumWidth = layoutStruct->minimumWidth; | - | ||||||||||||||||||||||||
2310 | p.maximumWidth = layoutStruct->maximumWidth; | - | ||||||||||||||||||||||||
2311 | p.contentsWidth = layoutStruct->contentsWidth; | - | ||||||||||||||||||||||||
2312 | checkPoints.append(p); | - | ||||||||||||||||||||||||
2313 | - | |||||||||||||||||||||||||
2314 | if (currentLazyLayoutPosition != -1
| 0 | ||||||||||||||||||||||||
2315 | && docPos > currentLazyLayoutPosition + lazyLayoutStepSize)
| 0 | ||||||||||||||||||||||||
2316 | break; never executed: break; | 0 | ||||||||||||||||||||||||
2317 | - | |||||||||||||||||||||||||
2318 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2319 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2320 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2321 | - | |||||||||||||||||||||||||
2322 | if (c) {
| 0 | ||||||||||||||||||||||||
2323 | // position child frame | - | ||||||||||||||||||||||||
2324 | QTextFrameData *cd = data(c); | - | ||||||||||||||||||||||||
2325 | - | |||||||||||||||||||||||||
2326 | QTextFrameFormat fformat = c->frameFormat(); | - | ||||||||||||||||||||||||
2327 | - | |||||||||||||||||||||||||
2328 | if (fformat.position() == QTextFrameFormat::InFlow) {
| 0 | ||||||||||||||||||||||||
2329 | if (fformat.pageBreakPolicy() & QTextFormat::PageBreak_AlwaysBefore)
| 0 | ||||||||||||||||||||||||
2330 | layoutStruct->newPage(); never executed: layoutStruct->newPage(); | 0 | ||||||||||||||||||||||||
2331 | - | |||||||||||||||||||||||||
2332 | QFixed left, right; | - | ||||||||||||||||||||||||
2333 | floatMargins(layoutStruct->y, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2334 | left = qMax(left, layoutStruct->x_left); | - | ||||||||||||||||||||||||
2335 | right = qMin(right, layoutStruct->x_right); | - | ||||||||||||||||||||||||
2336 | - | |||||||||||||||||||||||||
2337 | if (right - left < cd->size.width) {
| 0 | ||||||||||||||||||||||||
2338 | layoutStruct->y = findY(layoutStruct->y, layoutStruct, cd->size.width); | - | ||||||||||||||||||||||||
2339 | floatMargins(layoutStruct->y, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2340 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2341 | - | |||||||||||||||||||||||||
2342 | QFixedPoint pos(left, layoutStruct->y); | - | ||||||||||||||||||||||||
2343 | - | |||||||||||||||||||||||||
2344 | Qt::Alignment align = Qt::AlignLeft; | - | ||||||||||||||||||||||||
2345 | - | |||||||||||||||||||||||||
2346 | QTextTable *table = qobject_cast<QTextTable *>(c); | - | ||||||||||||||||||||||||
2347 | - | |||||||||||||||||||||||||
2348 | if (table)
| 0 | ||||||||||||||||||||||||
2349 | align = table->format().alignment() & Qt::AlignHorizontal_Mask; never executed: align = table->format().alignment() & Qt::AlignHorizontal_Mask; | 0 | ||||||||||||||||||||||||
2350 | - | |||||||||||||||||||||||||
2351 | // detect whether we have any alignment in the document that disallows optimizations, | - | ||||||||||||||||||||||||
2352 | // such as not laying out the document again in a textedit with wrapping disabled. | - | ||||||||||||||||||||||||
2353 | if (inRootFrame && !(align & Qt::AlignLeft))
| 0 | ||||||||||||||||||||||||
2354 | contentHasAlignment = true; never executed: contentHasAlignment = true; | 0 | ||||||||||||||||||||||||
2355 | - | |||||||||||||||||||||||||
2356 | cd->position = pos; | - | ||||||||||||||||||||||||
2357 | - | |||||||||||||||||||||||||
2358 | if (document->pageSize().height() > 0.0f)
| 0 | ||||||||||||||||||||||||
2359 | cd->sizeDirty = true; never executed: cd->sizeDirty = true; | 0 | ||||||||||||||||||||||||
2360 | - | |||||||||||||||||||||||||
2361 | if (cd->sizeDirty) {
| 0 | ||||||||||||||||||||||||
2362 | if (width != 0)
| 0 | ||||||||||||||||||||||||
2363 | layoutFrame(c, layoutFrom, layoutTo, width, -1, layoutStruct->frameY); never executed: layoutFrame(c, layoutFrom, layoutTo, width, -1, layoutStruct->frameY); | 0 | ||||||||||||||||||||||||
2364 | else | - | ||||||||||||||||||||||||
2365 | layoutFrame(c, layoutFrom, layoutTo, layoutStruct->frameY); never executed: layoutFrame(c, layoutFrom, layoutTo, layoutStruct->frameY); | 0 | ||||||||||||||||||||||||
2366 | - | |||||||||||||||||||||||||
2367 | QFixed absoluteChildPos = table ? pos.y + static_cast<QTextTableData *>(data(table))->rowPositions.at(0) : pos.y + firstChildPos(c);
| 0 | ||||||||||||||||||||||||
2368 | absoluteChildPos += layoutStruct->frameY; | - | ||||||||||||||||||||||||
2369 | - | |||||||||||||||||||||||||
2370 | // drop entire frame to next page if first child of frame is on next page | - | ||||||||||||||||||||||||
2371 | if (absoluteChildPos > layoutStruct->pageBottom) {
| 0 | ||||||||||||||||||||||||
2372 | layoutStruct->newPage(); | - | ||||||||||||||||||||||||
2373 | pos.y = layoutStruct->y; | - | ||||||||||||||||||||||||
2374 | - | |||||||||||||||||||||||||
2375 | cd->position = pos; | - | ||||||||||||||||||||||||
2376 | cd->sizeDirty = true; | - | ||||||||||||||||||||||||
2377 | - | |||||||||||||||||||||||||
2378 | if (width != 0)
| 0 | ||||||||||||||||||||||||
2379 | layoutFrame(c, layoutFrom, layoutTo, width, -1, layoutStruct->frameY); never executed: layoutFrame(c, layoutFrom, layoutTo, width, -1, layoutStruct->frameY); | 0 | ||||||||||||||||||||||||
2380 | else | - | ||||||||||||||||||||||||
2381 | layoutFrame(c, layoutFrom, layoutTo, layoutStruct->frameY); never executed: layoutFrame(c, layoutFrom, layoutTo, layoutStruct->frameY); | 0 | ||||||||||||||||||||||||
2382 | } | - | ||||||||||||||||||||||||
2383 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2384 | - | |||||||||||||||||||||||||
2385 | // align only if there is space for alignment | - | ||||||||||||||||||||||||
2386 | if (right - left > cd->size.width) {
| 0 | ||||||||||||||||||||||||
2387 | if (align & Qt::AlignRight)
| 0 | ||||||||||||||||||||||||
2388 | pos.x += layoutStruct->x_right - cd->size.width; never executed: pos.x += layoutStruct->x_right - cd->size.width; | 0 | ||||||||||||||||||||||||
2389 | else if (align & Qt::AlignHCenter)
| 0 | ||||||||||||||||||||||||
2390 | pos.x += (layoutStruct->x_right - cd->size.width) / 2; never executed: pos.x += (layoutStruct->x_right - cd->size.width) / 2; | 0 | ||||||||||||||||||||||||
2391 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2392 | - | |||||||||||||||||||||||||
2393 | cd->position = pos; | - | ||||||||||||||||||||||||
2394 | - | |||||||||||||||||||||||||
2395 | layoutStruct->y += cd->size.height; | - | ||||||||||||||||||||||||
2396 | const int page = layoutStruct->currentPage(); | - | ||||||||||||||||||||||||
2397 | layoutStruct->pageBottom = (page + 1) * layoutStruct->pageHeight - layoutStruct->pageBottomMargin; | - | ||||||||||||||||||||||||
2398 | - | |||||||||||||||||||||||||
2399 | cd->layoutDirty = false; | - | ||||||||||||||||||||||||
2400 | - | |||||||||||||||||||||||||
2401 | if (c->frameFormat().pageBreakPolicy() & QTextFormat::PageBreak_AlwaysAfter)
| 0 | ||||||||||||||||||||||||
2402 | layoutStruct->newPage(); never executed: layoutStruct->newPage(); | 0 | ||||||||||||||||||||||||
2403 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2404 | QRectF oldFrameRect(cd->position.toPointF(), cd->size.toSizeF()); | - | ||||||||||||||||||||||||
2405 | QRectF updateRect; | - | ||||||||||||||||||||||||
2406 | - | |||||||||||||||||||||||||
2407 | if (cd->sizeDirty)
| 0 | ||||||||||||||||||||||||
2408 | updateRect = layoutFrame(c, layoutFrom, layoutTo); never executed: updateRect = layoutFrame(c, layoutFrom, layoutTo); | 0 | ||||||||||||||||||||||||
2409 | - | |||||||||||||||||||||||||
2410 | positionFloat(c); | - | ||||||||||||||||||||||||
2411 | - | |||||||||||||||||||||||||
2412 | // If the size was made dirty when the position was set, layout again | - | ||||||||||||||||||||||||
2413 | if (cd->sizeDirty)
| 0 | ||||||||||||||||||||||||
2414 | updateRect = layoutFrame(c, layoutFrom, layoutTo); never executed: updateRect = layoutFrame(c, layoutFrom, layoutTo); | 0 | ||||||||||||||||||||||||
2415 | - | |||||||||||||||||||||||||
2416 | QRectF frameRect(cd->position.toPointF(), cd->size.toSizeF()); | - | ||||||||||||||||||||||||
2417 | - | |||||||||||||||||||||||||
2418 | if (frameRect == oldFrameRect && updateRect.isValid())
| 0 | ||||||||||||||||||||||||
2419 | updateRect.translate(cd->position.toPointF()); never executed: updateRect.translate(cd->position.toPointF()); | 0 | ||||||||||||||||||||||||
2420 | else | - | ||||||||||||||||||||||||
2421 | updateRect = frameRect; never executed: updateRect = frameRect; | 0 | ||||||||||||||||||||||||
2422 | - | |||||||||||||||||||||||||
2423 | layoutStruct->addUpdateRectForFloat(updateRect); | - | ||||||||||||||||||||||||
2424 | if (oldFrameRect.isValid())
| 0 | ||||||||||||||||||||||||
2425 | layoutStruct->addUpdateRectForFloat(oldFrameRect); never executed: layoutStruct->addUpdateRectForFloat(oldFrameRect); | 0 | ||||||||||||||||||||||||
2426 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2427 | - | |||||||||||||||||||||||||
2428 | layoutStruct->minimumWidth = qMax(layoutStruct->minimumWidth, cd->minimumWidth); | - | ||||||||||||||||||||||||
2429 | layoutStruct->maximumWidth = qMin(layoutStruct->maximumWidth, cd->maximumWidth); | - | ||||||||||||||||||||||||
2430 | - | |||||||||||||||||||||||||
2431 | previousIt = it; | - | ||||||||||||||||||||||||
2432 | ++it; | - | ||||||||||||||||||||||||
2433 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2434 | QTextFrame::Iterator lastIt; | - | ||||||||||||||||||||||||
2435 | if (!previousIt.atEnd() && previousIt != it)
| 0 | ||||||||||||||||||||||||
2436 | lastIt = previousIt; never executed: lastIt = previousIt; | 0 | ||||||||||||||||||||||||
2437 | previousIt = it; | - | ||||||||||||||||||||||||
2438 | QTextBlock block = it.currentBlock(); | - | ||||||||||||||||||||||||
2439 | ++it; | - | ||||||||||||||||||||||||
2440 | - | |||||||||||||||||||||||||
2441 | const QTextBlockFormat blockFormat = block.blockFormat(); | - | ||||||||||||||||||||||||
2442 | - | |||||||||||||||||||||||||
2443 | if (blockFormat.pageBreakPolicy() & QTextFormat::PageBreak_AlwaysBefore)
| 0 | ||||||||||||||||||||||||
2444 | layoutStruct->newPage(); never executed: layoutStruct->newPage(); | 0 | ||||||||||||||||||||||||
2445 | - | |||||||||||||||||||||||||
2446 | const QFixed origY = layoutStruct->y; | - | ||||||||||||||||||||||||
2447 | const QFixed origPageBottom = layoutStruct->pageBottom; | - | ||||||||||||||||||||||||
2448 | const QFixed origMaximumWidth = layoutStruct->maximumWidth; | - | ||||||||||||||||||||||||
2449 | layoutStruct->maximumWidth = 0; | - | ||||||||||||||||||||||||
2450 | - | |||||||||||||||||||||||||
2451 | const QTextBlockFormat *previousBlockFormatPtr = 0; | - | ||||||||||||||||||||||||
2452 | if (lastIt.currentBlock().isValid())
| 0 | ||||||||||||||||||||||||
2453 | previousBlockFormatPtr = &previousBlockFormat; never executed: previousBlockFormatPtr = &previousBlockFormat; | 0 | ||||||||||||||||||||||||
2454 | - | |||||||||||||||||||||||||
2455 | // layout and position child block | - | ||||||||||||||||||||||||
2456 | layoutBlock(block, docPos, blockFormat, layoutStruct, layoutFrom, layoutTo, previousBlockFormatPtr); | - | ||||||||||||||||||||||||
2457 | - | |||||||||||||||||||||||||
2458 | // detect whether we have any alignment in the document that disallows optimizations, | - | ||||||||||||||||||||||||
2459 | // such as not laying out the document again in a textedit with wrapping disabled. | - | ||||||||||||||||||||||||
2460 | if (inRootFrame && !(block.layout()->textOption().alignment() & Qt::AlignLeft))
| 0 | ||||||||||||||||||||||||
2461 | contentHasAlignment = true; never executed: contentHasAlignment = true; | 0 | ||||||||||||||||||||||||
2462 | - | |||||||||||||||||||||||||
2463 | // if the block right before a table is empty 'hide' it by | - | ||||||||||||||||||||||||
2464 | // positioning it into the table border | - | ||||||||||||||||||||||||
2465 | if (isEmptyBlockBeforeTable(block, blockFormat, it)) {
| 0 | ||||||||||||||||||||||||
2466 | const QTextBlock lastBlock = lastIt.currentBlock(); | - | ||||||||||||||||||||||||
2467 | const qreal lastBlockBottomMargin = lastBlock.isValid() ? lastBlock.blockFormat().bottomMargin() : 0.0f;
| 0 | ||||||||||||||||||||||||
2468 | layoutStruct->y = origY + QFixed::fromReal(qMax(lastBlockBottomMargin, block.blockFormat().topMargin())); | - | ||||||||||||||||||||||||
2469 | layoutStruct->pageBottom = origPageBottom; | - | ||||||||||||||||||||||||
2470 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2471 | // if the block right after a table is empty then 'hide' it, too | - | ||||||||||||||||||||||||
2472 | if (isEmptyBlockAfterTable(block, lastIt.currentFrame())) {
| 0 | ||||||||||||||||||||||||
2473 | QTextTableData *td = static_cast<QTextTableData *>(data(lastIt.currentFrame())); | - | ||||||||||||||||||||||||
2474 | QTextLayout *layout = block.layout(); | - | ||||||||||||||||||||||||
2475 | - | |||||||||||||||||||||||||
2476 | QPointF pos((td->position.x + td->size.width).toReal(), | - | ||||||||||||||||||||||||
2477 | (td->position.y + td->size.height).toReal() - layout->boundingRect().height()); | - | ||||||||||||||||||||||||
2478 | - | |||||||||||||||||||||||||
2479 | layout->setPosition(pos); | - | ||||||||||||||||||||||||
2480 | layoutStruct->y = origY; | - | ||||||||||||||||||||||||
2481 | layoutStruct->pageBottom = origPageBottom; | - | ||||||||||||||||||||||||
2482 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2483 | - | |||||||||||||||||||||||||
2484 | // if the block right after a table starts with a line separator, shift it up by one line | - | ||||||||||||||||||||||||
2485 | if (isLineSeparatorBlockAfterTable(block, lastIt.currentFrame())) {
| 0 | ||||||||||||||||||||||||
2486 | QTextTableData *td = static_cast<QTextTableData *>(data(lastIt.currentFrame())); | - | ||||||||||||||||||||||||
2487 | QTextLayout *layout = block.layout(); | - | ||||||||||||||||||||||||
2488 | - | |||||||||||||||||||||||||
2489 | QFixed height = QFixed::fromReal(layout->lineAt(0).height()); | - | ||||||||||||||||||||||||
2490 | - | |||||||||||||||||||||||||
2491 | if (layoutStruct->pageBottom == origPageBottom) {
| 0 | ||||||||||||||||||||||||
2492 | layoutStruct->y -= height; | - | ||||||||||||||||||||||||
2493 | layout->setPosition(layout->position() - QPointF(0, height.toReal())); | - | ||||||||||||||||||||||||
2494 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2495 | // relayout block to correctly handle page breaks | - | ||||||||||||||||||||||||
2496 | layoutStruct->y = origY - height; | - | ||||||||||||||||||||||||
2497 | layoutStruct->pageBottom = origPageBottom; | - | ||||||||||||||||||||||||
2498 | layoutBlock(block, docPos, blockFormat, layoutStruct, layoutFrom, layoutTo, previousBlockFormatPtr); | - | ||||||||||||||||||||||||
2499 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2500 | - | |||||||||||||||||||||||||
2501 | QPointF linePos((td->position.x + td->size.width).toReal(), | - | ||||||||||||||||||||||||
2502 | (td->position.y + td->size.height - height).toReal()); | - | ||||||||||||||||||||||||
2503 | - | |||||||||||||||||||||||||
2504 | layout->lineAt(0).setPosition(linePos - layout->position()); | - | ||||||||||||||||||||||||
2505 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2506 | - | |||||||||||||||||||||||||
2507 | if (blockFormat.pageBreakPolicy() & QTextFormat::PageBreak_AlwaysAfter)
| 0 | ||||||||||||||||||||||||
2508 | layoutStruct->newPage(); never executed: layoutStruct->newPage(); | 0 | ||||||||||||||||||||||||
2509 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2510 | - | |||||||||||||||||||||||||
2511 | maximumBlockWidth = qMax(maximumBlockWidth, layoutStruct->maximumWidth); | - | ||||||||||||||||||||||||
2512 | layoutStruct->maximumWidth = origMaximumWidth; | - | ||||||||||||||||||||||||
2513 | previousBlockFormat = blockFormat; | - | ||||||||||||||||||||||||
2514 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2515 | } | - | ||||||||||||||||||||||||
2516 | if (layoutStruct->maximumWidth == QFIXED_MAX && maximumBlockWidth > 0)
| 0 | ||||||||||||||||||||||||
2517 | layoutStruct->maximumWidth = maximumBlockWidth; never executed: layoutStruct->maximumWidth = maximumBlockWidth; | 0 | ||||||||||||||||||||||||
2518 | else | - | ||||||||||||||||||||||||
2519 | layoutStruct->maximumWidth = qMax(layoutStruct->maximumWidth, maximumBlockWidth); never executed: layoutStruct->maximumWidth = qMax(layoutStruct->maximumWidth, maximumBlockWidth); | 0 | ||||||||||||||||||||||||
2520 | - | |||||||||||||||||||||||||
2521 | // a float at the bottom of a frame may make it taller, hence the qMax() for layoutStruct->y. | - | ||||||||||||||||||||||||
2522 | // we don't need to do it for tables though because floats in tables are per table | - | ||||||||||||||||||||||||
2523 | // and not per cell and layoutCell already takes care of doing the same as we do here | - | ||||||||||||||||||||||||
2524 | if (!qobject_cast<QTextTable *>(layoutStruct->frame)) {
| 0 | ||||||||||||||||||||||||
2525 | QList<QTextFrame *> children = layoutStruct->frame->childFrames(); | - | ||||||||||||||||||||||||
2526 | for (int i = 0; i < children.count(); ++i) {
| 0 | ||||||||||||||||||||||||
2527 | QTextFrameData *fd = data(children.at(i)); | - | ||||||||||||||||||||||||
2528 | if (!fd->layoutDirty && children.at(i)->frameFormat().position() != QTextFrameFormat::InFlow)
| 0 | ||||||||||||||||||||||||
2529 | 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 | ||||||||||||||||||||||||
2530 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2531 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2532 | - | |||||||||||||||||||||||||
2533 | if (inRootFrame) {
| 0 | ||||||||||||||||||||||||
2534 | // we assume that any float is aligned in a way that disallows the optimizations that rely | - | ||||||||||||||||||||||||
2535 | // on unaligned content. | - | ||||||||||||||||||||||||
2536 | if (!fd->floats.isEmpty())
| 0 | ||||||||||||||||||||||||
2537 | contentHasAlignment = true; never executed: contentHasAlignment = true; | 0 | ||||||||||||||||||||||||
2538 | - | |||||||||||||||||||||||||
2539 | if (it.atEnd()) {
| 0 | ||||||||||||||||||||||||
2540 | //qDebug() << "layout done!"; | - | ||||||||||||||||||||||||
2541 | currentLazyLayoutPosition = -1; | - | ||||||||||||||||||||||||
2542 | QCheckPoint cp; | - | ||||||||||||||||||||||||
2543 | cp.y = layoutStruct->y; | - | ||||||||||||||||||||||||
2544 | cp.positionInFrame = docPrivate->length(); | - | ||||||||||||||||||||||||
2545 | cp.minimumWidth = layoutStruct->minimumWidth; | - | ||||||||||||||||||||||||
2546 | cp.maximumWidth = layoutStruct->maximumWidth; | - | ||||||||||||||||||||||||
2547 | cp.contentsWidth = layoutStruct->contentsWidth; | - | ||||||||||||||||||||||||
2548 | checkPoints.append(cp); | - | ||||||||||||||||||||||||
2549 | checkPoints.reserve(checkPoints.size()); | - | ||||||||||||||||||||||||
2550 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2551 | currentLazyLayoutPosition = checkPoints.last().positionInFrame; | - | ||||||||||||||||||||||||
2552 | // ####### | - | ||||||||||||||||||||||||
2553 | //checkPoints.last().positionInFrame = q->document()->docHandle()->length(); | - | ||||||||||||||||||||||||
2554 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2555 | } | - | ||||||||||||||||||||||||
2556 | - | |||||||||||||||||||||||||
2557 | - | |||||||||||||||||||||||||
2558 | fd->currentLayoutStruct = 0; | - | ||||||||||||||||||||||||
2559 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2560 | - | |||||||||||||||||||||||||
2561 | static inline void getLineHeightParams(const QTextBlockFormat &blockFormat, const QTextLine &line, qreal scaling, | - | ||||||||||||||||||||||||
2562 | QFixed *lineAdjustment, QFixed *lineBreakHeight, QFixed *lineHeight) | - | ||||||||||||||||||||||||
2563 | { | - | ||||||||||||||||||||||||
2564 | *lineHeight = QFixed::fromReal(blockFormat.lineHeight(line.height(), scaling)); | - | ||||||||||||||||||||||||
2565 | - | |||||||||||||||||||||||||
2566 | if (blockFormat.lineHeightType() == QTextBlockFormat::FixedHeight || blockFormat.lineHeightType() == QTextBlockFormat::MinimumHeight) {
| 0 | ||||||||||||||||||||||||
2567 | *lineBreakHeight = *lineHeight; | - | ||||||||||||||||||||||||
2568 | if (blockFormat.lineHeightType() == QTextBlockFormat::FixedHeight)
| 0 | ||||||||||||||||||||||||
2569 | *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 | ||||||||||||||||||||||||
2570 | else | - | ||||||||||||||||||||||||
2571 | *lineAdjustment = QFixed::fromReal(line.height()) - *lineHeight; never executed: *lineAdjustment = QFixed::fromReal(line.height()) - *lineHeight; | 0 | ||||||||||||||||||||||||
2572 | } | - | ||||||||||||||||||||||||
2573 | else { | - | ||||||||||||||||||||||||
2574 | *lineBreakHeight = QFixed::fromReal(line.height()); | - | ||||||||||||||||||||||||
2575 | *lineAdjustment = 0; | - | ||||||||||||||||||||||||
2576 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2577 | } | - | ||||||||||||||||||||||||
2578 | - | |||||||||||||||||||||||||
2579 | void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosition, const QTextBlockFormat &blockFormat, | - | ||||||||||||||||||||||||
2580 | QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, const QTextBlockFormat *previousBlockFormat) | - | ||||||||||||||||||||||||
2581 | { | - | ||||||||||||||||||||||||
2582 | Q_Q(QTextDocumentLayout); | - | ||||||||||||||||||||||||
2583 | if (!bl.isVisible())
| 0 | ||||||||||||||||||||||||
2584 | return; never executed: return; | 0 | ||||||||||||||||||||||||
2585 | - | |||||||||||||||||||||||||
2586 | QTextLayout *tl = bl.layout(); | - | ||||||||||||||||||||||||
2587 | const int blockLength = bl.length(); | - | ||||||||||||||||||||||||
2588 | - | |||||||||||||||||||||||||
2589 | LDEBUG << "layoutBlock from=" << layoutFrom << "to=" << layoutTo; dead code: QMessageLogger(__FILE__, 2589, __PRETTY_FUNCTION__).debug() << "layoutBlock from=" << layoutFrom << "to=" << layoutTo; | - | ||||||||||||||||||||||||
2590 | - | |||||||||||||||||||||||||
2591 | // qDebug() << "layoutBlock; width" << layoutStruct->x_right - layoutStruct->x_left << "(maxWidth is btw" << tl->maximumWidth() << ')'; | - | ||||||||||||||||||||||||
2592 | - | |||||||||||||||||||||||||
2593 | if (previousBlockFormat) {
| 0 | ||||||||||||||||||||||||
2594 | qreal margin = qMax(blockFormat.topMargin(), previousBlockFormat->bottomMargin()); | - | ||||||||||||||||||||||||
2595 | if (margin > 0 && q->paintDevice()) {
| 0 | ||||||||||||||||||||||||
2596 | margin *= qreal(q->paintDevice()->logicalDpiY()) / qreal(qt_defaultDpi()); | - | ||||||||||||||||||||||||
2597 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2598 | layoutStruct->y += QFixed::fromReal(margin); | - | ||||||||||||||||||||||||
2599 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2600 | - | |||||||||||||||||||||||||
2601 | //QTextFrameData *fd = data(layoutStruct->frame); | - | ||||||||||||||||||||||||
2602 | - | |||||||||||||||||||||||||
2603 | Qt::LayoutDirection dir = bl.textDirection(); | - | ||||||||||||||||||||||||
2604 | - | |||||||||||||||||||||||||
2605 | QFixed extraMargin; | - | ||||||||||||||||||||||||
2606 | if (docPrivate->defaultTextOption.flags() & QTextOption::AddSpaceForLineAndParagraphSeparators) {
| 0 | ||||||||||||||||||||||||
2607 | QFontMetricsF fm(bl.charFormat().font()); | - | ||||||||||||||||||||||||
2608 | extraMargin = QFixed::fromReal(fm.width(QChar(QChar(0x21B5)))); | - | ||||||||||||||||||||||||
2609 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2610 | - | |||||||||||||||||||||||||
2611 | const QFixed indent = this->blockIndent(blockFormat); | - | ||||||||||||||||||||||||
2612 | const QFixed totalLeftMargin = QFixed::fromReal(blockFormat.leftMargin()) + (dir == Qt::RightToLeft ? extraMargin : indent);
| 0 | ||||||||||||||||||||||||
2613 | const QFixed totalRightMargin = QFixed::fromReal(blockFormat.rightMargin()) + (dir == Qt::RightToLeft ? indent : extraMargin);
| 0 | ||||||||||||||||||||||||
2614 | - | |||||||||||||||||||||||||
2615 | const QPointF oldPosition = tl->position(); | - | ||||||||||||||||||||||||
2616 | tl->setPosition(QPointF(layoutStruct->x_left.toReal(), layoutStruct->y.toReal())); | - | ||||||||||||||||||||||||
2617 | - | |||||||||||||||||||||||||
2618 | if (layoutStruct->fullLayout
| 0 | ||||||||||||||||||||||||
2619 | || (blockPosition + blockLength > layoutFrom && blockPosition <= layoutTo)
| 0 | ||||||||||||||||||||||||
2620 | // force relayout if we cross a page boundary | - | ||||||||||||||||||||||||
2621 | || (layoutStruct->pageHeight != QFIXED_MAX && layoutStruct->absoluteY() + QFixed::fromReal(tl->boundingRect().height()) > layoutStruct->pageBottom)) {
| 0 | ||||||||||||||||||||||||
2622 | - | |||||||||||||||||||||||||
2623 | LDEBUG << " do layout"; dead code: QMessageLogger(__FILE__, 2623, __PRETTY_FUNCTION__).debug() << " do layout"; | - | ||||||||||||||||||||||||
2624 | QTextOption option = docPrivate->defaultTextOption; | - | ||||||||||||||||||||||||
2625 | option.setTextDirection(dir); | - | ||||||||||||||||||||||||
2626 | option.setTabs( blockFormat.tabPositions() ); | - | ||||||||||||||||||||||||
2627 | - | |||||||||||||||||||||||||
2628 | Qt::Alignment align = docPrivate->defaultTextOption.alignment(); | - | ||||||||||||||||||||||||
2629 | if (blockFormat.hasProperty(QTextFormat::BlockAlignment))
| 0 | ||||||||||||||||||||||||
2630 | align = blockFormat.alignment(); never executed: align = blockFormat.alignment(); | 0 | ||||||||||||||||||||||||
2631 | option.setAlignment(QGuiApplicationPrivate::visualAlignment(dir, align)); // for paragraph that are RTL, alignment is auto-reversed; | - | ||||||||||||||||||||||||
2632 | - | |||||||||||||||||||||||||
2633 | if (blockFormat.nonBreakableLines() || document->pageSize().width() < 0) {
| 0 | ||||||||||||||||||||||||
2634 | option.setWrapMode(QTextOption::ManualWrap); | - | ||||||||||||||||||||||||
2635 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2636 | - | |||||||||||||||||||||||||
2637 | tl->setTextOption(option); | - | ||||||||||||||||||||||||
2638 | - | |||||||||||||||||||||||||
2639 | const bool haveWordOrAnyWrapMode = (option.wrapMode() == QTextOption::WrapAtWordBoundaryOrAnywhere); | - | ||||||||||||||||||||||||
2640 | - | |||||||||||||||||||||||||
2641 | // qDebug() << " layouting block at" << bl.position(); | - | ||||||||||||||||||||||||
2642 | const QFixed cy = layoutStruct->y; | - | ||||||||||||||||||||||||
2643 | const QFixed l = layoutStruct->x_left + totalLeftMargin; | - | ||||||||||||||||||||||||
2644 | const QFixed r = layoutStruct->x_right - totalRightMargin; | - | ||||||||||||||||||||||||
2645 | - | |||||||||||||||||||||||||
2646 | tl->beginLayout(); | - | ||||||||||||||||||||||||
2647 | bool firstLine = true; | - | ||||||||||||||||||||||||
2648 | while (1) { | - | ||||||||||||||||||||||||
2649 | QTextLine line = tl->createLine(); | - | ||||||||||||||||||||||||
2650 | if (!line.isValid())
| 0 | ||||||||||||||||||||||||
2651 | break; never executed: break; | 0 | ||||||||||||||||||||||||
2652 | line.setLeadingIncluded(true); | - | ||||||||||||||||||||||||
2653 | - | |||||||||||||||||||||||||
2654 | QFixed left, right; | - | ||||||||||||||||||||||||
2655 | floatMargins(layoutStruct->y, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2656 | left = qMax(left, l); | - | ||||||||||||||||||||||||
2657 | right = qMin(right, r); | - | ||||||||||||||||||||||||
2658 | QFixed text_indent; | - | ||||||||||||||||||||||||
2659 | if (firstLine) {
| 0 | ||||||||||||||||||||||||
2660 | text_indent = QFixed::fromReal(blockFormat.textIndent()); | - | ||||||||||||||||||||||||
2661 | if (dir == Qt::LeftToRight)
| 0 | ||||||||||||||||||||||||
2662 | left += text_indent; never executed: left += text_indent; | 0 | ||||||||||||||||||||||||
2663 | else | - | ||||||||||||||||||||||||
2664 | right -= text_indent; never executed: right -= text_indent; | 0 | ||||||||||||||||||||||||
2665 | firstLine = false; | - | ||||||||||||||||||||||||
2666 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2667 | // qDebug() << "layout line y=" << currentYPos << "left=" << left << "right=" <<right; | - | ||||||||||||||||||||||||
2668 | - | |||||||||||||||||||||||||
2669 | if (fixedColumnWidth != -1)
| 0 | ||||||||||||||||||||||||
2670 | line.setNumColumns(fixedColumnWidth, (right - left).toReal()); never executed: line.setNumColumns(fixedColumnWidth, (right - left).toReal()); | 0 | ||||||||||||||||||||||||
2671 | else | - | ||||||||||||||||||||||||
2672 | line.setLineWidth((right - left).toReal()); never executed: line.setLineWidth((right - left).toReal()); | 0 | ||||||||||||||||||||||||
2673 | - | |||||||||||||||||||||||||
2674 | // qDebug() << "layoutBlock; layouting line with width" << right - left << "->textWidth" << line.textWidth(); | - | ||||||||||||||||||||||||
2675 | floatMargins(layoutStruct->y, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2676 | left = qMax(left, l); | - | ||||||||||||||||||||||||
2677 | right = qMin(right, r); | - | ||||||||||||||||||||||||
2678 | if (dir == Qt::LeftToRight)
| 0 | ||||||||||||||||||||||||
2679 | left += text_indent; never executed: left += text_indent; | 0 | ||||||||||||||||||||||||
2680 | else | - | ||||||||||||||||||||||||
2681 | right -= text_indent; never executed: right -= text_indent; | 0 | ||||||||||||||||||||||||
2682 | - | |||||||||||||||||||||||||
2683 | if (fixedColumnWidth == -1 && QFixed::fromReal(line.naturalTextWidth()) > right-left) {
| 0 | ||||||||||||||||||||||||
2684 | // float has been added in the meantime, redo | - | ||||||||||||||||||||||||
2685 | layoutStruct->pendingFloats.clear(); | - | ||||||||||||||||||||||||
2686 | - | |||||||||||||||||||||||||
2687 | line.setLineWidth((right-left).toReal()); | - | ||||||||||||||||||||||||
2688 | if (QFixed::fromReal(line.naturalTextWidth()) > right-left) {
| 0 | ||||||||||||||||||||||||
2689 | if (haveWordOrAnyWrapMode) {
| 0 | ||||||||||||||||||||||||
2690 | option.setWrapMode(QTextOption::WrapAnywhere); | - | ||||||||||||||||||||||||
2691 | tl->setTextOption(option); | - | ||||||||||||||||||||||||
2692 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2693 | - | |||||||||||||||||||||||||
2694 | layoutStruct->pendingFloats.clear(); | - | ||||||||||||||||||||||||
2695 | // lines min width more than what we have | - | ||||||||||||||||||||||||
2696 | layoutStruct->y = findY(layoutStruct->y, layoutStruct, QFixed::fromReal(line.naturalTextWidth())); | - | ||||||||||||||||||||||||
2697 | floatMargins(layoutStruct->y, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2698 | left = qMax(left, l); | - | ||||||||||||||||||||||||
2699 | right = qMin(right, r); | - | ||||||||||||||||||||||||
2700 | if (dir == Qt::LeftToRight)
| 0 | ||||||||||||||||||||||||
2701 | left += text_indent; never executed: left += text_indent; | 0 | ||||||||||||||||||||||||
2702 | else | - | ||||||||||||||||||||||||
2703 | right -= text_indent; never executed: right -= text_indent; | 0 | ||||||||||||||||||||||||
2704 | line.setLineWidth(qMax<qreal>(line.naturalTextWidth(), (right-left).toReal())); | - | ||||||||||||||||||||||||
2705 | - | |||||||||||||||||||||||||
2706 | if (haveWordOrAnyWrapMode) {
| 0 | ||||||||||||||||||||||||
2707 | option.setWrapMode(QTextOption::WordWrap); | - | ||||||||||||||||||||||||
2708 | tl->setTextOption(option); | - | ||||||||||||||||||||||||
2709 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2710 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2711 | - | |||||||||||||||||||||||||
2712 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2713 | - | |||||||||||||||||||||||||
2714 | QFixed lineBreakHeight, lineHeight, lineAdjustment; | - | ||||||||||||||||||||||||
2715 | qreal scaling = (q->paintDevice() && q->paintDevice()->logicalDpiY() != qt_defaultDpi()) ?
| 0 | ||||||||||||||||||||||||
2716 | qreal(q->paintDevice()->logicalDpiY()) / qreal(qt_defaultDpi()) : 1; | - | ||||||||||||||||||||||||
2717 | getLineHeightParams(blockFormat, line, scaling, &lineAdjustment, &lineBreakHeight, &lineHeight); | - | ||||||||||||||||||||||||
2718 | - | |||||||||||||||||||||||||
2719 | if (layoutStruct->pageHeight > 0 && layoutStruct->absoluteY() + lineBreakHeight > layoutStruct->pageBottom) {
| 0 | ||||||||||||||||||||||||
2720 | layoutStruct->newPage(); | - | ||||||||||||||||||||||||
2721 | - | |||||||||||||||||||||||||
2722 | floatMargins(layoutStruct->y, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2723 | left = qMax(left, l); | - | ||||||||||||||||||||||||
2724 | right = qMin(right, r); | - | ||||||||||||||||||||||||
2725 | if (dir == Qt::LeftToRight)
| 0 | ||||||||||||||||||||||||
2726 | left += text_indent; never executed: left += text_indent; | 0 | ||||||||||||||||||||||||
2727 | else | - | ||||||||||||||||||||||||
2728 | right -= text_indent; never executed: right -= text_indent; | 0 | ||||||||||||||||||||||||
2729 | } | - | ||||||||||||||||||||||||
2730 | - | |||||||||||||||||||||||||
2731 | line.setPosition(QPointF((left - layoutStruct->x_left).toReal(), (layoutStruct->y - cy - lineAdjustment).toReal())); | - | ||||||||||||||||||||||||
2732 | layoutStruct->y += lineHeight; | - | ||||||||||||||||||||||||
2733 | layoutStruct->contentsWidth | - | ||||||||||||||||||||||||
2734 | = qMax<QFixed>(layoutStruct->contentsWidth, QFixed::fromReal(line.x() + line.naturalTextWidth()) + totalRightMargin); | - | ||||||||||||||||||||||||
2735 | - | |||||||||||||||||||||||||
2736 | // position floats | - | ||||||||||||||||||||||||
2737 | for (int i = 0; i < layoutStruct->pendingFloats.size(); ++i) {
| 0 | ||||||||||||||||||||||||
2738 | QTextFrame *f = layoutStruct->pendingFloats.at(i); | - | ||||||||||||||||||||||||
2739 | positionFloat(f); | - | ||||||||||||||||||||||||
2740 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2741 | layoutStruct->pendingFloats.clear(); | - | ||||||||||||||||||||||||
2742 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2743 | tl->endLayout(); | - | ||||||||||||||||||||||||
2744 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2745 | const int cnt = tl->lineCount(); | - | ||||||||||||||||||||||||
2746 | for (int i = 0; i < cnt; ++i) {
| 0 | ||||||||||||||||||||||||
2747 | LDEBUG << "going to move text line" << i; dead code: QMessageLogger(__FILE__, 2747, __PRETTY_FUNCTION__).debug() << "going to move text line" << i; | - | ||||||||||||||||||||||||
2748 | QTextLine line = tl->lineAt(i); | - | ||||||||||||||||||||||||
2749 | layoutStruct->contentsWidth | - | ||||||||||||||||||||||||
2750 | = qMax(layoutStruct->contentsWidth, QFixed::fromReal(line.x() + tl->lineAt(i).naturalTextWidth()) + totalRightMargin); | - | ||||||||||||||||||||||||
2751 | - | |||||||||||||||||||||||||
2752 | QFixed lineBreakHeight, lineHeight, lineAdjustment; | - | ||||||||||||||||||||||||
2753 | qreal scaling = (q->paintDevice() && q->paintDevice()->logicalDpiY() != qt_defaultDpi()) ?
| 0 | ||||||||||||||||||||||||
2754 | qreal(q->paintDevice()->logicalDpiY()) / qreal(qt_defaultDpi()) : 1; | - | ||||||||||||||||||||||||
2755 | getLineHeightParams(blockFormat, line, scaling, &lineAdjustment, &lineBreakHeight, &lineHeight); | - | ||||||||||||||||||||||||
2756 | - | |||||||||||||||||||||||||
2757 | if (layoutStruct->pageHeight != QFIXED_MAX) {
| 0 | ||||||||||||||||||||||||
2758 | if (layoutStruct->absoluteY() + lineBreakHeight > layoutStruct->pageBottom)
| 0 | ||||||||||||||||||||||||
2759 | layoutStruct->newPage(); never executed: layoutStruct->newPage(); | 0 | ||||||||||||||||||||||||
2760 | line.setPosition(QPointF(line.position().x(), (layoutStruct->y - lineAdjustment).toReal() - tl->position().y())); | - | ||||||||||||||||||||||||
2761 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2762 | layoutStruct->y += lineHeight; | - | ||||||||||||||||||||||||
2763 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2764 | if (layoutStruct->updateRect.isValid()
| 0 | ||||||||||||||||||||||||
2765 | && blockLength > 1) {
| 0 | ||||||||||||||||||||||||
2766 | if (layoutFrom >= blockPosition + blockLength) {
| 0 | ||||||||||||||||||||||||
2767 | // if our height didn't change and the change in the document is | - | ||||||||||||||||||||||||
2768 | // in one of the later paragraphs, then we don't need to repaint | - | ||||||||||||||||||||||||
2769 | // this one | - | ||||||||||||||||||||||||
2770 | layoutStruct->updateRect.setTop(qMax(layoutStruct->updateRect.top(), layoutStruct->y.toReal())); | - | ||||||||||||||||||||||||
2771 | } else if (layoutTo < blockPosition) { never executed: end of block
| 0 | ||||||||||||||||||||||||
2772 | if (oldPosition == tl->position())
| 0 | ||||||||||||||||||||||||
2773 | // if the change in the document happened earlier in the document | - | ||||||||||||||||||||||||
2774 | // and our position did /not/ change because none of the earlier paragraphs | - | ||||||||||||||||||||||||
2775 | // or frames changed their height, then we don't need to repaint | - | ||||||||||||||||||||||||
2776 | // this one | - | ||||||||||||||||||||||||
2777 | layoutStruct->updateRect.setBottom(qMin(layoutStruct->updateRect.bottom(), tl->position().y())); never executed: layoutStruct->updateRect.setBottom(qMin(layoutStruct->updateRect.bottom(), tl->position().y())); | 0 | ||||||||||||||||||||||||
2778 | else | - | ||||||||||||||||||||||||
2779 | layoutStruct->updateRect.setBottom(qreal(INT_MAX)); // reset never executed: layoutStruct->updateRect.setBottom(qreal(2147483647)); | 0 | ||||||||||||||||||||||||
2780 | } | - | ||||||||||||||||||||||||
2781 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2782 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2783 | - | |||||||||||||||||||||||||
2784 | // ### doesn't take floats into account. would need to do it per line. but how to retrieve then? (Simon) | - | ||||||||||||||||||||||||
2785 | const QFixed margins = totalLeftMargin + totalRightMargin; | - | ||||||||||||||||||||||||
2786 | layoutStruct->minimumWidth = qMax(layoutStruct->minimumWidth, QFixed::fromReal(tl->minimumWidth()) + margins); | - | ||||||||||||||||||||||||
2787 | - | |||||||||||||||||||||||||
2788 | const QFixed maxW = QFixed::fromReal(tl->maximumWidth()) + margins; | - | ||||||||||||||||||||||||
2789 | - | |||||||||||||||||||||||||
2790 | if (maxW > 0) {
| 0 | ||||||||||||||||||||||||
2791 | if (layoutStruct->maximumWidth == QFIXED_MAX)
| 0 | ||||||||||||||||||||||||
2792 | layoutStruct->maximumWidth = maxW; never executed: layoutStruct->maximumWidth = maxW; | 0 | ||||||||||||||||||||||||
2793 | else | - | ||||||||||||||||||||||||
2794 | layoutStruct->maximumWidth = qMax(layoutStruct->maximumWidth, maxW); never executed: layoutStruct->maximumWidth = qMax(layoutStruct->maximumWidth, maxW); | 0 | ||||||||||||||||||||||||
2795 | } | - | ||||||||||||||||||||||||
2796 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2797 | - | |||||||||||||||||||||||||
2798 | void QTextDocumentLayoutPrivate::floatMargins(const QFixed &y, const QTextLayoutStruct *layoutStruct, | - | ||||||||||||||||||||||||
2799 | QFixed *left, QFixed *right) const | - | ||||||||||||||||||||||||
2800 | { | - | ||||||||||||||||||||||||
2801 | // qDebug() << "floatMargins y=" << y; | - | ||||||||||||||||||||||||
2802 | *left = layoutStruct->x_left; | - | ||||||||||||||||||||||||
2803 | *right = layoutStruct->x_right; | - | ||||||||||||||||||||||||
2804 | QTextFrameData *lfd = data(layoutStruct->frame); | - | ||||||||||||||||||||||||
2805 | for (int i = 0; i < lfd->floats.size(); ++i) {
| 0 | ||||||||||||||||||||||||
2806 | QTextFrameData *fd = data(lfd->floats.at(i)); | - | ||||||||||||||||||||||||
2807 | if (!fd->layoutDirty) {
| 0 | ||||||||||||||||||||||||
2808 | if (fd->position.y <= y && fd->position.y + fd->size.height > y) {
| 0 | ||||||||||||||||||||||||
2809 | // qDebug() << "adjusting with float" << f << fd->position.x()<< fd->size.width(); | - | ||||||||||||||||||||||||
2810 | if (lfd->floats.at(i)->frameFormat().position() == QTextFrameFormat::FloatLeft)
| 0 | ||||||||||||||||||||||||
2811 | *left = qMax(*left, fd->position.x + fd->size.width); never executed: *left = qMax(*left, fd->position.x + fd->size.width); | 0 | ||||||||||||||||||||||||
2812 | else | - | ||||||||||||||||||||||||
2813 | *right = qMin(*right, fd->position.x); never executed: *right = qMin(*right, fd->position.x); | 0 | ||||||||||||||||||||||||
2814 | } | - | ||||||||||||||||||||||||
2815 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2816 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2817 | // qDebug() << "floatMargins: left="<<*left<<"right="<<*right<<"y="<<y; | - | ||||||||||||||||||||||||
2818 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2819 | - | |||||||||||||||||||||||||
2820 | QFixed QTextDocumentLayoutPrivate::findY(QFixed yFrom, const QTextLayoutStruct *layoutStruct, QFixed requiredWidth) const | - | ||||||||||||||||||||||||
2821 | { | - | ||||||||||||||||||||||||
2822 | QFixed right, left; | - | ||||||||||||||||||||||||
2823 | requiredWidth = qMin(requiredWidth, layoutStruct->x_right - layoutStruct->x_left); | - | ||||||||||||||||||||||||
2824 | - | |||||||||||||||||||||||||
2825 | // qDebug() << "findY:" << yFrom; | - | ||||||||||||||||||||||||
2826 | while (1) { | - | ||||||||||||||||||||||||
2827 | floatMargins(yFrom, layoutStruct, &left, &right); | - | ||||||||||||||||||||||||
2828 | // qDebug() << " yFrom=" << yFrom<<"right=" << right << "left=" << left << "requiredWidth=" << requiredWidth; | - | ||||||||||||||||||||||||
2829 | if (right-left >= requiredWidth)
| 0 | ||||||||||||||||||||||||
2830 | break; never executed: break; | 0 | ||||||||||||||||||||||||
2831 | - | |||||||||||||||||||||||||
2832 | // move float down until we find enough space | - | ||||||||||||||||||||||||
2833 | QFixed newY = QFIXED_MAX; | - | ||||||||||||||||||||||||
2834 | QTextFrameData *lfd = data(layoutStruct->frame); | - | ||||||||||||||||||||||||
2835 | for (int i = 0; i < lfd->floats.size(); ++i) {
| 0 | ||||||||||||||||||||||||
2836 | QTextFrameData *fd = data(lfd->floats.at(i)); | - | ||||||||||||||||||||||||
2837 | if (!fd->layoutDirty) {
| 0 | ||||||||||||||||||||||||
2838 | if (fd->position.y <= yFrom && fd->position.y + fd->size.height > yFrom)
| 0 | ||||||||||||||||||||||||
2839 | newY = qMin(newY, fd->position.y + fd->size.height); never executed: newY = qMin(newY, fd->position.y + fd->size.height); | 0 | ||||||||||||||||||||||||
2840 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2841 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2842 | if (newY == QFIXED_MAX)
| 0 | ||||||||||||||||||||||||
2843 | break; never executed: break; | 0 | ||||||||||||||||||||||||
2844 | yFrom = newY; | - | ||||||||||||||||||||||||
2845 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2846 | return yFrom; never executed: return yFrom; | 0 | ||||||||||||||||||||||||
2847 | } | - | ||||||||||||||||||||||||
2848 | - | |||||||||||||||||||||||||
2849 | QTextDocumentLayout::QTextDocumentLayout(QTextDocument *doc) | - | ||||||||||||||||||||||||
2850 | : QAbstractTextDocumentLayout(*new QTextDocumentLayoutPrivate, doc) | - | ||||||||||||||||||||||||
2851 | { | - | ||||||||||||||||||||||||
2852 | registerHandler(QTextFormat::ImageObject, new QTextImageHandler(this)); | - | ||||||||||||||||||||||||
2853 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2854 | - | |||||||||||||||||||||||||
2855 | - | |||||||||||||||||||||||||
2856 | void QTextDocumentLayout::draw(QPainter *painter, const PaintContext &context) | - | ||||||||||||||||||||||||
2857 | { | - | ||||||||||||||||||||||||
2858 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
2859 | QTextFrame *frame = d->document->rootFrame(); | - | ||||||||||||||||||||||||
2860 | QTextFrameData *fd = data(frame); | - | ||||||||||||||||||||||||
2861 | - | |||||||||||||||||||||||||
2862 | if(fd->sizeDirty)
| 0 | ||||||||||||||||||||||||
2863 | return; never executed: return; | 0 | ||||||||||||||||||||||||
2864 | - | |||||||||||||||||||||||||
2865 | if (context.clip.isValid()) {
| 0 | ||||||||||||||||||||||||
2866 | d->ensureLayouted(QFixed::fromReal(context.clip.bottom())); | - | ||||||||||||||||||||||||
2867 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2868 | d->ensureLayoutFinished(); | - | ||||||||||||||||||||||||
2869 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2870 | - | |||||||||||||||||||||||||
2871 | QFixed width = fd->size.width; | - | ||||||||||||||||||||||||
2872 | if (d->document->pageSize().width() == 0 && d->viewportRect.isValid()) {
| 0 | ||||||||||||||||||||||||
2873 | // we're in NoWrap mode, meaning the frame should expand to the viewport | - | ||||||||||||||||||||||||
2874 | // so that backgrounds are drawn correctly | - | ||||||||||||||||||||||||
2875 | fd->size.width = qMax(width, QFixed::fromReal(d->viewportRect.right())); | - | ||||||||||||||||||||||||
2876 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2877 | - | |||||||||||||||||||||||||
2878 | // Make sure we conform to the root frames bounds when drawing. | - | ||||||||||||||||||||||||
2879 | d->clipRect = QRectF(fd->position.toPointF(), fd->size.toSizeF()).adjusted(fd->leftMargin.toReal(), 0, -fd->rightMargin.toReal(), 0); | - | ||||||||||||||||||||||||
2880 | d->drawFrame(QPointF(), painter, context, frame); | - | ||||||||||||||||||||||||
2881 | fd->size.width = width; | - | ||||||||||||||||||||||||
2882 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2883 | - | |||||||||||||||||||||||||
2884 | void QTextDocumentLayout::setViewport(const QRectF &viewport) | - | ||||||||||||||||||||||||
2885 | { | - | ||||||||||||||||||||||||
2886 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
2887 | d->viewportRect = viewport; | - | ||||||||||||||||||||||||
2888 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2889 | - | |||||||||||||||||||||||||
2890 | static void markFrames(QTextFrame *current, int from, int oldLength, int length) | - | ||||||||||||||||||||||||
2891 | { | - | ||||||||||||||||||||||||
2892 | int end = qMax(oldLength, length) + from; | - | ||||||||||||||||||||||||
2893 | - | |||||||||||||||||||||||||
2894 | if (current->firstPosition() >= end || current->lastPosition() < from)
| 0 | ||||||||||||||||||||||||
2895 | return; never executed: return; | 0 | ||||||||||||||||||||||||
2896 | - | |||||||||||||||||||||||||
2897 | QTextFrameData *fd = data(current); | - | ||||||||||||||||||||||||
2898 | for (int i = 0; i < fd->floats.size(); ++i) {
| 0 | ||||||||||||||||||||||||
2899 | QTextFrame *f = fd->floats[i]; | - | ||||||||||||||||||||||||
2900 | if (!f) {
| 0 | ||||||||||||||||||||||||
2901 | // float got removed in editing operation | - | ||||||||||||||||||||||||
2902 | fd->floats.removeAt(i); | - | ||||||||||||||||||||||||
2903 | --i; | - | ||||||||||||||||||||||||
2904 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2905 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2906 | - | |||||||||||||||||||||||||
2907 | fd->layoutDirty = true; | - | ||||||||||||||||||||||||
2908 | fd->sizeDirty = true; | - | ||||||||||||||||||||||||
2909 | - | |||||||||||||||||||||||||
2910 | // qDebug(" marking frame (%d--%d) as dirty", current->firstPosition(), current->lastPosition()); | - | ||||||||||||||||||||||||
2911 | QList<QTextFrame *> children = current->childFrames(); | - | ||||||||||||||||||||||||
2912 | for (int i = 0; i < children.size(); ++i)
| 0 | ||||||||||||||||||||||||
2913 | markFrames(children.at(i), from, oldLength, length); never executed: markFrames(children.at(i), from, oldLength, length); | 0 | ||||||||||||||||||||||||
2914 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2915 | - | |||||||||||||||||||||||||
2916 | void QTextDocumentLayout::documentChanged(int from, int oldLength, int length) | - | ||||||||||||||||||||||||
2917 | { | - | ||||||||||||||||||||||||
2918 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
2919 | - | |||||||||||||||||||||||||
2920 | QTextBlock startIt = document()->findBlock(from); | - | ||||||||||||||||||||||||
2921 | QTextBlock endIt = document()->findBlock(qMax(0, from + length - 1)); | - | ||||||||||||||||||||||||
2922 | if (endIt.isValid())
| 0 | ||||||||||||||||||||||||
2923 | endIt = endIt.next(); never executed: endIt = endIt.next(); | 0 | ||||||||||||||||||||||||
2924 | for (QTextBlock blockIt = startIt; blockIt.isValid() && blockIt != endIt; blockIt = blockIt.next())
| 0 | ||||||||||||||||||||||||
2925 | blockIt.clearLayout(); never executed: blockIt.clearLayout(); | 0 | ||||||||||||||||||||||||
2926 | - | |||||||||||||||||||||||||
2927 | if (d->docPrivate->pageSize.isNull())
| 0 | ||||||||||||||||||||||||
2928 | return; never executed: return; | 0 | ||||||||||||||||||||||||
2929 | - | |||||||||||||||||||||||||
2930 | QRectF updateRect; | - | ||||||||||||||||||||||||
2931 | - | |||||||||||||||||||||||||
2932 | d->lazyLayoutStepSize = 1000; | - | ||||||||||||||||||||||||
2933 | d->sizeChangedTimer.stop(); | - | ||||||||||||||||||||||||
2934 | d->insideDocumentChange = true; | - | ||||||||||||||||||||||||
2935 | - | |||||||||||||||||||||||||
2936 | const int documentLength = d->docPrivate->length(); | - | ||||||||||||||||||||||||
2937 | const bool fullLayout = (oldLength == 0 && length == documentLength);
| 0 | ||||||||||||||||||||||||
2938 | const bool smallChange = documentLength > 0
| 0 | ||||||||||||||||||||||||
2939 | && (qMax(length, oldLength) * 100 / documentLength) < 5;
| 0 | ||||||||||||||||||||||||
2940 | - | |||||||||||||||||||||||||
2941 | // don't show incremental layout progress (avoid scroll bar flicker) | - | ||||||||||||||||||||||||
2942 | // if we see only a small change in the document and we're either starting | - | ||||||||||||||||||||||||
2943 | // a layout run or we're already in progress for that and we haven't seen | - | ||||||||||||||||||||||||
2944 | // any bigger change previously (showLayoutProgress already false) | - | ||||||||||||||||||||||||
2945 | if (smallChange
| 0 | ||||||||||||||||||||||||
2946 | && (d->currentLazyLayoutPosition == -1 || d->showLayoutProgress == false))
| 0 | ||||||||||||||||||||||||
2947 | d->showLayoutProgress = false; never executed: d->showLayoutProgress = false; | 0 | ||||||||||||||||||||||||
2948 | else | - | ||||||||||||||||||||||||
2949 | d->showLayoutProgress = true; never executed: d->showLayoutProgress = true; | 0 | ||||||||||||||||||||||||
2950 | - | |||||||||||||||||||||||||
2951 | if (fullLayout) {
| 0 | ||||||||||||||||||||||||
2952 | d->contentHasAlignment = false; | - | ||||||||||||||||||||||||
2953 | d->currentLazyLayoutPosition = 0; | - | ||||||||||||||||||||||||
2954 | d->checkPoints.clear(); | - | ||||||||||||||||||||||||
2955 | d->layoutStep(); | - | ||||||||||||||||||||||||
2956 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
2957 | d->ensureLayoutedByPosition(from); | - | ||||||||||||||||||||||||
2958 | updateRect = doLayout(from, oldLength, length); | - | ||||||||||||||||||||||||
2959 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2960 | - | |||||||||||||||||||||||||
2961 | if (!d->layoutTimer.isActive() && d->currentLazyLayoutPosition != -1)
| 0 | ||||||||||||||||||||||||
2962 | d->layoutTimer.start(10, this); never executed: d->layoutTimer.start(10, this); | 0 | ||||||||||||||||||||||||
2963 | - | |||||||||||||||||||||||||
2964 | d->insideDocumentChange = false; | - | ||||||||||||||||||||||||
2965 | - | |||||||||||||||||||||||||
2966 | for (QTextBlock blockIt = startIt; blockIt.isValid() && blockIt != endIt; blockIt = blockIt.next())
| 0 | ||||||||||||||||||||||||
2967 | emit updateBlock(blockIt); never executed: updateBlock(blockIt); | 0 | ||||||||||||||||||||||||
2968 | - | |||||||||||||||||||||||||
2969 | if (d->showLayoutProgress) {
| 0 | ||||||||||||||||||||||||
2970 | const QSizeF newSize = dynamicDocumentSize(); | - | ||||||||||||||||||||||||
2971 | if (newSize != d->lastReportedSize) {
| 0 | ||||||||||||||||||||||||
2972 | d->lastReportedSize = newSize; | - | ||||||||||||||||||||||||
2973 | emit documentSizeChanged(newSize); | - | ||||||||||||||||||||||||
2974 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2975 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2976 | - | |||||||||||||||||||||||||
2977 | if (!updateRect.isValid()) {
| 0 | ||||||||||||||||||||||||
2978 | // don't use the frame size, it might have shrunken | - | ||||||||||||||||||||||||
2979 | updateRect = QRectF(QPointF(0, 0), QSizeF(qreal(INT_MAX), qreal(INT_MAX))); | - | ||||||||||||||||||||||||
2980 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2981 | - | |||||||||||||||||||||||||
2982 | emit update(updateRect); | - | ||||||||||||||||||||||||
2983 | } never executed: end of block | 0 | ||||||||||||||||||||||||
2984 | - | |||||||||||||||||||||||||
2985 | QRectF QTextDocumentLayout::doLayout(int from, int oldLength, int length) | - | ||||||||||||||||||||||||
2986 | { | - | ||||||||||||||||||||||||
2987 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
2988 | - | |||||||||||||||||||||||||
2989 | // qDebug("documentChange: from=%d, oldLength=%d, length=%d", from, oldLength, length); | - | ||||||||||||||||||||||||
2990 | - | |||||||||||||||||||||||||
2991 | // mark all frames between f_start and f_end as dirty | - | ||||||||||||||||||||||||
2992 | markFrames(d->docPrivate->rootFrame(), from, oldLength, length); | - | ||||||||||||||||||||||||
2993 | - | |||||||||||||||||||||||||
2994 | QRectF updateRect; | - | ||||||||||||||||||||||||
2995 | - | |||||||||||||||||||||||||
2996 | QTextFrame *root = d->docPrivate->rootFrame(); | - | ||||||||||||||||||||||||
2997 | if(data(root)->sizeDirty)
| 0 | ||||||||||||||||||||||||
2998 | updateRect = d->layoutFrame(root, from, from + length); never executed: updateRect = d->layoutFrame(root, from, from + length); | 0 | ||||||||||||||||||||||||
2999 | data(root)->layoutDirty = false; | - | ||||||||||||||||||||||||
3000 | - | |||||||||||||||||||||||||
3001 | if (d->currentLazyLayoutPosition == -1)
| 0 | ||||||||||||||||||||||||
3002 | layoutFinished(); never executed: layoutFinished(); | 0 | ||||||||||||||||||||||||
3003 | else if (d->showLayoutProgress)
| 0 | ||||||||||||||||||||||||
3004 | d->sizeChangedTimer.start(0, this); never executed: d->sizeChangedTimer.start(0, this); | 0 | ||||||||||||||||||||||||
3005 | - | |||||||||||||||||||||||||
3006 | return updateRect; never executed: return updateRect; | 0 | ||||||||||||||||||||||||
3007 | } | - | ||||||||||||||||||||||||
3008 | - | |||||||||||||||||||||||||
3009 | int QTextDocumentLayout::hitTest(const QPointF &point, Qt::HitTestAccuracy accuracy) const | - | ||||||||||||||||||||||||
3010 | { | - | ||||||||||||||||||||||||
3011 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3012 | d->ensureLayouted(QFixed::fromReal(point.y())); | - | ||||||||||||||||||||||||
3013 | QTextFrame *f = d->docPrivate->rootFrame(); | - | ||||||||||||||||||||||||
3014 | int position = 0; | - | ||||||||||||||||||||||||
3015 | QTextLayout *l = 0; | - | ||||||||||||||||||||||||
3016 | QFixedPoint pointf; | - | ||||||||||||||||||||||||
3017 | pointf.x = QFixed::fromReal(point.x()); | - | ||||||||||||||||||||||||
3018 | pointf.y = QFixed::fromReal(point.y()); | - | ||||||||||||||||||||||||
3019 | QTextDocumentLayoutPrivate::HitPoint p = d->hitTest(f, pointf, &position, &l, accuracy); | - | ||||||||||||||||||||||||
3020 | if (accuracy == Qt::ExactHit && p < QTextDocumentLayoutPrivate::PointExact)
| 0 | ||||||||||||||||||||||||
3021 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
3022 | - | |||||||||||||||||||||||||
3023 | // ensure we stay within document bounds | - | ||||||||||||||||||||||||
3024 | int lastPos = f->lastPosition(); | - | ||||||||||||||||||||||||
3025 | if (l && !l->preeditAreaText().isEmpty())
| 0 | ||||||||||||||||||||||||
3026 | lastPos += l->preeditAreaText().length(); never executed: lastPos += l->preeditAreaText().length(); | 0 | ||||||||||||||||||||||||
3027 | if (position > lastPos)
| 0 | ||||||||||||||||||||||||
3028 | position = lastPos; never executed: position = lastPos; | 0 | ||||||||||||||||||||||||
3029 | else if (position < 0)
| 0 | ||||||||||||||||||||||||
3030 | position = 0; never executed: position = 0; | 0 | ||||||||||||||||||||||||
3031 | - | |||||||||||||||||||||||||
3032 | return position; never executed: return position; | 0 | ||||||||||||||||||||||||
3033 | } | - | ||||||||||||||||||||||||
3034 | - | |||||||||||||||||||||||||
3035 | void QTextDocumentLayout::resizeInlineObject(QTextInlineObject item, int posInDocument, const QTextFormat &format) | - | ||||||||||||||||||||||||
3036 | { | - | ||||||||||||||||||||||||
3037 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
3038 | QTextCharFormat f = format.toCharFormat(); | - | ||||||||||||||||||||||||
3039 | Q_ASSERT(f.isValid()); | - | ||||||||||||||||||||||||
3040 | QTextObjectHandler handler = d->handlers.value(f.objectType()); | - | ||||||||||||||||||||||||
3041 | if (!handler.component)
| 0 | ||||||||||||||||||||||||
3042 | return; never executed: return; | 0 | ||||||||||||||||||||||||
3043 | - | |||||||||||||||||||||||||
3044 | QSizeF intrinsic = handler.iface->intrinsicSize(d->document, posInDocument, format); | - | ||||||||||||||||||||||||
3045 | - | |||||||||||||||||||||||||
3046 | QTextFrameFormat::Position pos = QTextFrameFormat::InFlow; | - | ||||||||||||||||||||||||
3047 | QTextFrame *frame = qobject_cast<QTextFrame *>(d->document->objectForFormat(f)); | - | ||||||||||||||||||||||||
3048 | if (frame) {
| 0 | ||||||||||||||||||||||||
3049 | pos = frame->frameFormat().position(); | - | ||||||||||||||||||||||||
3050 | QTextFrameData *fd = data(frame); | - | ||||||||||||||||||||||||
3051 | fd->sizeDirty = false; | - | ||||||||||||||||||||||||
3052 | fd->size = QFixedSize::fromSizeF(intrinsic); | - | ||||||||||||||||||||||||
3053 | fd->minimumWidth = fd->maximumWidth = fd->size.width; | - | ||||||||||||||||||||||||
3054 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3055 | - | |||||||||||||||||||||||||
3056 | QSizeF inlineSize = (pos == QTextFrameFormat::InFlow ? intrinsic : QSizeF(0, 0));
| 0 | ||||||||||||||||||||||||
3057 | item.setWidth(inlineSize.width()); | - | ||||||||||||||||||||||||
3058 | - | |||||||||||||||||||||||||
3059 | QFontMetrics m(f.font()); | - | ||||||||||||||||||||||||
3060 | switch (f.verticalAlignment()) | - | ||||||||||||||||||||||||
3061 | { | - | ||||||||||||||||||||||||
3062 | case QTextCharFormat::AlignMiddle: never executed: case QTextCharFormat::AlignMiddle: | 0 | ||||||||||||||||||||||||
3063 | item.setDescent(inlineSize.height() / 2); | - | ||||||||||||||||||||||||
3064 | item.setAscent(inlineSize.height() / 2); | - | ||||||||||||||||||||||||
3065 | break; never executed: break; | 0 | ||||||||||||||||||||||||
3066 | case QTextCharFormat::AlignBaseline: never executed: case QTextCharFormat::AlignBaseline: | 0 | ||||||||||||||||||||||||
3067 | item.setDescent(m.descent()); | - | ||||||||||||||||||||||||
3068 | item.setAscent(inlineSize.height() - m.descent()); | - | ||||||||||||||||||||||||
3069 | break; never executed: break; | 0 | ||||||||||||||||||||||||
3070 | default: never executed: default: | 0 | ||||||||||||||||||||||||
3071 | item.setDescent(0); | - | ||||||||||||||||||||||||
3072 | item.setAscent(inlineSize.height()); | - | ||||||||||||||||||||||||
3073 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3074 | } | - | ||||||||||||||||||||||||
3075 | - | |||||||||||||||||||||||||
3076 | void QTextDocumentLayout::positionInlineObject(QTextInlineObject item, int posInDocument, const QTextFormat &format) | - | ||||||||||||||||||||||||
3077 | { | - | ||||||||||||||||||||||||
3078 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
3079 | Q_UNUSED(posInDocument); | - | ||||||||||||||||||||||||
3080 | if (item.width() != 0)
| 0 | ||||||||||||||||||||||||
3081 | // inline | - | ||||||||||||||||||||||||
3082 | return; never executed: return; | 0 | ||||||||||||||||||||||||
3083 | - | |||||||||||||||||||||||||
3084 | QTextCharFormat f = format.toCharFormat(); | - | ||||||||||||||||||||||||
3085 | Q_ASSERT(f.isValid()); | - | ||||||||||||||||||||||||
3086 | QTextObjectHandler handler = d->handlers.value(f.objectType()); | - | ||||||||||||||||||||||||
3087 | if (!handler.component)
| 0 | ||||||||||||||||||||||||
3088 | return; never executed: return; | 0 | ||||||||||||||||||||||||
3089 | - | |||||||||||||||||||||||||
3090 | QTextFrame *frame = qobject_cast<QTextFrame *>(d->document->objectForFormat(f)); | - | ||||||||||||||||||||||||
3091 | if (!frame)
| 0 | ||||||||||||||||||||||||
3092 | return; never executed: return; | 0 | ||||||||||||||||||||||||
3093 | - | |||||||||||||||||||||||||
3094 | QTextBlock b = d->document->findBlock(frame->firstPosition()); | - | ||||||||||||||||||||||||
3095 | QTextLine line; | - | ||||||||||||||||||||||||
3096 | if (b.position() <= frame->firstPosition() && b.position() + b.length() > frame->lastPosition())
| 0 | ||||||||||||||||||||||||
3097 | line = b.layout()->lineAt(b.layout()->lineCount()-1); never executed: line = b.layout()->lineAt(b.layout()->lineCount()-1); | 0 | ||||||||||||||||||||||||
3098 | // qDebug() << "layoutObject: line.isValid" << line.isValid() << b.position() << b.length() << | - | ||||||||||||||||||||||||
3099 | // frame->firstPosition() << frame->lastPosition(); | - | ||||||||||||||||||||||||
3100 | d->positionFloat(frame, line.isValid() ? &line : 0); | - | ||||||||||||||||||||||||
3101 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3102 | - | |||||||||||||||||||||||||
3103 | void QTextDocumentLayout::drawInlineObject(QPainter *p, const QRectF &rect, QTextInlineObject item, | - | ||||||||||||||||||||||||
3104 | int posInDocument, const QTextFormat &format) | - | ||||||||||||||||||||||||
3105 | { | - | ||||||||||||||||||||||||
3106 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
3107 | QTextCharFormat f = format.toCharFormat(); | - | ||||||||||||||||||||||||
3108 | Q_ASSERT(f.isValid()); | - | ||||||||||||||||||||||||
3109 | QTextFrame *frame = qobject_cast<QTextFrame *>(d->document->objectForFormat(f)); | - | ||||||||||||||||||||||||
3110 | if (frame && frame->frameFormat().position() != QTextFrameFormat::InFlow)
| 0 | ||||||||||||||||||||||||
3111 | return; // don't draw floating frames from inline objects here but in drawFlow instead never executed: return; | 0 | ||||||||||||||||||||||||
3112 | - | |||||||||||||||||||||||||
3113 | // qDebug() << "drawObject at" << r; | - | ||||||||||||||||||||||||
3114 | QAbstractTextDocumentLayout::drawInlineObject(p, rect, item, posInDocument, format); | - | ||||||||||||||||||||||||
3115 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3116 | - | |||||||||||||||||||||||||
3117 | int QTextDocumentLayout::dynamicPageCount() const | - | ||||||||||||||||||||||||
3118 | { | - | ||||||||||||||||||||||||
3119 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3120 | const QSizeF pgSize = d->document->pageSize(); | - | ||||||||||||||||||||||||
3121 | if (pgSize.height() < 0)
| 0 | ||||||||||||||||||||||||
3122 | return 1; never executed: return 1; | 0 | ||||||||||||||||||||||||
3123 | return qCeil(dynamicDocumentSize().height() / pgSize.height()); never executed: return qCeil(dynamicDocumentSize().height() / pgSize.height()); | 0 | ||||||||||||||||||||||||
3124 | } | - | ||||||||||||||||||||||||
3125 | - | |||||||||||||||||||||||||
3126 | QSizeF QTextDocumentLayout::dynamicDocumentSize() const | - | ||||||||||||||||||||||||
3127 | { | - | ||||||||||||||||||||||||
3128 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3129 | return data(d->docPrivate->rootFrame())->size.toSizeF(); never executed: return data(d->docPrivate->rootFrame())->size.toSizeF(); | 0 | ||||||||||||||||||||||||
3130 | } | - | ||||||||||||||||||||||||
3131 | - | |||||||||||||||||||||||||
3132 | int QTextDocumentLayout::pageCount() const | - | ||||||||||||||||||||||||
3133 | { | - | ||||||||||||||||||||||||
3134 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3135 | d->ensureLayoutFinished(); | - | ||||||||||||||||||||||||
3136 | return dynamicPageCount(); never executed: return dynamicPageCount(); | 0 | ||||||||||||||||||||||||
3137 | } | - | ||||||||||||||||||||||||
3138 | - | |||||||||||||||||||||||||
3139 | QSizeF QTextDocumentLayout::documentSize() const | - | ||||||||||||||||||||||||
3140 | { | - | ||||||||||||||||||||||||
3141 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3142 | d->ensureLayoutFinished(); | - | ||||||||||||||||||||||||
3143 | return dynamicDocumentSize(); never executed: return dynamicDocumentSize(); | 0 | ||||||||||||||||||||||||
3144 | } | - | ||||||||||||||||||||||||
3145 | - | |||||||||||||||||||||||||
3146 | void QTextDocumentLayoutPrivate::ensureLayouted(QFixed y) const | - | ||||||||||||||||||||||||
3147 | { | - | ||||||||||||||||||||||||
3148 | Q_Q(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3149 | if (currentLazyLayoutPosition == -1)
| 0 | ||||||||||||||||||||||||
3150 | return; never executed: return; | 0 | ||||||||||||||||||||||||
3151 | const QSizeF oldSize = q->dynamicDocumentSize(); | - | ||||||||||||||||||||||||
3152 | Q_UNUSED(oldSize); | - | ||||||||||||||||||||||||
3153 | - | |||||||||||||||||||||||||
3154 | if (checkPoints.isEmpty())
| 0 | ||||||||||||||||||||||||
3155 | layoutStep(); never executed: layoutStep(); | 0 | ||||||||||||||||||||||||
3156 | - | |||||||||||||||||||||||||
3157 | while (currentLazyLayoutPosition != -1
| 0 | ||||||||||||||||||||||||
3158 | && checkPoints.last().y < y)
| 0 | ||||||||||||||||||||||||
3159 | layoutStep(); never executed: layoutStep(); | 0 | ||||||||||||||||||||||||
3160 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3161 | - | |||||||||||||||||||||||||
3162 | void QTextDocumentLayoutPrivate::ensureLayoutedByPosition(int position) const | - | ||||||||||||||||||||||||
3163 | { | - | ||||||||||||||||||||||||
3164 | if (currentLazyLayoutPosition == -1)
| 0 | ||||||||||||||||||||||||
3165 | return; never executed: return; | 0 | ||||||||||||||||||||||||
3166 | if (position < currentLazyLayoutPosition)
| 0 | ||||||||||||||||||||||||
3167 | return; never executed: return; | 0 | ||||||||||||||||||||||||
3168 | while (currentLazyLayoutPosition != -1
| 0 | ||||||||||||||||||||||||
3169 | && currentLazyLayoutPosition < position) {
| 0 | ||||||||||||||||||||||||
3170 | const_cast<QTextDocumentLayout *>(q_func())->doLayout(currentLazyLayoutPosition, 0, INT_MAX - currentLazyLayoutPosition); | - | ||||||||||||||||||||||||
3171 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3172 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3173 | - | |||||||||||||||||||||||||
3174 | void QTextDocumentLayoutPrivate::layoutStep() const | - | ||||||||||||||||||||||||
3175 | { | - | ||||||||||||||||||||||||
3176 | ensureLayoutedByPosition(currentLazyLayoutPosition + lazyLayoutStepSize); | - | ||||||||||||||||||||||||
3177 | lazyLayoutStepSize = qMin(200000, lazyLayoutStepSize * 2); | - | ||||||||||||||||||||||||
3178 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3179 | - | |||||||||||||||||||||||||
3180 | void QTextDocumentLayout::setCursorWidth(int width) | - | ||||||||||||||||||||||||
3181 | { | - | ||||||||||||||||||||||||
3182 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
3183 | d->cursorWidth = width; | - | ||||||||||||||||||||||||
3184 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3185 | - | |||||||||||||||||||||||||
3186 | int QTextDocumentLayout::cursorWidth() const | - | ||||||||||||||||||||||||
3187 | { | - | ||||||||||||||||||||||||
3188 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3189 | return d->cursorWidth; never executed: return d->cursorWidth; | 0 | ||||||||||||||||||||||||
3190 | } | - | ||||||||||||||||||||||||
3191 | - | |||||||||||||||||||||||||
3192 | void QTextDocumentLayout::setFixedColumnWidth(int width) | - | ||||||||||||||||||||||||
3193 | { | - | ||||||||||||||||||||||||
3194 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
3195 | d->fixedColumnWidth = width; | - | ||||||||||||||||||||||||
3196 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3197 | - | |||||||||||||||||||||||||
3198 | QRectF QTextDocumentLayout::tableCellBoundingRect(QTextTable *table, const QTextTableCell &cell) const | - | ||||||||||||||||||||||||
3199 | { | - | ||||||||||||||||||||||||
3200 | if (!cell.isValid())
| 0 | ||||||||||||||||||||||||
3201 | return QRectF(); never executed: return QRectF(); | 0 | ||||||||||||||||||||||||
3202 | - | |||||||||||||||||||||||||
3203 | QTextTableData *td = static_cast<QTextTableData *>(data(table)); | - | ||||||||||||||||||||||||
3204 | - | |||||||||||||||||||||||||
3205 | QRectF tableRect = tableBoundingRect(table); | - | ||||||||||||||||||||||||
3206 | QRectF cellRect = td->cellRect(cell); | - | ||||||||||||||||||||||||
3207 | - | |||||||||||||||||||||||||
3208 | return cellRect.translated(tableRect.topLeft()); never executed: return cellRect.translated(tableRect.topLeft()); | 0 | ||||||||||||||||||||||||
3209 | } | - | ||||||||||||||||||||||||
3210 | - | |||||||||||||||||||||||||
3211 | QRectF QTextDocumentLayout::tableBoundingRect(QTextTable *table) const | - | ||||||||||||||||||||||||
3212 | { | - | ||||||||||||||||||||||||
3213 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3214 | if (d->docPrivate->pageSize.isNull())
| 0 | ||||||||||||||||||||||||
3215 | return QRectF(); never executed: return QRectF(); | 0 | ||||||||||||||||||||||||
3216 | d->ensureLayoutFinished(); | - | ||||||||||||||||||||||||
3217 | - | |||||||||||||||||||||||||
3218 | QPointF pos; | - | ||||||||||||||||||||||||
3219 | const int framePos = table->firstPosition(); | - | ||||||||||||||||||||||||
3220 | QTextFrame *f = table; | - | ||||||||||||||||||||||||
3221 | while (f) {
| 0 | ||||||||||||||||||||||||
3222 | QTextFrameData *fd = data(f); | - | ||||||||||||||||||||||||
3223 | pos += fd->position.toPointF(); | - | ||||||||||||||||||||||||
3224 | - | |||||||||||||||||||||||||
3225 | if (f != table) {
| 0 | ||||||||||||||||||||||||
3226 | if (QTextTable *table = qobject_cast<QTextTable *>(f)) {
| 0 | ||||||||||||||||||||||||
3227 | QTextTableCell cell = table->cellAt(framePos); | - | ||||||||||||||||||||||||
3228 | if (cell.isValid())
| 0 | ||||||||||||||||||||||||
3229 | pos += static_cast<QTextTableData *>(fd)->cellPosition(cell).toPointF(); never executed: pos += static_cast<QTextTableData *>(fd)->cellPosition(cell).toPointF(); | 0 | ||||||||||||||||||||||||
3230 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3231 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3232 | - | |||||||||||||||||||||||||
3233 | f = f->parentFrame(); | - | ||||||||||||||||||||||||
3234 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3235 | return QRectF(pos, data(table)->size.toSizeF()); never executed: return QRectF(pos, data(table)->size.toSizeF()); | 0 | ||||||||||||||||||||||||
3236 | } | - | ||||||||||||||||||||||||
3237 | - | |||||||||||||||||||||||||
3238 | QRectF QTextDocumentLayout::frameBoundingRect(QTextFrame *frame) const | - | ||||||||||||||||||||||||
3239 | { | - | ||||||||||||||||||||||||
3240 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3241 | if (d->docPrivate->pageSize.isNull())
| 0 | ||||||||||||||||||||||||
3242 | return QRectF(); never executed: return QRectF(); | 0 | ||||||||||||||||||||||||
3243 | d->ensureLayoutFinished(); | - | ||||||||||||||||||||||||
3244 | return d->frameBoundingRectInternal(frame); never executed: return d->frameBoundingRectInternal(frame); | 0 | ||||||||||||||||||||||||
3245 | } | - | ||||||||||||||||||||||||
3246 | - | |||||||||||||||||||||||||
3247 | QRectF QTextDocumentLayoutPrivate::frameBoundingRectInternal(QTextFrame *frame) const | - | ||||||||||||||||||||||||
3248 | { | - | ||||||||||||||||||||||||
3249 | QPointF pos; | - | ||||||||||||||||||||||||
3250 | const int framePos = frame->firstPosition(); | - | ||||||||||||||||||||||||
3251 | QTextFrame *f = frame; | - | ||||||||||||||||||||||||
3252 | while (f) {
| 0 | ||||||||||||||||||||||||
3253 | QTextFrameData *fd = data(f); | - | ||||||||||||||||||||||||
3254 | pos += fd->position.toPointF(); | - | ||||||||||||||||||||||||
3255 | - | |||||||||||||||||||||||||
3256 | if (QTextTable *table = qobject_cast<QTextTable *>(f)) {
| 0 | ||||||||||||||||||||||||
3257 | QTextTableCell cell = table->cellAt(framePos); | - | ||||||||||||||||||||||||
3258 | if (cell.isValid())
| 0 | ||||||||||||||||||||||||
3259 | pos += static_cast<QTextTableData *>(fd)->cellPosition(cell).toPointF(); never executed: pos += static_cast<QTextTableData *>(fd)->cellPosition(cell).toPointF(); | 0 | ||||||||||||||||||||||||
3260 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3261 | - | |||||||||||||||||||||||||
3262 | f = f->parentFrame(); | - | ||||||||||||||||||||||||
3263 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3264 | return QRectF(pos, data(frame)->size.toSizeF()); never executed: return QRectF(pos, data(frame)->size.toSizeF()); | 0 | ||||||||||||||||||||||||
3265 | } | - | ||||||||||||||||||||||||
3266 | - | |||||||||||||||||||||||||
3267 | QRectF QTextDocumentLayout::blockBoundingRect(const QTextBlock &block) const | - | ||||||||||||||||||||||||
3268 | { | - | ||||||||||||||||||||||||
3269 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3270 | if (d->docPrivate->pageSize.isNull() || !block.isValid() || !block.isVisible())
| 0 | ||||||||||||||||||||||||
3271 | return QRectF(); never executed: return QRectF(); | 0 | ||||||||||||||||||||||||
3272 | d->ensureLayoutedByPosition(block.position() + block.length()); | - | ||||||||||||||||||||||||
3273 | QTextFrame *frame = d->document->frameAt(block.position()); | - | ||||||||||||||||||||||||
3274 | QPointF offset; | - | ||||||||||||||||||||||||
3275 | const int blockPos = block.position(); | - | ||||||||||||||||||||||||
3276 | - | |||||||||||||||||||||||||
3277 | while (frame) {
| 0 | ||||||||||||||||||||||||
3278 | QTextFrameData *fd = data(frame); | - | ||||||||||||||||||||||||
3279 | offset += fd->position.toPointF(); | - | ||||||||||||||||||||||||
3280 | - | |||||||||||||||||||||||||
3281 | if (QTextTable *table = qobject_cast<QTextTable *>(frame)) {
| 0 | ||||||||||||||||||||||||
3282 | QTextTableCell cell = table->cellAt(blockPos); | - | ||||||||||||||||||||||||
3283 | if (cell.isValid())
| 0 | ||||||||||||||||||||||||
3284 | offset += static_cast<QTextTableData *>(fd)->cellPosition(cell).toPointF(); never executed: offset += static_cast<QTextTableData *>(fd)->cellPosition(cell).toPointF(); | 0 | ||||||||||||||||||||||||
3285 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3286 | - | |||||||||||||||||||||||||
3287 | frame = frame->parentFrame(); | - | ||||||||||||||||||||||||
3288 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3289 | - | |||||||||||||||||||||||||
3290 | const QTextLayout *layout = block.layout(); | - | ||||||||||||||||||||||||
3291 | QRectF rect = layout->boundingRect(); | - | ||||||||||||||||||||||||
3292 | rect.moveTopLeft(layout->position() + offset); | - | ||||||||||||||||||||||||
3293 | return rect; never executed: return rect; | 0 | ||||||||||||||||||||||||
3294 | } | - | ||||||||||||||||||||||||
3295 | - | |||||||||||||||||||||||||
3296 | int QTextDocumentLayout::layoutStatus() const | - | ||||||||||||||||||||||||
3297 | { | - | ||||||||||||||||||||||||
3298 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3299 | int pos = d->currentLazyLayoutPosition; | - | ||||||||||||||||||||||||
3300 | if (pos == -1)
| 0 | ||||||||||||||||||||||||
3301 | return 100; never executed: return 100; | 0 | ||||||||||||||||||||||||
3302 | return pos * 100 / d->document->docHandle()->length(); never executed: return pos * 100 / d->document->docHandle()->length(); | 0 | ||||||||||||||||||||||||
3303 | } | - | ||||||||||||||||||||||||
3304 | - | |||||||||||||||||||||||||
3305 | void QTextDocumentLayout::timerEvent(QTimerEvent *e) | - | ||||||||||||||||||||||||
3306 | { | - | ||||||||||||||||||||||||
3307 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
3308 | if (e->timerId() == d->layoutTimer.timerId()) {
| 0 | ||||||||||||||||||||||||
3309 | if (d->currentLazyLayoutPosition != -1)
| 0 | ||||||||||||||||||||||||
3310 | d->layoutStep(); never executed: d->layoutStep(); | 0 | ||||||||||||||||||||||||
3311 | } else if (e->timerId() == d->sizeChangedTimer.timerId()) { never executed: end of block
| 0 | ||||||||||||||||||||||||
3312 | d->lastReportedSize = dynamicDocumentSize(); | - | ||||||||||||||||||||||||
3313 | emit documentSizeChanged(d->lastReportedSize); | - | ||||||||||||||||||||||||
3314 | d->sizeChangedTimer.stop(); | - | ||||||||||||||||||||||||
3315 | - | |||||||||||||||||||||||||
3316 | if (d->currentLazyLayoutPosition == -1) {
| 0 | ||||||||||||||||||||||||
3317 | const int newCount = dynamicPageCount(); | - | ||||||||||||||||||||||||
3318 | if (newCount != d->lastPageCount) {
| 0 | ||||||||||||||||||||||||
3319 | d->lastPageCount = newCount; | - | ||||||||||||||||||||||||
3320 | emit pageCountChanged(newCount); | - | ||||||||||||||||||||||||
3321 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3322 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3323 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
3324 | QAbstractTextDocumentLayout::timerEvent(e); | - | ||||||||||||||||||||||||
3325 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3326 | } | - | ||||||||||||||||||||||||
3327 | - | |||||||||||||||||||||||||
3328 | void QTextDocumentLayout::layoutFinished() | - | ||||||||||||||||||||||||
3329 | { | - | ||||||||||||||||||||||||
3330 | Q_D(QTextDocumentLayout); | - | ||||||||||||||||||||||||
3331 | d->layoutTimer.stop(); | - | ||||||||||||||||||||||||
3332 | if (!d->insideDocumentChange)
| 0 | ||||||||||||||||||||||||
3333 | d->sizeChangedTimer.start(0, this); never executed: d->sizeChangedTimer.start(0, this); | 0 | ||||||||||||||||||||||||
3334 | // reset | - | ||||||||||||||||||||||||
3335 | d->showLayoutProgress = true; | - | ||||||||||||||||||||||||
3336 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3337 | - | |||||||||||||||||||||||||
3338 | void QTextDocumentLayout::ensureLayouted(qreal y) | - | ||||||||||||||||||||||||
3339 | { | - | ||||||||||||||||||||||||
3340 | d_func()->ensureLayouted(QFixed::fromReal(y)); | - | ||||||||||||||||||||||||
3341 | } never executed: end of block | 0 | ||||||||||||||||||||||||
3342 | - | |||||||||||||||||||||||||
3343 | qreal QTextDocumentLayout::idealWidth() const | - | ||||||||||||||||||||||||
3344 | { | - | ||||||||||||||||||||||||
3345 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3346 | d->ensureLayoutFinished(); | - | ||||||||||||||||||||||||
3347 | return d->idealWidth; never executed: return d->idealWidth; | 0 | ||||||||||||||||||||||||
3348 | } | - | ||||||||||||||||||||||||
3349 | - | |||||||||||||||||||||||||
3350 | bool QTextDocumentLayout::contentHasAlignment() const | - | ||||||||||||||||||||||||
3351 | { | - | ||||||||||||||||||||||||
3352 | Q_D(const QTextDocumentLayout); | - | ||||||||||||||||||||||||
3353 | return d->contentHasAlignment; never executed: return d->contentHasAlignment; | 0 | ||||||||||||||||||||||||
3354 | } | - | ||||||||||||||||||||||||
3355 | - | |||||||||||||||||||||||||
3356 | qreal QTextDocumentLayoutPrivate::scaleToDevice(qreal value) const | - | ||||||||||||||||||||||||
3357 | { | - | ||||||||||||||||||||||||
3358 | if (!paintDevice)
| 0 | ||||||||||||||||||||||||
3359 | return value; never executed: return value; | 0 | ||||||||||||||||||||||||
3360 | return value * paintDevice->logicalDpiY() / qreal(qt_defaultDpi()); never executed: return value * paintDevice->logicalDpiY() / qreal(qt_defaultDpi()); | 0 | ||||||||||||||||||||||||
3361 | } | - | ||||||||||||||||||||||||
3362 | - | |||||||||||||||||||||||||
3363 | QFixed QTextDocumentLayoutPrivate::scaleToDevice(QFixed value) const | - | ||||||||||||||||||||||||
3364 | { | - | ||||||||||||||||||||||||
3365 | if (!paintDevice)
| 0 | ||||||||||||||||||||||||
3366 | return value; never executed: return value; | 0 | ||||||||||||||||||||||||
3367 | return value * QFixed(paintDevice->logicalDpiY()) / QFixed(qt_defaultDpi()); never executed: return value * QFixed(paintDevice->logicalDpiY()) / QFixed(qt_defaultDpi()); | 0 | ||||||||||||||||||||||||
3368 | } | - | ||||||||||||||||||||||||
3369 | - | |||||||||||||||||||||||||
3370 | QT_END_NAMESPACE | - | ||||||||||||||||||||||||
3371 | - | |||||||||||||||||||||||||
3372 | #include "moc_qtextdocumentlayout_p.cpp" | - | ||||||||||||||||||||||||
Source code | Switch to Preprocessed file |