26#include <private/qpainter_p.h>
30#define ObjectSelectionBrush (QTextFormat::ForegroundBrush + 1)
31#define SuppressText 0x5012
32#define SuppressBackground 0x513
597 qWarning(
"QTextLayout::beginLayout: Called while already doing layout");
616 qWarning(
"QTextLayout::endLayout: Called without beginLayout()");
655 Q_ASSERT(len <= d->layoutData->string.size());
656 if (!attributes || oldPos < 0 || oldPos >=
len)
661 while (oldPos <
len && !attributes[oldPos].graphemeBoundary)
664 if (oldPos < len && d->atWordSeparator(oldPos)) {
666 while (oldPos < len && d->atWordSeparator(oldPos))
672 while (oldPos <
len && attributes[oldPos].whiteSpace)
691 Q_ASSERT(len <= d->layoutData->string.size());
692 if (!attributes || oldPos <= 0 || oldPos >
len)
697 while (oldPos && !attributes[oldPos].graphemeBoundary)
700 while (oldPos > 0 && attributes[oldPos - 1].whiteSpace)
708 while (oldPos > 0 && !attributes[oldPos - 1].whiteSpace && !d->
atWordSeparator(oldPos-1))
787 qWarning(
"QTextLayout::createLine: Called without layouting");
798 qWarning(
"QTextLayout: text too long, truncated.");
804 if (l && from >= strlen) {
812 line.justified =
false;
813 line.gridfitted =
false;
887 xmin =
qMin(xmin, si.
x);
888 ymin =
qMin(ymin, si.
y);
890 xmax =
qMax(xmax, si.
x+lineWidth);
894 return QRectF(xmin.
toReal(), ymin.
toReal(), (xmax-xmin).toReal(), (ymax-ymin).toReal());
952 const qreal lineHeight =
line.height().toReal();
954 QFixed lastSelectionX = iterator.x;
955 QFixed lastSelectionWidth;
957 while (!iterator.atEnd()) {
960 QFixed selectionX, selectionWidth;
961 if (iterator.getSelectionBounds(&selectionX, &selectionWidth)) {
962 if (selectionX == lastSelectionX + lastSelectionWidth) {
963 lastSelectionWidth += selectionWidth;
967 if (lastSelectionWidth > 0) {
972 lastSelectionX = selectionX;
973 lastSelectionWidth = selectionWidth;
976 if (lastSelectionWidth > 0) {
988#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
1008# if !defined(QT_NO_RAWFONT)
1032#if !defined(QT_NO_RAWFONT)
1035 QTextLayout::GlyphRunRetrievalFlags retrievalFlags)
const
1055 QGlyphRun::GlyphRunFlags
flags = glyphRun.
flags();
1060 oldGlyphRun = glyphRun;
1081 return glyphRunHash.
values();
1100 QFixed clipy = (INT_MIN/256);
1101 QFixed clipe = (INT_MAX/256);
1117 if ((sl.
y + sl.
height()) < clipy) {
1125 for (
int i = 0;
i < selections.
size(); ++
i) {
1140 int sl_length = sl.
length + (isLastLineInBlock? 1 : 0);
1146 const bool selectionStartInLine = sl.
from <=
selection.start;
1149 if (sl.
length && (selectionStartInLine || selectionEndInLine)) {
1163 if (!selectionEndInLine) {
1167 if (!selectionStartInLine) {
1171 }
else if (!selectionEndInLine
1172 && isLastLineInBlock
1180 const QPen oldPen =
p->pen();
1181 const QBrush oldBrush =
p->brush();
1185 p->drawPath(region);
1188 p->setBrush(oldBrush);
1196 if (hasBackground) {
1206 if (hasText && !hasBackground && !(textDoneRegion & region).isEmpty())
1219 textDoneRegion += region;
1222 textDoneRegion -= region;
1225 excludedRegion += region;
1228 QPainterPath needsTextButNoBackground = excludedRegion - textDoneRegion;
1229 if (!needsTextButNoBackground.
isEmpty()){
1243 if (!excludedRegion.
isEmpty()) {
1251 path -= excludedRegion;
1255 for (
int i = firstLine;
i < lastLine; ++
i) {
1259 if (!excludedRegion.
isEmpty())
1313 const int realCursorPosition = cursorPosition;
1320 int itm = d->
findItem(cursorPosition);
1327 int neighborItem = itm;
1328 if (neighborItem > 0 && si->
position == realCursorPosition)
1330 else if (neighborItem < d->layoutData->items.size() - 1 && si->
position + si->
num_glyphs == realCursorPosition)
1332 const bool onBoundary = neighborItem != itm
1351 if (toggleAntialiasing)
1362 const QPen origPen =
p->pen();
1370 p->setCompositionMode(origCompositionMode);
1371 if (toggleAntialiasing)
1374 const int arrow_extent = 4;
1375 int sign = rightToLeft ? -1 : 1;
1376 p->drawLine(
QLineF(
x,
y,
x + (
sign * arrow_extent/2),
y + arrow_extent/2));
1377 p->drawLine(
QLineF(
x,
y+arrow_extent,
x + (
sign * arrow_extent/2),
y + arrow_extent/2));
1615 qWarning(
"QTextLine: Can't set a line width while not layouting.");
1629 layout_helper(INT_MAX);
1645 layout_helper(numColumns);
1662 layout_helper(numColumns);
1666#define LB_DEBUG qDebug
1668#define LB_DEBUG if (0) qDebug
1673 struct LineBreakHelper
1676 : glyphCount(0), maxGlyphs(0), currentPosition(0), fontEngine(
nullptr), logClusters(
nullptr),
1677 manualWrap(
false), whiteSpaceOrObject(
true)
1689 int currentPosition;
1694 QFixed currentSoftHyphenWidth;
1695 QFixed commitedSoftHyphenWidth;
1697 QFixed minimumRightBearing;
1700 const unsigned short *logClusters;
1703 bool whiteSpaceOrObject;
1709 + (
line.textWidth > 0 ? currentSoftHyphenWidth :
QFixed()) + negativeRightBearing();
1712 inline glyph_t currentGlyph()
const
1717 return glyphs.
glyphs[logClusters[currentPosition - 1]];
1720 inline void saveCurrentGlyph()
1723 if (currentPosition > 0 &&
1724 logClusters[currentPosition - 1] < glyphs.
numGlyphs) {
1725 previousGlyph = currentGlyph();
1726 previousGlyphFontEngine = fontEngine;
1734 engine->getGlyphBearings(glyph,
nullptr, &rb);
1743 inline void calculateRightBearing()
1745 if (currentPosition <= 0)
1747 calculateRightBearing(fontEngine, currentGlyph());
1750 inline void calculateRightBearingForPreviousGlyph()
1752 if (previousGlyph > 0)
1753 calculateRightBearing(previousGlyphFontEngine, previousGlyph);
1756 static const QFixed RightBearingNotCalculated;
1758 inline void resetRightBearing()
1760 rightBearing = RightBearingNotCalculated;
1765 inline QFixed negativeRightBearing()
const
1767 if (rightBearing == RightBearingNotCalculated)
1770 return qAbs(rightBearing);
1774Q_CONSTINIT
const QFixed LineBreakHelper::RightBearingNotCalculated =
QFixed(1);
1776inline bool LineBreakHelper::checkFullOtherwiseExtend(
QScriptLine &
line)
1778 LB_DEBUG(
"possible break width %f, spacew=%f", tmpData.textWidth.toReal(), spaceData.textWidth.toReal());
1781 if (
line.
length && !manualWrap && (newWidth >
line.width || glyphCount > maxGlyphs))
1786 line.textWidth += spaceData.textWidth;
1789 tmpData.textWidth = 0;
1791 spaceData.textWidth = 0;
1792 spaceData.length = 0;
1794 if (oldTextWidth !=
line.textWidth || currentSoftHyphenWidth > 0) {
1795 commitedSoftHyphenWidth = currentSoftHyphenWidth;
1796 currentSoftHyphenWidth = 0;
1806 const QScriptItem ¤t,
const unsigned short *logClusters,
1809 int glyphPosition = logClusters[
pos];
1813 }
while (
pos <
end && logClusters[
pos] == glyphPosition);
1824 *clusterWidth += (
line.textWidth - clusterWid);
1830void QTextLine::layout_helper(
int maxGlyphs)
1834 line.trailingSpaces = 0;
1836 line.hasTrailingSpaces =
false;
1839 line.setDefaultHeight(eng);
1845 LineBreakHelper lbh;
1847 lbh.maxGlyphs = maxGlyphs;
1865 lbh.currentPosition =
line.from;
1868 lbh.previousGlyph = 0;
1870 bool manuallyWrapped =
false;
1871 bool hasInlineObject =
false;
1872 QFixed maxInlineObjectHeight = 0;
1874 while (newItem < eng->layoutData->items.size()) {
1875 lbh.resetRightBearing();
1876 if (newItem !=
item) {
1890 if (lbh.fontEngine != fontEngine) {
1891 lbh.fontEngine = fontEngine;
1898 lbh.tmpData.leading =
qMax(lbh.tmpData.leading + lbh.tmpData.ascent,
1903 lbh.tmpData.ascent =
qMax(lbh.tmpData.ascent, current.
ascent);
1904 lbh.tmpData.descent =
qMax(lbh.tmpData.descent, current.
descent);
1908 lbh.whiteSpaceOrObject =
true;
1909 if (lbh.checkFullOtherwiseExtend(
line))
1912 QFixed x =
line.x +
line.textWidth + lbh.tmpData.textWidth + lbh.spaceData.textWidth;
1920 lbh.spaceData.textWidth += tabWidth;
1921 lbh.spaceData.length++;
1925 lbh.glyphCount +=
qRound(tabWidth / averageCharWidth);
1927 if (lbh.checkFullOtherwiseExtend(
line))
1930 lbh.whiteSpaceOrObject =
true;
1934 line.setDefaultHeight(eng);
1936 if (lbh.checkFullOtherwiseExtend(
line))
1940 current, lbh.logClusters, lbh.glyphs);
1942 lbh.tmpData.length++;
1943 lbh.calculateRightBearingForPreviousGlyph();
1945 line += lbh.tmpData;
1946 manuallyWrapped =
true;
1949 lbh.whiteSpaceOrObject =
true;
1950 lbh.tmpData.length++;
1958 lbh.tmpData.ascent =
qMax(lbh.tmpData.ascent, current.
ascent);
1959 lbh.tmpData.descent =
qMax(lbh.tmpData.descent, current.
descent);
1963 hasInlineObject =
true;
1964 maxInlineObjectHeight =
qMax(maxInlineObjectHeight, current.
ascent + current.
descent);
1966 lbh.tmpData.textWidth += current.
width;
1970 if (lbh.checkFullOtherwiseExtend(
line))
1972 }
else if (attributes[lbh.currentPosition].whiteSpace
1974 lbh.whiteSpaceOrObject =
true;
1975 while (lbh.currentPosition <
end
1976 && attributes[lbh.currentPosition].whiteSpace
1979 current, lbh.logClusters, lbh.glyphs);
1982 if (!lbh.manualWrap && lbh.spaceData.textWidth >
line.width)
1985 lbh.whiteSpaceOrObject =
false;
1986 bool sb_or_ws =
false;
1987 lbh.saveCurrentGlyph();
1988 QFixed accumulatedTextWidth;
1991 current, lbh.logClusters, lbh.glyphs, &accumulatedTextWidth);
1999 && attributes[lbh.currentPosition].
whiteSpace
2004 || attributes[lbh.currentPosition].lineBreak
2008 }
else if (attributes[lbh.currentPosition].graphemeBoundary) {
2009 if (breakWordOrAny) {
2010 lbh.minw =
qMax(accumulatedTextWidth, lbh.minw);
2011 accumulatedTextWidth = 0;
2016 }
while (lbh.currentPosition <
end);
2017 lbh.minw =
qMax(accumulatedTextWidth, lbh.minw);
2019 if (lbh.currentPosition > 0 && lbh.currentPosition <=
end
2020 && (lbh.currentPosition ==
end || attributes[lbh.currentPosition].lineBreak)
2038 lbh.currentSoftHyphenWidth = lbh.glyphs.advances[lbh.logClusters[lbh.currentPosition - 1]];
2041 if (sb_or_ws|breakany) {
2049 QFixed previousRightBearing = lbh.rightBearing;
2060 if ((lbh.calculateNewWidth(
line) +
qAbs(lbh.minimumRightBearing)) >
line.width)
2061 lbh.calculateRightBearing();
2063 if (lbh.checkFullOtherwiseExtend(
line)) {
2068 if (previousRightBearing != LineBreakHelper::RightBearingNotCalculated)
2069 lbh.rightBearing = previousRightBearing;
2071 lbh.calculateRightBearingForPreviousGlyph();
2073 line.textWidth += lbh.commitedSoftHyphenWidth;
2078 lbh.saveCurrentGlyph();
2080 if (lbh.currentPosition ==
end)
2084 lbh.checkFullOtherwiseExtend(
line);
2085 line.textWidth += lbh.commitedSoftHyphenWidth;
2090 if (lbh.rightBearing == LineBreakHelper::RightBearingNotCalculated && !lbh.whiteSpaceOrObject)
2091 lbh.calculateRightBearing();
2094 line.textWidth += lbh.negativeRightBearing();
2097 LB_DEBUG(
"no break available in line, adding temp: length %d, width %f, space: length %d, width %f",
2098 lbh.tmpData.length, lbh.tmpData.textWidth.toReal(),
2099 lbh.spaceData.length, lbh.spaceData.textWidth.toReal());
2100 line += lbh.tmpData;
2105 if (maxInlineObjectHeight >
line.ascent +
line.descent) {
2107 QFixed toAdd = (maxInlineObjectHeight -
line.ascent -
line.descent)/2;
2108 line.ascent += toAdd;
2109 line.descent = maxInlineObjectHeight -
line.ascent;
2144 LB_DEBUG(
"line length = %d, ascent=%f, descent=%f, textWidth=%f (spacew=%f)",
line.
length,
line.ascent.toReal(),
2145 line.descent.toReal(),
line.textWidth.toReal(), lbh.spaceData.width.toReal());
2149 ? lbh.spaceData.textWidth
2152 if ((lbh.maxGlyphs != INT_MAX && lbh.glyphCount > lbh.maxGlyphs)
2153 || (lbh.maxGlyphs == INT_MAX &&
line.textWidth > (
line.width - trailingSpace))) {
2156 layout_helper(lbh.maxGlyphs);
2162 if (lbh.manualWrap) {
2169 if (!manuallyWrapped) {
2174 if (manuallyWrapped)
2178 line.textWidth += trailingSpace;
2179 if (lbh.spaceData.length) {
2180 line.trailingSpaces = lbh.spaceData.length;
2181 line.hasTrailingSpaces =
true;
2184 line.justified =
false;
2185 line.gridfitted =
false;
2239 p->setPen(defaultPen);
2244 p->fillRect(
r.toAlignedRect(), bg);
2251#if !defined(QT_NO_RAWFONT)
2256 const QGlyphRun::GlyphRunFlags &
flags,
2257 QTextLayout::GlyphRunRetrievalFlags retrievalFlags,
2262 unsigned short *logClusters,
2272 int rangeStart = textPosition;
2273 int logClusterIndex = 0;
2274 while (logClusters[logClusterIndex] != glyphsStart && rangeStart < textPosition + textLength) {
2279 int rangeEnd = rangeStart;
2280 while (logClusters[logClusterIndex] != glyphsEnd && rangeEnd < textPosition + textLength) {
2285 d->textRangeStart = rangeStart;
2286 d->textRangeEnd = rangeEnd;
2296 QTextItem::RenderFlags renderFlags;
2323 int nextClusterIndex = 0;
2324 int currentClusterIndex = 0;
2325 for (
int i = 0;
i < glyphsArray.
size(); ++
i) {
2326 const int glyphArrayIndex =
i + glyphsStart;
2330 if (nextClusterIndex < textLength && logClusters[nextClusterIndex] == glyphArrayIndex) {
2331 currentClusterIndex = nextClusterIndex;
2332 while (logClusters[nextClusterIndex] == glyphArrayIndex && nextClusterIndex < textLength)
2339 Q_ASSERT(nextClusterIndex == textLength || logClusters[nextClusterIndex] != glyphArrayIndex);
2340 stringIndexes.
append(textPosition + currentClusterIndex);
2344 glyph_t glyphIndex = glyphsArray.
at(
i) & 0xffffff;
2345 glyphs.
append(glyphIndex);
2379# if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
2425 QTextLayout::GlyphRunRetrievalFlags retrievalFlags)
const
2448 while (!iterator.atEnd()) {
2453 if (from >= 0 &&
length >= 0 && (from >= iterator.itemEnd || from +
length <= iterator.itemStart))
2459 QGlyphRun::GlyphRunFlags
flags;
2476 int relativeFrom =
qMax(iterator.itemStart, from) - si.
position;
2479 unsigned short *logClusters = eng->
logClusters(&si);
2480 int glyphsStart = logClusters[relativeFrom];
2481 int glyphsEnd = (relativeTo == iterator.itemLength) ? si.
num_glyphs - 1 : logClusters[relativeTo];
2483 int nextGlyphIndex = (relativeTo < iterator.itemLength - 1) ? logClusters[relativeTo + 1] : si.
num_glyphs;
2484 if (nextGlyphIndex - 1 > glyphsEnd)
2485 glyphsEnd = nextGlyphIndex - 1;
2486 bool startsInsideLigature = relativeFrom > 0 && logClusters[relativeFrom - 1] == glyphsStart;
2487 bool endsInsideLigature = nextGlyphIndex == glyphsEnd;
2489 int itemGlyphsStart = logClusters[iterator.itemStart - si.
position];
2490 int itemGlyphsEnd = logClusters[iterator.itemEnd - 1 - si.
position];
2497 if (relativeFrom != (iterator.itemStart - si.
position) && !rtl) {
2498 for (
int i = itemGlyphsStart;
i < glyphsStart; ++
i) {
2501 pos.rx() += (glyphLayout.
advances[
i] + justification).toReal();
2504 }
else if (relativeTo != (iterator.itemEnd - si.
position - 1) && rtl) {
2505 for (
int i = itemGlyphsEnd;
i > glyphsEnd; --
i) {
2508 pos.rx() += (glyphLayout.
advances[
i] + justification).toReal();
2513 glyphLayout = glyphLayout.
mid(glyphsStart, glyphsEnd - glyphsStart + 1);
2517 iterator.getSelectionBounds(&
x, &
width);
2521#ifndef QT_NO_RAWFONT
2542 QGlyphRun::GlyphRunFlags subFlags =
flags;
2543 if (
start == 0 && startsInsideLigature)
2555 glyphsStart +
start,
2557 logClusters + relativeFrom,
2559 relativeTo - relativeFrom + 1);
2566 pos.rx() += (subLayout.
advances[
i] + justification).toReal();
2580 QGlyphRun::GlyphRunFlags subFlags =
flags;
2581 if ((
start == 0 && startsInsideLigature) || endsInsideLigature)
2592 glyphsStart +
start,
2594 logClusters + relativeFrom,
2596 relativeTo - relativeFrom + 1);
2600 if (startsInsideLigature || endsInsideLigature)
2612 logClusters + relativeFrom,
2614 relativeTo - relativeFrom + 1);
2638#ifndef QT_NO_RAWFONT
2643 QPen pen =
p->pen();
2652 const qreal lineHeight =
line.height().toReal();
2662 const bool xlateToFixedRange = !maxFixedRect.contains(origPos);
2667 p->translate(origPos);
2692 if (formatCollection !=
nullptr)
2698 if (suppressColors) {
2699 format.clearForeground();
2700 format.clearBackground();
2732 switch (
format.verticalAlignment()) {
2734 itemY =
y - lineBase;
2737 itemY =
y - lineBase + (
line.height() - si.
height()) / 2;
2740 itemY =
y - lineBase +
line.height() - si.
height();
2757 p->fillRect(itemRect,
c);
2779 y.toReal()), visualTab);
2789 unsigned short *logClusters = eng->
logClusters(&si);
2797 gf.justified =
line.justified;
2798 gf.initWithScriptItem(si);
2807 if (gf.glyphs.numGlyphs)
2808 gf.fontEngine->addOutlineToPath(
pos.x(),
pos.y(), gf.glyphs, &
path, gf.flags);
2814 path.addRect(
pos.x(),
pos.y() + offs, gf.width.toReal(), lw);
2818 path.addRect(
pos.x(),
pos.y() - offs, gf.width.toReal(), lw);
2822 path.addRect(
pos.x(),
pos.y() - offs, gf.width.toReal(), lw);
2833 p->setBrush(
p->pen().brush());
2835 p->setPen(
format.textOutline());
2840 gf.glyphs.numGlyphs = 0;
2849 p->setPen(
c.color());
2851 QFont oldFont =
p->font();
2852 p->setFont(eng->
font(si));
2855 p->setFont(oldFont);
2860 if (xlateToFixedRange)
2861 p->translate(-origPos);
2893 *cursorPos =
line.from;
2901 *cursorPos =
line.from;
2904 while (
pos < lineEnd && !attributes[
pos].graphemeBoundary)
2909 *cursorPos =
line.from;
2921 int neighborItem = itm;
2922 if (neighborItem > 0 && scriptItem->
position ==
pos)
2924 else if (neighborItem < eng->layoutData->items.size() - 1 && scriptItem->
position + scriptItem->
num_glyphs ==
pos)
2938 const int l = eng->
length(itm);
2942 unsigned short *logClusters = eng->
logClusters(scriptItem);
2946 if (edge ==
Trailing && glyph_pos < scriptItem->num_glyphs) {
2959 int lastItem = eng->
findItem(lineEnd - 1, itm);
2960 int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0;
2964 for (
int i = 0;
i < nItems; ++
i)
2968 for (
int i = 0;
i < nItems; ++
i) {
2969 int item = visualOrder[
i]+firstItem;
3001 if (
pos == (reverse ? 0 : l))
3009 int glyph_start = glyph_pos;
3010 if (visual && !rtl && !(lastLine && itm == (visualOrder[nItems - 1] + firstItem)))
3012 for (
int i = glyph_end - 1;
i >= glyph_start;
i--)
3017 int glyph_start = logClusters[
start];
3018 int glyph_end = glyph_pos;
3019 if (!visual || !rtl || (lastLine && itm == visualOrder[0] + firstItem))
3021 for (
int i = glyph_start;
i <= glyph_end;
i++)
3050 int lineNum =
index;
3061 int lastItem = eng->
findItem(
line.from + line_length - 1, firstItem);
3062 int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0;
3073 for (
int i = 0;
i < nItems; ++
i)
3081 return line.from + line_length;
3083 }
else if (
x <
line.textWidth || (
line.justified &&
x <
line.width)) {
3089 const auto insertionPoints = (visual && rtl) ? eng->
insertionPointsForLine(lineNum) : std::vector<int>();
3091 for (
int i = 0;
i < nItems; ++
i) {
3092 int item = visualOrder[
i]+firstItem;
3100 unsigned short *logClusters = eng->
logClusters(&si);
3102 int gs = logClusters[
start];
3108 item_width = si.
width;
3118 if (
pos + item_width <
x) {
3127 bool left_half = (
x -
pos) < item_width/2;
3167 if (!visual || rtl || (lastLine &&
i == nItems - 1)) {
3190 if (!visual || !rtl || (lastLine &&
i == 0)) {
3216 if (!rtl &&
i < nItems - 1) {
3220 if (rtl && nchars > 0)
3221 return insertionPoints[size_t(lastLine ? nchars : nchars - 1)];
3241 if (index < eng->lines.size() - 1)
virtual void drawInlineObject(QPainter *painter, const QRectF &rect, QTextInlineObject object, int posInDocument, const QTextFormat &format)
This function is called to draw the inline object, object, with the given painter within the rectangl...
virtual void positionInlineObject(QTextInlineObject item, int posInDocument, const QTextFormat &format)
Lays out the inline object item using the given text format.
const QColor & color() const
Returns the brush color.
Qt::BrushStyle style() const
Returns the brush style.
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
Decomposition decompositionTag() const noexcept
Returns the tag defining the composition of the character.
The QColor class provides colors based on RGB, HSV or CMYK values.
void setAlpha(int alpha)
Sets the alpha of this color to alpha.
void ensureEngineAt(int at)
QFontEngine * engine(int at) const
virtual QFixed descent() const
virtual qreal minRightBearing() const
virtual QFixed ascent() const
virtual QFixed averageCharWidth() const
void getGlyphPositions(const QGlyphLayout &glyphs, const QTransform &matrix, QTextItem::RenderFlags flags, QVarLengthArray< glyph_t > &glyphs_out, QVarLengthArray< QFixedPoint > &positions)
virtual QFixed lineThickness() const
virtual QFixed underlinePosition() const
\reentrant \inmodule QtGui
int horizontalAdvance(const QString &, int len=-1) const
Returns the horizontal advance in pixels of the first len characters of text.
QFontEngine * engineForScript(int script) const
bool strikeOut() const
Returns true if strikeout has been set; otherwise returns false.
bool underline() const
Returns true if underline has been set; otherwise returns false.
bool overline() const
Returns true if overline has been set; otherwise returns false.
static QGlyphRunPrivate * get(const QGlyphRun &glyphRun)
The QGlyphRun class provides direct access to the internal glyphs in a font.
QList< qsizetype > stringIndexes() const
void setSourceString(const QString &sourceString)
void setStringIndexes(const QList< qsizetype > &stringIndexes)
void setPositions(const QList< QPointF > &positions)
Sets the positions of the edge of the baseline for each glyph in this set of glyph indexes to positio...
void setRawFont(const QRawFont &rawFont)
Sets the font in which to look up the glyph indexes to the rawFont specified.
QList< quint32 > glyphIndexes() const
Returns the glyph indexes for this QGlyphRun object.
void setBoundingRect(const QRectF &boundingRect)
Sets the bounding rect of the glyphs in this QGlyphRun to be boundingRect.
QRawFont rawFont() const
Returns the font selected for this QGlyphRun object.
GlyphRunFlags flags() const
Returns the flags set for this QGlyphRun.
void setFlags(GlyphRunFlags flags)
Sets the flags of this QGlyphRun to flags.
void setGlyphIndexes(const QList< quint32 > &glyphIndexes)
Set the glyph indexes for this QGlyphRun object to glyphIndexes.
bool isEmpty() const
Returns true if the QGlyphRun does not contain any glyphs.
QRectF boundingRect() const
Returns the smallest rectangle that contains all glyphs in this QGlyphRun.
QList< QPointF > positions() const
Returns the position of the edge of the baseline for each glyph in this set of glyph indexes.
QList< T > values() const
Returns a list containing all the values in the hash, in an arbitrary order.
qsizetype size() const noexcept
bool isEmpty() const noexcept
qsizetype length() const noexcept
const_reference at(qsizetype i) const noexcept
void reserve(qsizetype size)
void append(parameter_type t)
void addRect(const QRectF &rect)
Adds the given rectangle to this path as a closed subpath.
void setFillRule(Qt::FillRule fillRule)
Sets the fill rule of the painter path to the given fillRule.
bool isEmpty() const
Returns true if either there are no elements in this path, or if the only element is a MoveToElement;...
static QPainterPrivate * get(QPainter *painter)
void drawTextItem(const QPointF &p, const QTextItem &_ti, QTextEngine *textEngine)
The QPainter class performs low-level painting on widgets and other paint devices.
CompositionMode
Defines the modes supported for digital image compositing.
@ RasterOp_NotDestination
void setCosmetic(bool cosmetic)
Sets this pen to cosmetic or non-cosmetic, depending on the value of cosmetic.
QBrush brush() const
Returns the brush used to fill strokes generated with this pen.
\inmodule QtCore\reentrant
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
static QRawFontPrivate * get(const QRawFont &font)
void setFontEngine(QFontEngine *engine)
The QRawFont class provides access to a single physical instance of a font.
bool isValid() const
Returns true if the QRawFont is valid and false otherwise.
\inmodule QtCore\reentrant
constexpr qreal bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
constexpr void setBottom(qreal pos) noexcept
Sets the bottom edge of the rectangle to the given finite y coordinate.
constexpr void setRight(qreal pos) noexcept
Sets the right edge of the rectangle to the given finite x coordinate.
constexpr qreal y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr qreal height() const noexcept
Returns the height of the rectangle.
constexpr QRectF translated(qreal dx, qreal dy) const noexcept
Returns a copy of the rectangle that is translated dx along the x axis and dy along the y axis,...
constexpr QPointF bottomLeft() const noexcept
Returns the position of the rectangle's bottom-left corner.
constexpr bool isNull() const noexcept
Returns true if the rectangle is a null rectangle, otherwise returns false.
constexpr QPointF topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
constexpr QPointF bottomRight() const noexcept
Returns the position of the rectangle's bottom-right corner.
constexpr void adjust(qreal x1, qreal y1, qreal x2, qreal y2) noexcept
Adds dx1, dy1, dx2 and dy2 respectively to the existing coordinates of the rectangle.
constexpr void translate(qreal dx, qreal dy) noexcept
Moves the rectangle dx along the x-axis and dy along the y-axis, relative to the current position.
constexpr qreal top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr bool isValid() const noexcept
Returns true if the rectangle is valid, otherwise returns false.
constexpr QPointF topRight() const noexcept
Returns the position of the rectangle's top-right corner.
QRectF intersected(const QRectF &other) const noexcept
QRectF united(const QRectF &other) const noexcept
constexpr qreal right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isNull() const
Returns true if this string is null; otherwise returns false.
qsizetype size() const
Returns the number of characters in this string.
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
QByteArray toUtf8() const &
qsizetype length() const
Returns the number of characters in this string.
const QChar * unicode() const
Returns a Unicode representation of the string.
int length() const
Returns the length of the block in characters.
bool isValid() const
Returns true if this text block is valid; otherwise returns false.
int position() const
Returns the index of the block's first character within the document.
VerticalAlignment
This enum describes the ways that adjacent characters can be vertically aligned.
void documentChange(int from, int length)
static const QTextDocumentPrivate * get(const QTextDocument *document)
QList< QTextLayout::FormatRange > formats() const
void setPreeditArea(int position, const QString &text)
int lineNumberForTextPosition(int pos)
unsigned short * logClusters(const QScriptItem *si) const
bool isRightToLeft() const
void shapeLine(const QScriptLine &line)
QGlyphLayout shapedGlyphs(const QScriptItem *si) const
int preeditAreaPosition() const
int positionInLigature(const QScriptItem *si, int end, QFixed x, QFixed edge, int glyph_pos, bool cursorOnCharacter)
int findItem(int strPos, int firstItem=0) const
void shape(int item) const
void enableDelayDecorations(bool enable=true)
void resetFontEngineCache()
const QCharAttributes * attributes() const
QFixed leadingSpaceWidth(const QScriptLine &line)
QFixed alignLine(const QScriptLine &line)
QString preeditAreaText() const
int positionAfterVisualMovement(int oldPos, QTextCursor::MoveOperation op)
int formatIndex(const QScriptItem *si) const
QFontEngine * fontEngine(const QScriptItem &si, QFixed *ascent=nullptr, QFixed *descent=nullptr, QFixed *leading=nullptr) const
void drawDecorations(QPainter *painter)
bool visualCursorMovement() const
QFixed calculateTabWidth(int index, QFixed x) const
returns the width of tab at index (in the tabs array) with the tab-start at position x
bool atWordSeparator(int position) const
void setFormats(const QList< QTextLayout::FormatRange > &formats)
QTextCharFormat format(const QScriptItem *si) const
std::vector< int > insertionPointsForLine(int lineNum)
static void bidiReorder(int numRuns, const quint8 *levels, int *visualOrder)
int previousLogicalPosition(int oldPos) const
QFixed offsetInLigature(const QScriptItem *si, int pos, int max, int glyph_pos)
QFont font(const QScriptItem &si) const
int length(int item) const
QTextFormatCollection * formatCollection() const
QAbstractTextDocumentLayout * docLayout() const
QTextCharFormat defaultTextFormat() const
QBrush background() const
Returns the brush used to paint the document's background.
void merge(const QTextFormat &other)
Merges the other format with this format; where there are conflicts the other format takes precedence...
QVariant property(int propertyId) const
Returns the property specified by the given propertyId.
QBrush foreground() const
Returns the brush used to render foreground details, such as text, frame outlines,...
QTextFormat format() const
Returns format of the inline object within the text layout.
void setDescent(qreal d)
Sets the inline object's descent to d.
void setAscent(qreal a)
Sets the inline object's ascent to a.
qreal ascent() const
Returns the inline object's ascent.
qreal width() const
Returns the inline object's width.
qreal height() const
Returns the inline object's total height.
int formatIndex() const
Returns an integer describing the format of the inline object within the text layout.
QRectF rect() const
Returns the inline object's rectangle.
void setWidth(qreal w)
Sets the inline object's width to w.
Qt::LayoutDirection textDirection() const
Returns if the object should be laid out right-to-left or left-to-right.
qreal descent() const
Returns the inline object's descent.
int textPosition() const
The position of the inline object within the text layout.
const QTextOption & textOption() const
Returns the current text option used to control the layout process.
int rightCursorPosition(int oldPos) const
Returns the cursor position to the right of oldPos, next to it.
QTextLine lineForTextPosition(int pos) const
Returns the line that contains the cursor position specified by pos.
void setFont(const QFont &f)
Sets the layout's font to the given font.
QTextLine createLine()
Returns a new text line to be laid out if there is text to be inserted into the layout; otherwise ret...
void beginLayout()
Begins the layout process.
qreal minimumWidth() const
The minimum width the layout needs.
void setPosition(const QPointF &p)
Moves the text layout to point p.
void setCacheEnabled(bool enable)
Enables caching of the complete layout information if enable is true; otherwise disables layout cachi...
void setFormats(const QList< FormatRange > &overrides)
void setText(const QString &string)
Sets the layout's text to the given string.
QList< QGlyphRun > glyphRuns(int from=-1, int length=-1, GlyphRunRetrievalFlags flags=DefaultRetrievalFlags) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
QList< FormatRange > formats() const
QString text() const
Returns the layout's text.
QTextLayout()
Constructs an empty text layout.
void setRawFont(const QRawFont &rawFont)
int previousCursorPosition(int oldPos, CursorMode mode=SkipCharacters) const
Returns the first valid cursor position before oldPos that respects the given cursor mode.
int lineCount() const
Returns the number of lines in this text layout.
int preeditAreaPosition() const
Returns the position of the area in the text layout that will be processed before editing occurs.
qreal maximumWidth() const
The maximum width the layout could expand to; this is essentially the width of the entire text.
QTextLine lineAt(int i) const
Returns the {i}-th line of text in this text layout.
int nextCursorPosition(int oldPos, CursorMode mode=SkipCharacters) const
Returns the next valid cursor position after oldPos that respects the given cursor mode.
void setTextOption(const QTextOption &option)
Sets the text option structure that controls the layout process to the given option.
bool isValidCursorPosition(int pos) const
Returns true if position pos is a valid cursor position.
bool cacheEnabled() const
Returns true if the complete layout information is cached; otherwise returns false.
void draw(QPainter *p, const QPointF &pos, const QList< FormatRange > &selections=QList< FormatRange >(), const QRectF &clip=QRectF()) const
Draws the whole layout on the painter p at the position specified by pos.
Qt::CursorMoveStyle cursorMoveStyle() const
The cursor movement style of this QTextLayout.
QFont font() const
Returns the current font that is used for the layout, or a default font if none is set.
~QTextLayout()
Destructs the layout.
void endLayout()
Ends the layout process.
QString preeditAreaText() const
Returns the text that is inserted in the layout before editing occurs.
void setPreeditArea(int position, const QString &text)
Sets the position and text of the area in the layout that is processed before editing occurs.
void drawCursor(QPainter *p, const QPointF &pos, int cursorPosition) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
void setCursorMoveStyle(Qt::CursorMoveStyle style)
Sets the visual cursor movement style to the given style.
QRectF boundingRect() const
The smallest rectangle that contains all the lines in the layout.
CursorMode
\value SkipCharacters \value SkipWords
int leftCursorPosition(int oldPos) const
Returns the cursor position to the left of oldPos, next to it.
qreal descent() const
Returns the line's descent.
int textStart() const
Returns the start of the line from the beginning of the string passed to the QTextLayout.
void setNumColumns(int columns)
Lays out the line.
QList< QGlyphRun > glyphRuns(int from=-1, int length=-1, QTextLayout::GlyphRunRetrievalFlags flags=QTextLayout::DefaultRetrievalFlags) const
Returns the glyph indexes and positions for all glyphs in this QTextLine for characters in the range ...
QRectF naturalTextRect() const
Returns the rectangle covered by the line.
QRectF rect() const
Returns the line's bounding rectangle.
qreal height() const
Returns the line's height.
void draw(QPainter *painter, const QPointF &position) const
Draws a line on the given painter at the specified position.
bool leadingIncluded() const
qreal cursorToX(int *cursorPos, Edge edge=Leading) const
Converts the cursor position cursorPos to the corresponding x position inside the line,...
qreal naturalTextWidth() const
Returns the width of the line that is occupied by text.
void setLeadingIncluded(bool included)
qreal y() const
Returns the line's y position.
qreal width() const
Returns the line's width as specified by the layout() function.
void setPosition(const QPointF &pos)
Moves the line to position pos.
Edge
\value Leading \value Trailing
CursorPosition
\value CursorBetweenCharacters \value CursorOnCharacter
void setLineWidth(qreal width)
Lays out the line with the given width.
qreal ascent() const
Returns the line's ascent.
int xToCursor(qreal x, CursorPosition=CursorBetweenCharacters) const
Converts the x-coordinate x, to the nearest matching cursor position, depending on the cursor positio...
qreal horizontalAdvance() const
qreal x() const
Returns the line's x position.
int textLength() const
Returns the length of the text in the line.
QPointF position() const
Returns the line's position relative to the text layout's position.
void setTextDirection(Qt::LayoutDirection aDirection)
Sets the direction of the text layout defined by the option to the given direction.
WrapMode wrapMode() const
Returns the text wrap mode defined by the option.
Qt::Alignment alignment() const
Returns the text alignment defined by the option.
void setWrapMode(WrapMode wrap)
Sets the option's text wrap mode to the given mode.
void setAlignment(Qt::Alignment alignment)
Sets the option's text alignment to the specified alignment.
Flags flags() const
Returns the flags associated with the option.
@ ShowLineAndParagraphSeparators
WrapMode
This enum describes how text is wrapped in a document.
@ WrapAtWordBoundaryOrAnywhere
constexpr size_type size() const noexcept
const T & at(qsizetype idx) const
bool toBool() const
Returns the variant as a bool if the variant has userType() Bool.
typename C::iterator iterator
Combined button and popup list for selecting options.
@ TextJustificationForced
std::pair< T1, T2 > QPair
static const QCssKnownValue positions[NumKnownPositionModes - 1]
bool qFuzzyIsNull(qfloat16 f) noexcept
int qRound(qfloat16 d) noexcept
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qBound(const T &min, const T &val, const T &max)
constexpr const T & qMax(const T &a, const T &b)
constexpr T qAbs(const T &t)
std::enable_if_t< std::is_unsigned_v< T >, bool > qAddOverflow(T v1, T v2, T *r)
GLint GLint GLint GLint GLint x
[0]
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLfloat GLfloat GLfloat GLfloat GLfloat maxY
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLenum GLsizei length
GLint GLsizei GLsizei GLenum format
GLsizei const GLchar *const * path
GLsizei const GLchar *const * string
[0]
static const QRectF boundingRect(const QPointF *points, int pointCount)
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
int baseLineOffset(QQuickContext2D::TextBaseLineType value, const QFontMetrics &metrics)
static void addSelectedRegionsToPath(QTextEngine *eng, int lineNumber, const QPointF &pos, QTextLayout::FormatRange *selection, QPainterPath *region, const QRectF &boundingRect)
static void addNextCluster(int &pos, int end, QScriptLine &line, int &glyphCount, const QScriptItem ¤t, const unsigned short *logClusters, const QGlyphLayout &glyphs, QFixed *clusterWidth=nullptr)
static QRectF clipIfValid(const QRectF &rect, const QRectF &clip)
static QGlyphRun glyphRunWithInfo(QFontEngine *fontEngine, const QString &text, const QGlyphLayout &glyphLayout, const QPointF &pos, const QGlyphRun::GlyphRunFlags &flags, QTextLayout::GlyphRunRetrievalFlags retrievalFlags, QFixed selectionX, QFixed selectionWidth, int glyphsStart, int glyphsEnd, unsigned short *logClusters, int textPosition, int textLength)
#define SuppressBackground
static void setPenAndDrawBackground(QPainter *p, const QPen &defaultPen, const QTextCharFormat &chf, const QRectF &r)
#define ObjectSelectionBrush
std::uniform_real_distribution dist(1, 2.5)
[2]
rect deviceTransform(view->viewportTransform()).map(QPointF(0
QItemSelection * selection
[0]
static constexpr QFixed fromReal(qreal r)
static constexpr QFixed fromFixed(int fixed)
constexpr QFixed ceil() const
constexpr qreal toReal() const
QGlyphJustification * justifications
QFixed effectiveAdvance(int item) const
QGlyphAttributes * attributes
QGlyphLayout mid(int position, int n=-1) const
@ LineOrParagraphSeparator
constexpr QFixed height() const noexcept
unsigned short num_glyphs
unsigned short trailingSpaces
unsigned short * logClustersPtr