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(¤t); |
1758 glyphs = eng->shapedGlyphs(¤t); |
1712 } |
1759 } |
1713 const QScriptItem ¤t = eng->layoutData->items[item]; |
1760 const QScriptItem ¤t = 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, |