changeset 33 | 3e2da88830cd |
parent 22 | 79de32ba3296 |
30:5dc02b23752f | 33:3e2da88830cd |
---|---|
77 |
77 |
78 Q_GUI_EXPORT extern int qt_defaultDpi(); |
78 Q_GUI_EXPORT extern int qt_defaultDpi(); |
79 |
79 |
80 // ################ should probably add frameFormatChange notification! |
80 // ################ should probably add frameFormatChange notification! |
81 |
81 |
82 struct QLayoutStruct; |
82 struct QTextLayoutStruct; |
83 |
83 |
84 class QTextFrameData : public QTextFrameLayoutData |
84 class QTextFrameData : public QTextFrameLayoutData |
85 { |
85 { |
86 public: |
86 public: |
87 QTextFrameData(); |
87 QTextFrameData(); |
107 QFixed effectiveBottomMargin; |
107 QFixed effectiveBottomMargin; |
108 |
108 |
109 QFixed minimumWidth; |
109 QFixed minimumWidth; |
110 QFixed maximumWidth; |
110 QFixed maximumWidth; |
111 |
111 |
112 QLayoutStruct *currentLayoutStruct; |
112 QTextLayoutStruct *currentLayoutStruct; |
113 |
113 |
114 bool sizeDirty; |
114 bool sizeDirty; |
115 bool layoutDirty; |
115 bool layoutDirty; |
116 |
116 |
117 QList<QPointer<QTextFrame> > floats; |
117 QList<QPointer<QTextFrame> > floats; |
121 : maximumWidth(QFIXED_MAX), |
121 : maximumWidth(QFIXED_MAX), |
122 currentLayoutStruct(0), sizeDirty(true), layoutDirty(true) |
122 currentLayoutStruct(0), sizeDirty(true), layoutDirty(true) |
123 { |
123 { |
124 } |
124 } |
125 |
125 |
126 struct QLayoutStruct { |
126 struct QTextLayoutStruct { |
127 QLayoutStruct() : maximumWidth(QFIXED_MAX), fullLayout(false) |
127 QTextLayoutStruct() : maximumWidth(QFIXED_MAX), fullLayout(false) |
128 {} |
128 {} |
129 QTextFrame *frame; |
129 QTextFrame *frame; |
130 QFixed x_left; |
130 QFixed x_left; |
131 QFixed x_right; |
131 QFixed x_right; |
132 QFixed frameY; // absolute y position of the current frame |
132 QFixed frameY; // absolute y position of the current frame |
475 HitPoint hitTest(QTextFrame::Iterator it, HitPoint hit, const QFixedPoint &p, |
475 HitPoint hitTest(QTextFrame::Iterator it, HitPoint hit, const QFixedPoint &p, |
476 int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; |
476 int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; |
477 HitPoint hitTest(QTextTable *table, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; |
477 HitPoint hitTest(QTextTable *table, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; |
478 HitPoint hitTest(QTextBlock bl, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; |
478 HitPoint hitTest(QTextBlock bl, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; |
479 |
479 |
480 QLayoutStruct layoutCell(QTextTable *t, const QTextTableCell &cell, QFixed width, |
480 QTextLayoutStruct layoutCell(QTextTable *t, const QTextTableCell &cell, QFixed width, |
481 int layoutFrom, int layoutTo, QTextTableData *tableData, QFixed absoluteTableY, |
481 int layoutFrom, int layoutTo, QTextTableData *tableData, QFixed absoluteTableY, |
482 bool withPageBreaks); |
482 bool withPageBreaks); |
483 void setCellPosition(QTextTable *t, const QTextTableCell &cell, const QPointF &pos); |
483 void setCellPosition(QTextTable *t, const QTextTableCell &cell, const QPointF &pos); |
484 QRectF layoutTable(QTextTable *t, int layoutFrom, int layoutTo, QFixed parentY); |
484 QRectF layoutTable(QTextTable *t, int layoutFrom, int layoutTo, QFixed parentY); |
485 |
485 |
486 void positionFloat(QTextFrame *frame, QTextLine *currentLine = 0); |
486 void positionFloat(QTextFrame *frame, QTextLine *currentLine = 0); |
487 |
487 |
488 // calls the next one |
488 // calls the next one |
489 QRectF layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed parentY = 0); |
489 QRectF layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed parentY = 0); |
490 QRectF layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed frameWidth, QFixed frameHeight, QFixed parentY = 0); |
490 QRectF layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed frameWidth, QFixed frameHeight, QFixed parentY = 0); |
491 |
491 |
492 void layoutBlock(const QTextBlock &bl, int blockPosition, const QTextBlockFormat &blockFormat, |
492 void layoutBlock(const QTextBlock &bl, int blockPosition, const QTextBlockFormat &blockFormat, |
493 QLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, const QTextBlockFormat *previousBlockFormat); |
493 QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, const QTextBlockFormat *previousBlockFormat); |
494 void layoutFlow(QTextFrame::Iterator it, QLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, QFixed width = 0); |
494 void layoutFlow(QTextFrame::Iterator it, QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, QFixed width = 0); |
495 void pageBreakInsideTable(QTextTable *table, QLayoutStruct *layoutStruct); |
495 void pageBreakInsideTable(QTextTable *table, QTextLayoutStruct *layoutStruct); |
496 |
496 |
497 |
497 |
498 void floatMargins(const QFixed &y, const QLayoutStruct *layoutStruct, QFixed *left, QFixed *right) const; |
498 void floatMargins(const QFixed &y, const QTextLayoutStruct *layoutStruct, QFixed *left, QFixed *right) const; |
499 QFixed findY(QFixed yFrom, const QLayoutStruct *layoutStruct, QFixed requiredWidth) const; |
499 QFixed findY(QFixed yFrom, const QTextLayoutStruct *layoutStruct, QFixed requiredWidth) const; |
500 |
500 |
501 QVector<QCheckPoint> checkPoints; |
501 QVector<QCheckPoint> checkPoints; |
502 |
502 |
503 QTextFrame::Iterator frameIteratorForYPosition(QFixed y) const; |
503 QTextFrame::Iterator frameIteratorForYPosition(QFixed y) const; |
504 QTextFrame::Iterator frameIteratorForTextPosition(int position) const; |
504 QTextFrame::Iterator frameIteratorForTextPosition(int position) const; |
1367 if (layout->lineCount() == 0) |
1367 if (layout->lineCount() == 0) |
1368 return; |
1368 return; |
1369 QTextLine firstLine = layout->lineAt(0); |
1369 QTextLine firstLine = layout->lineAt(0); |
1370 Q_ASSERT(firstLine.isValid()); |
1370 Q_ASSERT(firstLine.isValid()); |
1371 QPointF pos = (offset + layout->position()).toPoint(); |
1371 QPointF pos = (offset + layout->position()).toPoint(); |
1372 Qt::LayoutDirection dir = docPrivate->defaultTextOption.textDirection(); |
1372 Qt::LayoutDirection dir = bl.textDirection(); |
1373 if (blockFormat.hasProperty(QTextFormat::LayoutDirection)) |
|
1374 dir = blockFormat.layoutDirection(); |
|
1375 { |
1373 { |
1376 QRectF textRect = firstLine.naturalTextRect(); |
1374 QRectF textRect = firstLine.naturalTextRect(); |
1377 pos += textRect.topLeft().toPoint(); |
1375 pos += textRect.topLeft().toPoint(); |
1378 if (dir == Qt::RightToLeft) |
1376 if (dir == Qt::RightToLeft) |
1379 pos.rx() += textRect.width(); |
1377 pos.rx() += textRect.width(); |
1485 static QFixed firstChildPos(const QTextFrame *f) |
1483 static QFixed firstChildPos(const QTextFrame *f) |
1486 { |
1484 { |
1487 return flowPosition(f->begin()); |
1485 return flowPosition(f->begin()); |
1488 } |
1486 } |
1489 |
1487 |
1490 QLayoutStruct QTextDocumentLayoutPrivate::layoutCell(QTextTable *t, const QTextTableCell &cell, QFixed width, |
1488 QTextLayoutStruct QTextDocumentLayoutPrivate::layoutCell(QTextTable *t, const QTextTableCell &cell, QFixed width, |
1491 int layoutFrom, int layoutTo, QTextTableData *td, |
1489 int layoutFrom, int layoutTo, QTextTableData *td, |
1492 QFixed absoluteTableY, bool withPageBreaks) |
1490 QFixed absoluteTableY, bool withPageBreaks) |
1493 { |
1491 { |
1494 LDEBUG << "layoutCell"; |
1492 LDEBUG << "layoutCell"; |
1495 QLayoutStruct layoutStruct; |
1493 QTextLayoutStruct layoutStruct; |
1496 layoutStruct.frame = t; |
1494 layoutStruct.frame = t; |
1497 layoutStruct.minimumWidth = 0; |
1495 layoutStruct.minimumWidth = 0; |
1498 layoutStruct.maximumWidth = QFIXED_MAX; |
1496 layoutStruct.maximumWidth = QFIXED_MAX; |
1499 layoutStruct.y = 0; |
1497 layoutStruct.y = 0; |
1500 |
1498 |
1639 const QFixed widthPadding = leftPadding + rightPadding; |
1637 const QFixed widthPadding = leftPadding + rightPadding; |
1640 |
1638 |
1641 // to figure out the min and the max width lay out the cell at |
1639 // to figure out the min and the max width lay out the cell at |
1642 // maximum width. otherwise the maxwidth calculation sometimes |
1640 // maximum width. otherwise the maxwidth calculation sometimes |
1643 // returns wrong values |
1641 // returns wrong values |
1644 QLayoutStruct layoutStruct = layoutCell(table, cell, QFIXED_MAX, layoutFrom, |
1642 QTextLayoutStruct layoutStruct = layoutCell(table, cell, QFIXED_MAX, layoutFrom, |
1645 layoutTo, td, absoluteTableY, |
1643 layoutTo, td, absoluteTableY, |
1646 /*withPageBreaks =*/false); |
1644 /*withPageBreaks =*/false); |
1647 |
1645 |
1648 // distribute the minimum width over all columns the cell spans |
1646 // distribute the minimum width over all columns the cell spans |
1649 QFixed widthToDistribute = layoutStruct.minimumWidth + widthPadding; |
1647 QFixed widthToDistribute = layoutStruct.minimumWidth + widthPadding; |
1650 for (int n = 0; n < cspan; ++n) { |
1648 for (int n = 0; n < cspan; ++n) { |
1651 const int col = i + n; |
1649 const int col = i + n; |
1866 const QFixed widthPadding = leftPadding + rightPadding; |
1864 const QFixed widthPadding = leftPadding + rightPadding; |
1867 |
1865 |
1868 ++rowCellCount; |
1866 ++rowCellCount; |
1869 |
1867 |
1870 const QFixed width = td->cellWidth(c, cspan) - widthPadding; |
1868 const QFixed width = td->cellWidth(c, cspan) - widthPadding; |
1871 QLayoutStruct layoutStruct = layoutCell(table, cell, width, |
1869 QTextLayoutStruct layoutStruct = layoutCell(table, cell, width, |
1872 layoutFrom, layoutTo, |
1870 layoutFrom, layoutTo, |
1873 td, absoluteTableY, |
1871 td, absoluteTableY, |
1874 /*withPageBreaks =*/true); |
1872 /*withPageBreaks =*/true); |
1875 |
1873 |
1876 const QFixed height = layoutStruct.y + bottomPadding + topPadding; |
1874 const QFixed height = layoutStruct.y + bottomPadding + topPadding; |
1877 |
1875 |
1878 if (rspan > 1) |
1876 if (rspan > 1) |
1879 heightToDistribute[c] = height + dropDistance; |
1877 heightToDistribute[c] = height + dropDistance; |
1974 QTextFrame *parent = frame->parentFrame(); |
1972 QTextFrame *parent = frame->parentFrame(); |
1975 Q_ASSERT(parent); |
1973 Q_ASSERT(parent); |
1976 QTextFrameData *pd = data(parent); |
1974 QTextFrameData *pd = data(parent); |
1977 Q_ASSERT(pd && pd->currentLayoutStruct); |
1975 Q_ASSERT(pd && pd->currentLayoutStruct); |
1978 |
1976 |
1979 QLayoutStruct *layoutStruct = pd->currentLayoutStruct; |
1977 QTextLayoutStruct *layoutStruct = pd->currentLayoutStruct; |
1980 |
1978 |
1981 if (!pd->floats.contains(frame)) |
1979 if (!pd->floats.contains(frame)) |
1982 pd->floats.append(frame); |
1980 pd->floats.append(frame); |
1983 fd->layoutDirty = true; |
1981 fd->layoutDirty = true; |
1984 Q_ASSERT(!fd->sizeDirty); |
1982 Q_ASSERT(!fd->sizeDirty); |
2114 // set fd->contentsWidth temporarily, so that layoutFrame for the children |
2112 // set fd->contentsWidth temporarily, so that layoutFrame for the children |
2115 // picks the right width. We'll initialize it properly at the end of this |
2113 // picks the right width. We'll initialize it properly at the end of this |
2116 // function. |
2114 // function. |
2117 fd->contentsWidth = newContentsWidth; |
2115 fd->contentsWidth = newContentsWidth; |
2118 |
2116 |
2119 QLayoutStruct layoutStruct; |
2117 QTextLayoutStruct layoutStruct; |
2120 layoutStruct.frame = f; |
2118 layoutStruct.frame = f; |
2121 layoutStruct.x_left = fd->leftMargin + fd->border + fd->padding; |
2119 layoutStruct.x_left = fd->leftMargin + fd->border + fd->padding; |
2122 layoutStruct.x_right = layoutStruct.x_left + newContentsWidth; |
2120 layoutStruct.x_right = layoutStruct.x_left + newContentsWidth; |
2123 layoutStruct.y = fd->topMargin + fd->border + fd->padding; |
2121 layoutStruct.y = fd->topMargin + fd->border + fd->padding; |
2124 layoutStruct.frameY = parentY + fd->position.y; |
2122 layoutStruct.frameY = parentY + fd->position.y; |
2177 if (layoutStruct.updateRectForFloats.isValid()) |
2175 if (layoutStruct.updateRectForFloats.isValid()) |
2178 layoutStruct.updateRect |= layoutStruct.updateRectForFloats; |
2176 layoutStruct.updateRect |= layoutStruct.updateRectForFloats; |
2179 return layoutStruct.updateRect; |
2177 return layoutStruct.updateRect; |
2180 } |
2178 } |
2181 |
2179 |
2182 void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QLayoutStruct *layoutStruct, |
2180 void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QTextLayoutStruct *layoutStruct, |
2183 int layoutFrom, int layoutTo, QFixed width) |
2181 int layoutFrom, int layoutTo, QFixed width) |
2184 { |
2182 { |
2185 LDEBUG << "layoutFlow from=" << layoutFrom << "to=" << layoutTo; |
2183 LDEBUG << "layoutFlow from=" << layoutFrom << "to=" << layoutTo; |
2186 QTextFrameData *fd = data(layoutStruct->frame); |
2184 QTextFrameData *fd = data(layoutStruct->frame); |
2187 |
2185 |
2507 |
2505 |
2508 fd->currentLayoutStruct = 0; |
2506 fd->currentLayoutStruct = 0; |
2509 } |
2507 } |
2510 |
2508 |
2511 void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosition, const QTextBlockFormat &blockFormat, |
2509 void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosition, const QTextBlockFormat &blockFormat, |
2512 QLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, const QTextBlockFormat *previousBlockFormat) |
2510 QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, const QTextBlockFormat *previousBlockFormat) |
2513 { |
2511 { |
2514 Q_Q(QTextDocumentLayout); |
2512 Q_Q(QTextDocumentLayout); |
2515 |
2513 |
2516 QTextLayout *tl = bl.layout(); |
2514 QTextLayout *tl = bl.layout(); |
2517 const int blockLength = bl.length(); |
2515 const int blockLength = bl.length(); |
2528 layoutStruct->y += QFixed::fromReal(margin); |
2526 layoutStruct->y += QFixed::fromReal(margin); |
2529 } |
2527 } |
2530 |
2528 |
2531 //QTextFrameData *fd = data(layoutStruct->frame); |
2529 //QTextFrameData *fd = data(layoutStruct->frame); |
2532 |
2530 |
2533 Qt::LayoutDirection dir = docPrivate->defaultTextOption.textDirection(); |
2531 Qt::LayoutDirection dir = bl.textDirection(); |
2534 if (blockFormat.hasProperty(QTextFormat::LayoutDirection)) |
|
2535 dir = blockFormat.layoutDirection(); |
|
2536 |
2532 |
2537 QFixed extraMargin; |
2533 QFixed extraMargin; |
2538 if (docPrivate->defaultTextOption.flags() & QTextOption::AddSpaceForLineAndParagraphSeparators) { |
2534 if (docPrivate->defaultTextOption.flags() & QTextOption::AddSpaceForLineAndParagraphSeparators) { |
2539 QFontMetricsF fm(bl.charFormat().font()); |
2535 QFontMetricsF fm(bl.charFormat().font()); |
2540 extraMargin = QFixed::fromReal(fm.width(QChar(QChar(0x21B5)))); |
2536 extraMargin = QFixed::fromReal(fm.width(QChar(QChar(0x21B5)))); |
2716 else |
2712 else |
2717 layoutStruct->maximumWidth = qMax(layoutStruct->maximumWidth, maxW); |
2713 layoutStruct->maximumWidth = qMax(layoutStruct->maximumWidth, maxW); |
2718 } |
2714 } |
2719 } |
2715 } |
2720 |
2716 |
2721 void QTextDocumentLayoutPrivate::floatMargins(const QFixed &y, const QLayoutStruct *layoutStruct, |
2717 void QTextDocumentLayoutPrivate::floatMargins(const QFixed &y, const QTextLayoutStruct *layoutStruct, |
2722 QFixed *left, QFixed *right) const |
2718 QFixed *left, QFixed *right) const |
2723 { |
2719 { |
2724 // qDebug() << "floatMargins y=" << y; |
2720 // qDebug() << "floatMargins y=" << y; |
2725 *left = layoutStruct->x_left; |
2721 *left = layoutStruct->x_left; |
2726 *right = layoutStruct->x_right; |
2722 *right = layoutStruct->x_right; |
2738 } |
2734 } |
2739 } |
2735 } |
2740 // qDebug() << "floatMargins: left="<<*left<<"right="<<*right<<"y="<<y; |
2736 // qDebug() << "floatMargins: left="<<*left<<"right="<<*right<<"y="<<y; |
2741 } |
2737 } |
2742 |
2738 |
2743 QFixed QTextDocumentLayoutPrivate::findY(QFixed yFrom, const QLayoutStruct *layoutStruct, QFixed requiredWidth) const |
2739 QFixed QTextDocumentLayoutPrivate::findY(QFixed yFrom, const QTextLayoutStruct *layoutStruct, QFixed requiredWidth) const |
2744 { |
2740 { |
2745 QFixed right, left; |
2741 QFixed right, left; |
2746 requiredWidth = qMin(requiredWidth, layoutStruct->x_right - layoutStruct->x_left); |
2742 requiredWidth = qMin(requiredWidth, layoutStruct->x_right - layoutStruct->x_left); |
2747 |
2743 |
2748 // qDebug() << "findY:" << yFrom; |
2744 // qDebug() << "findY:" << yFrom; |