src/gui/text/qtextlayout.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
   858         const QScriptLine &si = d->lines[i];
   858         const QScriptLine &si = d->lines[i];
   859         xmin = qMin(xmin, si.x);
   859         xmin = qMin(xmin, si.x);
   860         ymin = qMin(ymin, si.y);
   860         ymin = qMin(ymin, si.y);
   861         xmax = qMax(xmax, si.x+qMax(si.width, si.textWidth));
   861         xmax = qMax(xmax, si.x+qMax(si.width, si.textWidth));
   862         // ### shouldn't the ascent be used in ymin???
   862         // ### shouldn't the ascent be used in ymin???
   863         ymax = qMax(ymax, si.y+si.ascent+si.descent+1);
   863         ymax = qMax(ymax, si.y+si.height());
   864     }
   864     }
   865     return QRectF(xmin.toReal(), ymin.toReal(), (xmax-xmin).toReal(), (ymax-ymin).toReal());
   865     return QRectF(xmin.toReal(), ymin.toReal(), (xmax-xmin).toReal(), (ymax-ymin).toReal());
   866 }
   866 }
   867 
   867 
   868 /*!
   868 /*!
  1069 {
  1069 {
  1070     const QScriptLine &line = eng->lines[lineNumber];
  1070     const QScriptLine &line = eng->lines[lineNumber];
  1071 
  1071 
  1072     QTextLineItemIterator iterator(eng, lineNumber, pos, selection);
  1072     QTextLineItemIterator iterator(eng, lineNumber, pos, selection);
  1073 
  1073 
  1074     const QFixed y = QFixed::fromReal(pos.y()) + line.y + line.ascent;
  1074 
  1075 
  1075 
       
  1076     const qreal selectionY = pos.y() + line.y.toReal();
  1076     const qreal lineHeight = line.height().toReal();
  1077     const qreal lineHeight = line.height().toReal();
  1077     const qreal selectionY = (y - line.ascent).toReal();
       
  1078 
  1078 
  1079     QFixed lastSelectionX = iterator.x;
  1079     QFixed lastSelectionX = iterator.x;
  1080     QFixed lastSelectionWidth;
  1080     QFixed lastSelectionWidth;
  1081 
  1081 
  1082     while (!iterator.atEnd()) {
  1082     while (!iterator.atEnd()) {
  1332     const QScriptLine &sl = d->lines[line];
  1332     const QScriptLine &sl = d->lines[line];
  1333 
  1333 
  1334     const qreal x = position.x() + l.cursorToX(cursorPosition);
  1334     const qreal x = position.x() + l.cursorToX(cursorPosition);
  1335 
  1335 
  1336     int itm = d->findItem(cursorPosition - 1);
  1336     int itm = d->findItem(cursorPosition - 1);
  1337     QFixed ascent = sl.ascent;
  1337     QFixed base = sl.base();
  1338     QFixed descent = sl.descent;
  1338     QFixed descent = sl.descent;
  1339     bool rightToLeft = (d->option.textDirection() == Qt::RightToLeft);
  1339     bool rightToLeft = (d->option.textDirection() == Qt::RightToLeft);
  1340     if (itm >= 0) {
  1340     if (itm >= 0) {
  1341         const QScriptItem &si = d->layoutData->items.at(itm);
  1341         const QScriptItem &si = d->layoutData->items.at(itm);
  1342         if (si.ascent > 0)
  1342         if (si.ascent > 0)
  1343             ascent = si.ascent;
  1343             base = si.ascent;
  1344         if (si.descent > 0)
  1344         if (si.descent > 0)
  1345             descent = si.descent;
  1345             descent = si.descent;
  1346         rightToLeft = si.analysis.bidiLevel % 2;
  1346         rightToLeft = si.analysis.bidiLevel % 2;
  1347     }
  1347     }
  1348     qreal y = position.y() + (sl.y + sl.ascent - ascent).toReal();
  1348     qreal y = position.y() + (sl.y + sl.base() - base).toReal();
  1349     bool toggleAntialiasing = !(p->renderHints() & QPainter::Antialiasing)
  1349     bool toggleAntialiasing = !(p->renderHints() & QPainter::Antialiasing)
  1350                               && (p->transform().type() > QTransform::TxTranslate);
  1350                               && (p->transform().type() > QTransform::TxTranslate);
  1351     if (toggleAntialiasing)
  1351     if (toggleAntialiasing)
  1352         p->setRenderHint(QPainter::Antialiasing);
  1352         p->setRenderHint(QPainter::Antialiasing);
  1353     p->fillRect(QRectF(x, y, qreal(width), (ascent + descent).toReal()), p->pen().brush());
  1353     p->fillRect(QRectF(x, y, qreal(width), (base + descent + 1).toReal()), p->pen().brush());
  1354     if (toggleAntialiasing)
  1354     if (toggleAntialiasing)
  1355         p->setRenderHint(QPainter::Antialiasing, false);
  1355         p->setRenderHint(QPainter::Antialiasing, false);
  1356     if (d->layoutData->hasBidi) {
  1356     if (d->layoutData->hasBidi) {
  1357         const int arrow_extent = 4;
  1357         const int arrow_extent = 4;
  1358         int sign = rightToLeft ? -1 : 1;
  1358         int sign = rightToLeft ? -1 : 1;
  1498 {
  1498 {
  1499     return eng->lines[i].descent.toReal();
  1499     return eng->lines[i].descent.toReal();
  1500 }
  1500 }
  1501 
  1501 
  1502 /*!
  1502 /*!
  1503     Returns the line's height. This is equal to ascent() + descent() + 1.
  1503     Returns the line's height. This is equal to ascent() + descent() + 1
  1504 
  1504     if leading is not included. If leading is included, this equals to
  1505     \sa ascent() descent()
  1505     ascent() + descent() + leading() + 1.
       
  1506 
       
  1507     \sa ascent() descent() leading() setLeadingIncluded()
  1506 */
  1508 */
  1507 qreal QTextLine::height() const
  1509 qreal QTextLine::height() const
  1508 {
  1510 {
  1509     return eng->lines[i].height().toReal();
  1511     return eng->lines[i].height().toReal();
  1510 }
  1512 }
       
  1513 
       
  1514 /*!
       
  1515     \since 4.6
       
  1516 
       
  1517     Returns the line's leading.
       
  1518 
       
  1519     \sa ascent() descent() height()
       
  1520 */
       
  1521 qreal QTextLine::leading() const
       
  1522 {
       
  1523     return eng->lines[i].leading.toReal();
       
  1524 }
       
  1525 
       
  1526 /*! \since 4.6
       
  1527 
       
  1528   Includes positive leading into the line's height if \a included is true;
       
  1529   otherwise does not include leading.
       
  1530 
       
  1531   By default, leading is not included.
       
  1532 
       
  1533   Note that negative leading is ignored, it must be handled
       
  1534   in the code using the text lines by letting the lines overlap.
       
  1535 
       
  1536   \sa leadingIncluded()
       
  1537 
       
  1538 */
       
  1539 void QTextLine::setLeadingIncluded(bool included)
       
  1540 {
       
  1541     eng->lines[i].leadingIncluded= included;
       
  1542 
       
  1543 }
       
  1544 
       
  1545 /*! \since 4.6
       
  1546 
       
  1547   Returns true if positive leading is included into the line's height; otherwise returns false.
       
  1548 
       
  1549   By default, leading is not included.
       
  1550 
       
  1551   \sa setLeadingIncluded()
       
  1552 */
       
  1553 bool QTextLine::leadingIncluded() const
       
  1554 {
       
  1555     return eng->lines[i].leadingIncluded;
       
  1556 }
       
  1557 
  1511 
  1558 
  1512 /*!
  1559 /*!
  1513     Returns the width of the line that is occupied by text. This is
  1560     Returns the width of the line that is occupied by text. This is
  1514     always \<= to width(), and is the minimum width that could be used
  1561     always \<= to width(), and is the minimum width that could be used
  1515     by layout() without changing the line break position.
  1562     by layout() without changing the line break position.
  1710             end = current.position + eng->length(item);
  1757             end = current.position + eng->length(item);
  1711             glyphs = eng->shapedGlyphs(&current);
  1758             glyphs = eng->shapedGlyphs(&current);
  1712         }
  1759         }
  1713         const QScriptItem &current = eng->layoutData->items[item];
  1760         const QScriptItem &current = eng->layoutData->items[item];
  1714 
  1761 
       
  1762         lbh.tmpData.leading = qMax(lbh.tmpData.leading + lbh.tmpData.ascent,
       
  1763                                    current.leading + current.ascent) - qMax(lbh.tmpData.ascent,
       
  1764                                                                             current.ascent);
  1715         lbh.tmpData.ascent = qMax(lbh.tmpData.ascent, current.ascent);
  1765         lbh.tmpData.ascent = qMax(lbh.tmpData.ascent, current.ascent);
  1716         lbh.tmpData.descent = qMax(lbh.tmpData.descent, current.descent);
  1766         lbh.tmpData.descent = qMax(lbh.tmpData.descent, current.descent);
  1717 
  1767 
  1718         if (current.analysis.flags == QScriptAnalysis::Tab && (alignment & (Qt::AlignLeft | Qt::AlignRight | Qt::AlignCenter | Qt::AlignJustify))) {
  1768         if (current.analysis.flags == QScriptAnalysis::Tab && (alignment & (Qt::AlignLeft | Qt::AlignRight | Qt::AlignCenter | Qt::AlignJustify))) {
  1719             if (lbh.checkFullOtherwiseExtend(line))
  1769             if (lbh.checkFullOtherwiseExtend(line))
  2040         return;
  2090         return;
  2041     }
  2091     }
  2042 
  2092 
  2043 
  2093 
  2044     QTextLineItemIterator iterator(eng, i, pos, selection);
  2094     QTextLineItemIterator iterator(eng, i, pos, selection);
  2045     const QFixed y = QFixed::fromReal(pos.y()) + line.y + line.ascent;
  2095     QFixed lineBase = line.base();
       
  2096 
       
  2097     const QFixed y = QFixed::fromReal(pos.y()) + line.y + lineBase;
  2046 
  2098 
  2047     bool suppressColors = (eng->option.flags() & QTextOption::SuppressColors);
  2099     bool suppressColors = (eng->option.flags() & QTextOption::SuppressColors);
  2048     while (!iterator.atEnd()) {
  2100     while (!iterator.atEnd()) {
  2049         QScriptItem &si = iterator.next();
  2101         QScriptItem &si = iterator.next();
  2050 
  2102 
  2063             if (!suppressColors)
  2115             if (!suppressColors)
  2064                 format = eng->format(&si);
  2116                 format = eng->format(&si);
  2065             if (selection)
  2117             if (selection)
  2066                 format.merge(selection->format);
  2118                 format.merge(selection->format);
  2067 
  2119 
  2068             setPenAndDrawBackground(p, pen, format, QRectF(iterator.x.toReal(), (y - line.ascent).toReal(),
  2120             setPenAndDrawBackground(p, pen, format, QRectF(iterator.x.toReal(), (y - lineBase).toReal(),
  2069                                                            iterator.itemWidth.toReal(), line.height().toReal()));
  2121                                                            iterator.itemWidth.toReal(), line.height().toReal()));
  2070 
  2122 
  2071             QTextCharFormat::VerticalAlignment valign = format.verticalAlignment();
  2123             QTextCharFormat::VerticalAlignment valign = format.verticalAlignment();
  2072             if (valign == QTextCharFormat::AlignSuperScript || valign == QTextCharFormat::AlignSubScript) {
  2124             if (valign == QTextCharFormat::AlignSuperScript || valign == QTextCharFormat::AlignSubScript) {
  2073                 QFontEngine *fe = f.d->engineForScript(si.analysis.script);
  2125                 QFontEngine *fe = f.d->engineForScript(si.analysis.script);
  2084             if (eng->hasFormats()) {
  2136             if (eng->hasFormats()) {
  2085                 p->save();
  2137                 p->save();
  2086                 if (si.analysis.flags == QScriptAnalysis::Object && eng->block.docHandle()) {
  2138                 if (si.analysis.flags == QScriptAnalysis::Object && eng->block.docHandle()) {
  2087                     QFixed itemY = y - si.ascent;
  2139                     QFixed itemY = y - si.ascent;
  2088                     if (format.verticalAlignment() == QTextCharFormat::AlignTop) {
  2140                     if (format.verticalAlignment() == QTextCharFormat::AlignTop) {
  2089                         itemY = y - line.ascent;
  2141                         itemY = y - lineBase;
  2090                     }
  2142                     }
  2091 
  2143 
  2092                     QRectF itemRect(iterator.x.toReal(), itemY.toReal(), iterator.itemWidth.toReal(), si.height().toReal());
  2144                     QRectF itemRect(iterator.x.toReal(), itemY.toReal(), iterator.itemWidth.toReal(), si.height().toReal());
  2093 
  2145 
  2094                     eng->docLayout()->drawInlineObject(p, itemRect,
  2146                     eng->docLayout()->drawInlineObject(p, itemRect,