Qt 4.8
Classes | Public Types | Public Functions | Static Public Functions | Public Variables | Private Functions | List of all members
QTextEngine Class Reference

#include <qtextengine_p.h>

Inheritance diagram for QTextEngine:
QStackTextEngine

Classes

struct  FontEngineCache
 
struct  LayoutData
 
struct  SpecialData
 

Public Types

enum  LayoutState { LayoutEmpty, InLayout, LayoutFailed }
 
enum  Mode { WidthOnly = 0x07 }
 
enum  ShaperFlag { RightToLeft = 0x0001, DesignMetrics = 0x0002, GlyphIndicesOnly = 0x0004 }
 

Public Functions

QFixed alignLine (const QScriptLine &line)
 
bool atSpace (int position) const
 
const HB_CharAttributes * attributes () const
 
bool atWordSeparator (int position) const
 
QGlyphLayout availableGlyphs (const QScriptItem *si) const
 
glyph_metrics_t boundingBox (int from, int len) 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 More...
 
void clearLineData ()
 
QAbstractTextDocumentLayoutdocLayout () const
 
QString elidedText (Qt::TextElideMode mode, const QFixed &width, int flags=0) const
 
bool ensureSpace (int nGlyphs) const
 
int findItem (int strPos) const
 
QFont font (const QScriptItem &si) const
 
QFont font () const
 
QFontEnginefontEngine (const QScriptItem &si, QFixed *ascent=0, QFixed *descent=0, QFixed *leading=0) const
 
QTextCharFormat format (const QScriptItem *si) const
 
int formatIndex (const QScriptItem *si) const
 
QTextFormatCollectionformats () const
 
void freeMemory ()
 
bool hasFormats () const
 
void indexAdditionalFormats ()
 
void insertionPointsForLine (int lineNum, QVector< int > &insertionPoints)
 
void invalidate ()
 
bool isRightToLeft () const
 
void itemize () const
 
void justify (const QScriptLine &si)
 
QFixed leadingSpaceWidth (const QScriptLine &line)
 
int length (int item) const
 
int length (const QScriptItem *si) const
 
int lineNumberForTextPosition (int pos)
 
unsigned short * logClusters (const QScriptItem *si) const
 
int nextLogicalPosition (int oldPos) const
 
QFixed offsetInLigature (const QScriptItem *si, int pos, int max, int glyph_pos)
 
int positionAfterVisualMovement (int oldPos, QTextCursor::MoveOperation op)
 
int positionInLigature (const QScriptItem *si, int end, QFixed x, QFixed edge, int glyph_pos, bool cursorOnCharacter)
 
int previousLogicalPosition (int oldPos) const
 
 QTextEngine (LayoutData *data)
 
 QTextEngine ()
 
 QTextEngine (const QString &str, const QFont &f)
 
void resetFontEngineCache ()
 
void shape (int item) const
 
QGlyphLayout shapedGlyphs (const QScriptItem *si) const
 
void shapeLine (const QScriptLine &line)
 
glyph_metrics_t tightBoundingBox (int from, int len) const
 
void validate () const
 
bool visualCursorMovement () const
 
QFixed width (int charFrom, int numChars) const
 
 ~QTextEngine ()
 

Static Public Functions

static void bidiReorder (int numRuns, const quint8 *levels, int *visualOrder)
 

Public Variables

QTextBlock block
 
uint cacheGlyphs: 1
 
FontEngineCache feCache
 
QFont fnt
 
uint forceJustification: 1
 
uint ignoreBidi: 1
 
LayoutDatalayoutData
 
QScriptLineArray lines
 
QFixed maxWidth
 
QFixed minWidth
 
QTextOption option
 
QPointF position
 
SpecialDataspecialData
 
uint stackEngine: 1
 
QString text
 
int * underlinePositions
 
uint visualMovement: 1
 

Private Functions

void addRequiredBoundaries () const
 
int beginningOfLine (int lineNum)
 
int endOfLine (int lineNum)
 
int getClusterLength (unsigned short *logClusters, const HB_CharAttributes *attributes, int from, int to, int glyph_pos, int *start)
 
void resolveAdditionalFormats () const
 
void setBoundary (int strPos) const
 
void shapeText (int item) const
 
void shapeTextMac (int item) const
 
void shapeTextWithCE (int item) const
 
void shapeTextWithHarfbuzz (int item) const
 take the item from layoutData->items and More...
 
void splitItem (int item, int pos) const
 

Detailed Description

Definition at line 421 of file qtextengine_p.h.

Enumerations

◆ LayoutState

Enumerator
LayoutEmpty 
InLayout 
LayoutFailed 

Definition at line 423 of file qtextengine_p.h.

◆ Mode

Enumerator
WidthOnly 

Definition at line 452 of file qtextengine_p.h.

452  {
453  WidthOnly = 0x07
454  };

◆ ShaperFlag

Enumerator
RightToLeft 
DesignMetrics 
GlyphIndicesOnly 

Definition at line 457 of file qtextengine_p.h.

Constructors and Destructors

◆ QTextEngine() [1/3]

QTextEngine::QTextEngine ( LayoutData data)

◆ QTextEngine() [2/3]

QTextEngine::QTextEngine ( )

Definition at line 1385 of file qtextengine.cpp.

1386 {
1387  init(this);
1388 }
static void init(QTextEngine *e)

◆ QTextEngine() [3/3]

QTextEngine::QTextEngine ( const QString str,
const QFont f 
)

Definition at line 1390 of file qtextengine.cpp.

1391  : text(str),
1392  fnt(f)
1393 {
1394  init(this);
1395 }
static void init(QTextEngine *e)
QString text

◆ ~QTextEngine()

QTextEngine::~QTextEngine ( )

Definition at line 1397 of file qtextengine.cpp.

1398 {
1399  if (!stackEngine)
1400  delete layoutData;
1401  delete specialData;
1403 }
SpecialData * specialData
LayoutData * layoutData
void resetFontEngineCache()

Functions

◆ addRequiredBoundaries()

void QTextEngine::addRequiredBoundaries ( ) const
private

Definition at line 2385 of file qtextengine.cpp.

Referenced by itemize().

2386 {
2387  if (specialData) {
2388  for (int i = 0; i < specialData->addFormats.size(); ++i) {
2390  setBoundary(r.start);
2391  setBoundary(r.start + r.length);
2392  //qDebug("adding boundaries %d %d", r.start, r.start+r.length);
2393  }
2394  }
2395 }
The QTextLayout::FormatRange structure is used to apply extra formatting information for a specified ...
Definition: qtextlayout.h:128
SpecialData * specialData
int start
Specifies the beginning of the format range within the text layout&#39;s text.
Definition: qtextlayout.h:129
QList< QTextLayout::FormatRange > addFormats
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
void setBoundary(int strPos) const
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
int length
Specifies the numer of characters the format range spans.
Definition: qtextlayout.h:130

◆ alignLine()

QFixed QTextEngine::alignLine ( const QScriptLine line)

Definition at line 2832 of file qtextengine.cpp.

Referenced by QTextLine::cursorToX(), QTextLine::naturalTextRect(), QTextLineItemIterator::QTextLineItemIterator(), and QTextLine::xToCursor().

2833 {
2834  QFixed x = 0;
2835  justify(line);
2836  // if width is QFIXED_MAX that means we used setNumColumns() and that implicitly makes this line left aligned.
2837  if (!line.justified && line.width != QFIXED_MAX) {
2838  int align = option.alignment();
2839  if (align & Qt::AlignJustify && isRightToLeft())
2840  align = Qt::AlignRight;
2841  if (align & Qt::AlignRight)
2842  x = line.width - (line.textAdvance);
2843  else if (align & Qt::AlignHCenter)
2844  x = (line.width - line.textAdvance)/2;
2845  }
2846  return x;
2847 }
bool isRightToLeft() const
#define QFIXED_MAX
Definition: qfixed_p.h:158
QTextOption option
QFixed textAdvance
void justify(const QScriptLine &si)
Qt::Alignment alignment() const
Returns the text alignment defined by the option.
Definition: qtextoption.h:97

◆ atSpace()

bool QTextEngine::atSpace ( int  position) const

Definition at line 2437 of file qtextengine.cpp.

Referenced by QTextCursorPrivate::movePosition().

2438 {
2439  const QChar c = layoutData->string.at(position);
2440 
2441  return c == QLatin1Char(' ')
2442  || c == QChar::Nbsp
2443  || c == QChar::LineSeparator
2444  || c == QLatin1Char('\t')
2445  ;
2446 }
unsigned char c[8]
Definition: qnumeric_p.h:62
const QChar at(int i) const
Returns the character at the given index position in the string.
Definition: qstring.h:698
LayoutData * layoutData
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
QPointF position
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55

◆ attributes()

const HB_CharAttributes * QTextEngine::attributes ( ) const

Definition at line 1405 of file qtextengine.cpp.

Referenced by QTextLine::cursorToX(), elidedText(), justify(), QTextLine::layout_helper(), QTextCursorPrivate::movePosition(), nextLogicalPosition(), positionInLigature(), and previousLogicalPosition().

1406 {
1408  return (HB_CharAttributes *) layoutData->memory;
1409 
1410  itemize();
1411  if (! ensureSpace(layoutData->string.length()))
1412  return NULL;
1413 
1415 
1416  for (int i = 0; i < layoutData->items.size(); ++i) {
1417  const QScriptItem &si = layoutData->items[i];
1418  hbScriptItems[i].pos = si.position;
1419  hbScriptItems[i].length = length(i);
1420  hbScriptItems[i].bidiLevel = si.analysis.bidiLevel;
1421  hbScriptItems[i].script = (HB_Script)si.analysis.script;
1422  }
1423 
1424  qGetCharAttributes(reinterpret_cast<const HB_UChar16 *>(layoutData->string.constData()),
1426  hbScriptItems.data(), hbScriptItems.size(),
1427  (HB_CharAttributes *)layoutData->memory);
1428 
1429 
1431  return (HB_CharAttributes *) layoutData->memory;
1432 }
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
bool ensureSpace(int nGlyphs) const
QScriptItemArray items
LayoutData * layoutData
unsigned short bidiLevel
void itemize() const
unsigned short script
int length(int item) const
void qGetCharAttributes(const HB_UChar16 *string, hb_uint32 stringLength, const HB_ScriptItem *items, hb_uint32 numItems, HB_CharAttributes *attributes)
Definition: qharfbuzz.cpp:133
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
const QChar * constData() const
Returns a pointer to the data stored in the QString.
Definition: qstring.h:712
QScriptAnalysis analysis

◆ atWordSeparator()

bool QTextEngine::atWordSeparator ( int  position) const

Definition at line 2397 of file qtextengine.cpp.

Referenced by QTextCursorPrivate::movePosition().

2398 {
2399  const QChar c = layoutData->string.at(position);
2400  switch (c.toLatin1()) {
2401  case '.':
2402  case ',':
2403  case '?':
2404  case '!':
2405  case '@':
2406  case '#':
2407  case '$':
2408  case ':':
2409  case ';':
2410  case '-':
2411  case '<':
2412  case '>':
2413  case '[':
2414  case ']':
2415  case '(':
2416  case ')':
2417  case '{':
2418  case '}':
2419  case '=':
2420  case '/':
2421  case '+':
2422  case '%':
2423  case '&':
2424  case '^':
2425  case '*':
2426  case '\'':
2427  case '"':
2428  case '`':
2429  case '~':
2430  case '|':
2431  return true;
2432  default:
2433  return false;
2434  }
2435 }
unsigned char c[8]
Definition: qnumeric_p.h:62
const QChar at(int i) const
Returns the character at the given index position in the string.
Definition: qstring.h:698
LayoutData * layoutData
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
QPointF position
char toLatin1() const
Returns the Latin-1 character equivalent to the QChar, or 0.
Definition: qchar.h:376

◆ availableGlyphs()

QGlyphLayout QTextEngine::availableGlyphs ( const QScriptItem si) const
inline

Returns an array of QGlyphLayout items, offset at the script item. Each item in the array matches one glyph in the text, storing the advance, position etc. The returned item's length equals to the number of available glyphs. This may be more than what was actually shaped.

See also
logClusters()

Definition at line 520 of file qtextengine_p.h.

520  {
522  }
LayoutData * layoutData
QGlyphLayout mid(int position, int n=-1) const
int glyph_data_offset

◆ beginningOfLine()

int QTextEngine::beginningOfLine ( int  lineNum)
private

Definition at line 3029 of file qtextengine.cpp.

Referenced by positionAfterVisualMovement().

3030 {
3031  QVector<int> insertionPoints;
3032  insertionPointsForLine(lineNum, insertionPoints);
3033 
3034  if (insertionPoints.size() > 0)
3035  return insertionPoints.first();
3036  return 0;
3037 }
T & first()
Returns a reference to the first item in the vector.
Definition: qvector.h:260
void insertionPointsForLine(int lineNum, QVector< int > &insertionPoints)
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137

◆ bidiReorder()

void QTextEngine::bidiReorder ( int  numRuns,
const quint8 levels,
int *  visualOrder 
)
static

Definition at line 774 of file qtextengine.cpp.

Referenced by QPainterPath::addText(), QTextLine::cursorToX(), QPainter::drawText(), QTextLineItemIterator::QTextLineItemIterator(), and QTextLine::xToCursor().

775 {
776 
777  // first find highest and lowest levels
778  quint8 levelLow = 128;
779  quint8 levelHigh = 0;
780  int i = 0;
781  while (i < numItems) {
782  //printf("level = %d\n", r->level);
783  if (levels[i] > levelHigh)
784  levelHigh = levels[i];
785  if (levels[i] < levelLow)
786  levelLow = levels[i];
787  i++;
788  }
789 
790  // implements reordering of the line (L2 according to BiDi spec):
791  // L2. From the highest level found in the text to the lowest odd level on each line,
792  // reverse any contiguous sequence of characters that are at that level or higher.
793 
794  // reversing is only done up to the lowest odd level
795  if(!(levelLow%2)) levelLow++;
796 
797 #if (BIDI_DEBUG >= 1)
798 // qDebug() << "reorderLine: lineLow = " << (uint)levelLow << ", lineHigh = " << (uint)levelHigh;
799 #endif
800 
801  int count = numItems - 1;
802  for (i = 0; i < numItems; i++)
803  visualOrder[i] = i;
804 
805  while(levelHigh >= levelLow) {
806  int i = 0;
807  while (i < count) {
808  while(i < count && levels[i] < levelHigh) i++;
809  int start = i;
810  while(i <= count && levels[i] >= levelHigh) i++;
811  int end = i-1;
812 
813  if(start != end) {
814  //qDebug() << "reversing from " << start << " to " << end;
815  for(int j = 0; j < (end-start+1)/2; j++) {
816  int tmp = visualOrder[start+j];
817  visualOrder[start+j] = visualOrder[end-j];
818  visualOrder[end-j] = tmp;
819  }
820  }
821  i++;
822  }
823  levelHigh--;
824  }
825 
826 #if (BIDI_DEBUG >= 1)
827 // qDebug() << "visual order is:";
828 // for (i = 0; i < numItems; i++)
829 // qDebug() << visualOrder[i];
830 #endif
831 }
unsigned char quint8
Definition: qglobal.h:934
static const KeyPair *const end

◆ boundingBox()

glyph_metrics_t QTextEngine::boundingBox ( int  from,
int  len 
) const

Definition at line 1736 of file qtextengine.cpp.

1737 {
1738  itemize();
1739 
1740  glyph_metrics_t gm;
1741 
1742  for (int i = 0; i < layoutData->items.size(); i++) {
1743  const QScriptItem *si = layoutData->items.constData() + i;
1744 
1745  int pos = si->position;
1746  int ilen = length(i);
1747  if (pos > from + len)
1748  break;
1749  if (pos + ilen > from) {
1750  if (!si->num_glyphs)
1751  shape(i);
1752 
1753  if (si->analysis.flags == QScriptAnalysis::Object) {
1754  gm.width += si->width;
1755  continue;
1756  } else if (si->analysis.flags == QScriptAnalysis::Tab) {
1757  gm.width += calculateTabWidth(i, gm.width);
1758  continue;
1759  }
1760 
1761  unsigned short *logClusters = this->logClusters(si);
1762  QGlyphLayout glyphs = shapedGlyphs(si);
1763 
1764  // do the simple thing for now and give the first glyph in a cluster the full width, all other ones 0.
1765  int charFrom = from - pos;
1766  if (charFrom < 0)
1767  charFrom = 0;
1768  int glyphStart = logClusters[charFrom];
1769  if (charFrom > 0 && logClusters[charFrom-1] == glyphStart)
1770  while (charFrom < ilen && logClusters[charFrom] == glyphStart)
1771  charFrom++;
1772  if (charFrom < ilen) {
1773  QFontEngine *fe = fontEngine(*si);
1774  glyphStart = logClusters[charFrom];
1775  int charEnd = from + len - 1 - pos;
1776  if (charEnd >= ilen)
1777  charEnd = ilen-1;
1778  int glyphEnd = logClusters[charEnd];
1779  while (charEnd < ilen && logClusters[charEnd] == glyphEnd)
1780  charEnd++;
1781  glyphEnd = (charEnd == ilen) ? si->num_glyphs : logClusters[charEnd];
1782  if (glyphStart <= glyphEnd ) {
1783  glyph_metrics_t m = fe->boundingBox(glyphs.mid(glyphStart, glyphEnd - glyphStart));
1784  gm.x = qMin(gm.x, m.x + gm.xoff);
1785  gm.y = qMin(gm.y, m.y + gm.yoff);
1786  gm.width = qMax(gm.width, m.width+gm.xoff);
1787  gm.height = qMax(gm.height, m.height+gm.yoff);
1788  gm.xoff += m.xoff;
1789  gm.yoff += m.yoff;
1790  }
1791  }
1792  }
1793  }
1794  return gm;
1795 }
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
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 ...
QFontEngine * fontEngine(const QScriptItem &si, QFixed *ascent=0, QFixed *descent=0, QFixed *leading=0) const
QScriptItemArray items
LayoutData * layoutData
unsigned short * logClusters(const QScriptItem *si) const
QGlyphLayout mid(int position, int n=-1) const
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
QGlyphLayout shapedGlyphs(const QScriptItem *si) const
unsigned short num_glyphs
virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs)=0
void itemize() const
unsigned short flags
void shape(int item) const
int length(int item) const
if(void) toggleToolbarShown
const T * constData() const
Returns a const pointer to the data stored in the vector.
Definition: qvector.h:154
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
QScriptAnalysis analysis

◆ calculateTabWidth()

QFixed QTextEngine::calculateTabWidth ( int  index,
QFixed  x 
) const

returns the width of tab at index (in the tabs array) with the tab-start at position x

Definition at line 2710 of file qtextengine.cpp.

Referenced by boundingBox(), QTextLine::layout_helper(), and width().

2711 {
2712  const QScriptItem &si = layoutData->items[item];
2713 
2714  QFixed dpiScale = 1;
2715  if (block.docHandle() && block.docHandle()->layout()) {
2716  QPaintDevice *pdev = block.docHandle()->layout()->paintDevice();
2717  if (pdev)
2718  dpiScale = QFixed::fromReal(pdev->logicalDpiY() / qreal(qt_defaultDpiY()));
2719  } else {
2720  dpiScale = QFixed::fromReal(fnt.d->dpi / qreal(qt_defaultDpiY()));
2721  }
2722 
2723  QList<QTextOption::Tab> tabArray = option.tabs();
2724  if (!tabArray.isEmpty()) {
2725  if (isRightToLeft()) { // rebase the tabArray positions.
2726  QList<QTextOption::Tab> newTabs;
2727  QList<QTextOption::Tab>::Iterator iter = tabArray.begin();
2728  while(iter != tabArray.end()) {
2729  QTextOption::Tab tab = *iter;
2730  if (tab.type == QTextOption::LeftTab)
2732  else if (tab.type == QTextOption::RightTab)
2733  tab.type = QTextOption::LeftTab;
2734  newTabs << tab;
2735  ++iter;
2736  }
2737  tabArray = newTabs;
2738  }
2739  for (int i = 0; i < tabArray.size(); ++i) {
2740  QFixed tab = QFixed::fromReal(tabArray[i].position) * dpiScale;
2741  if (tab > x) { // this is the tab we need.
2742  QTextOption::Tab tabSpec = tabArray[i];
2743  int tabSectionEnd = layoutData->string.count();
2744  if (tabSpec.type == QTextOption::RightTab || tabSpec.type == QTextOption::CenterTab) {
2745  // find next tab to calculate the width required.
2746  tab = QFixed::fromReal(tabSpec.position);
2747  for (int i=item + 1; i < layoutData->items.count(); i++) {
2748  const QScriptItem &item = layoutData->items[i];
2749  if (item.analysis.flags == QScriptAnalysis::TabOrObject) { // found it.
2750  tabSectionEnd = item.position;
2751  break;
2752  }
2753  }
2754  }
2755  else if (tabSpec.type == QTextOption::DelimiterTab)
2756  // find delimitor character to calculate the width required
2757  tabSectionEnd = qMax(si.position, layoutData->string.indexOf(tabSpec.delimiter, si.position) + 1);
2758 
2759  if (tabSectionEnd > si.position) {
2760  QFixed length;
2761  // Calculate the length of text between this tab and the tabSectionEnd
2762  for (int i=item; i < layoutData->items.count(); i++) {
2763  QScriptItem &item = layoutData->items[i];
2764  if (item.position > tabSectionEnd || item.position <= si.position)
2765  continue;
2766  shape(i); // first, lets make sure relevant text is already shaped
2767  QGlyphLayout glyphs = this->shapedGlyphs(&item);
2768  const int end = qMin(item.position + item.num_glyphs, tabSectionEnd) - item.position;
2769  for (int i=0; i < end; i++)
2770  length += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint;
2771  if (end + item.position == tabSectionEnd && tabSpec.type == QTextOption::DelimiterTab) // remove half of matching char
2772  length -= glyphs.advances_x[end] / 2 * !glyphs.attributes[end].dontPrint;
2773  }
2774 
2775  switch (tabSpec.type) {
2777  length /= 2;
2778  // fall through
2780  // fall through
2781  case QTextOption::RightTab:
2782  tab = QFixed::fromReal(tabSpec.position) * dpiScale - length;
2783  if (tab < 0) // default to tab taking no space
2784  return QFixed();
2785  break;
2786  case QTextOption::LeftTab:
2787  break;
2788  }
2789  }
2790  return tab - x;
2791  }
2792  }
2793  }
2795  if (tab <= 0)
2796  tab = 80; // default
2797  tab *= dpiScale;
2798  QFixed nextTabPos = ((x / tab).truncate() + 1) * tab;
2799  QFixed tabWidth = nextTabPos - x;
2800 
2801  return tabWidth;
2802 }
bool isRightToLeft() const
double qreal
Definition: qglobal.h:1193
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
QFixed * advances_x
int logicalDpiY() const
Definition: qpaintdevice.h:96
int count(const T &t) const
Returns the number of occurrences of value in the vector.
Definition: qvector.h:742
Q_GUI_EXPORT int qt_defaultDpiY()
Definition: qfont.cpp:201
iterator begin()
Returns an STL-style iterator pointing to the first item in the list.
Definition: qlist.h:267
QScriptItemArray items
QAbstractTextDocumentLayout * layout() const
LayoutData * layoutData
static QFixed fromReal(qreal r)
Definition: qfixed_p.h:70
qreal tabStop() const
Returns the distance in device units between tab stops.
Definition: qtextoption.h:124
TabType type
Determine which type is used.
Definition: qtextoption.h:85
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
qreal position
Distance from the start of the paragraph.
Definition: qtextoption.h:84
QChar delimiter
If type is DelimitorTab; tab until this char is found in the text.
Definition: qtextoption.h:86
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qlist.h:270
QGlyphLayout shapedGlyphs(const QScriptItem *si) const
int indexOf(QChar c, int from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:2838
unsigned short num_glyphs
QTextOption option
int count() const
Definition: qstring.h:103
QList< Tab > tabs() const
Returns a list of tab positions defined for the text layout.
unsigned short flags
QTextBlock block
void shape(int item) const
QPointF position
QExplicitlySharedDataPointer< QFontPrivate > d
Definition: qfont.h:343
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
int length(int item) const
QPaintDevice * paintDevice() const
Returns the paint device used to render the document&#39;s layout.
if(void) toggleToolbarShown
HB_GlyphAttributes * attributes
QTextDocumentPrivate * docHandle() const
Definition: qtextobject.h:283
static const KeyPair *const end
Each tab definition is represented by this struct.
Definition: qtextoption.h:69
QScriptAnalysis analysis

◆ clearLineData()

void QTextEngine::clearLineData ( )

Definition at line 1481 of file qtextengine.cpp.

1482 {
1483  lines.clear();
1484 }
void clear()
Removes all the elements from the vector and releases the memory used by the vector.
Definition: qvector.h:347
QScriptLineArray lines

◆ docLayout()

QAbstractTextDocumentLayout* QTextEngine::docLayout ( ) const
inline

Definition at line 550 of file qtextengine_p.h.

Referenced by QTextLine::draw(), QTextLine::layout_helper(), and shape().

550  {
551 #ifdef QT_BUILD_COMPAT_LIB
552  return 0; // Compat should never reference this symbol
553 #else
554  return block.docHandle()->document()->documentLayout();
555 #endif
556  }
QTextBlock block
QAbstractTextDocumentLayout * documentLayout() const
Returns the document layout for this document.
QTextDocumentPrivate * docHandle() const
Definition: qtextobject.h:283
QTextDocument * document()

◆ elidedText()

QString QTextEngine::elidedText ( Qt::TextElideMode  mode,
const QFixed width,
int  flags = 0 
) const

Definition at line 2486 of file qtextengine.cpp.

Referenced by QFontMetrics::elidedText(), QFontMetricsF::elidedText(), and QCommonStylePrivate::viewItemDrawText().

2487 {
2488 // qDebug() << "elidedText; available width" << width.toReal() << "text width:" << this->width(0, layoutData->string.length()).toReal();
2489 
2490  if (flags & Qt::TextShowMnemonic) {
2491  itemize();
2492  HB_CharAttributes *attributes = const_cast<HB_CharAttributes *>(this->attributes());
2493  if (!attributes)
2494  return QString();
2495  for (int i = 0; i < layoutData->items.size(); ++i) {
2496  QScriptItem &si = layoutData->items[i];
2497  if (!si.num_glyphs)
2498  shape(i);
2499 
2500  unsigned short *logClusters = this->logClusters(&si);
2501  QGlyphLayout glyphs = shapedGlyphs(&si);
2502 
2503  const int end = si.position + length(&si);
2504  for (int i = si.position; i < end - 1; ++i) {
2505  if (layoutData->string.at(i) == QLatin1Char('&')) {
2506  const int gp = logClusters[i - si.position];
2507  glyphs.attributes[gp].dontPrint = true;
2508  attributes[i + 1].charStop = false;
2509  attributes[i + 1].whiteSpace = false;
2510  attributes[i + 1].lineBreakType = HB_NoBreak;
2511  if (layoutData->string.at(i + 1) == QLatin1Char('&'))
2512  ++i;
2513  }
2514  }
2515  }
2516  }
2517 
2518  validate();
2519 
2520  if (mode == Qt::ElideNone
2521  || this->width(0, layoutData->string.length()) <= width
2522  || layoutData->string.length() <= 1)
2523  return layoutData->string;
2524 
2525  QFixed ellipsisWidth;
2526  QString ellipsisText;
2527  {
2528  QChar ellipsisChar(0x2026);
2529 
2531 
2532  QGlyphLayoutArray<1> ellipsisGlyph;
2533  {
2534  QFontEngine *feForEllipsis = (fe->type() == QFontEngine::Multi)
2535  ? static_cast<QFontEngineMulti *>(fe)->engine(0)
2536  : fe;
2537 
2538  if (feForEllipsis->type() == QFontEngine::Mac)
2539  feForEllipsis = fe;
2540 
2541  // the lookup can be really slow when we use XLFD fonts
2542  if (feForEllipsis->type() != QFontEngine::XLFD
2543  && feForEllipsis->canRender(&ellipsisChar, 1)) {
2544  int nGlyphs = 1;
2545  feForEllipsis->stringToCMap(&ellipsisChar, 1, &ellipsisGlyph, &nGlyphs, 0);
2546  }
2547  }
2548 
2549  if (ellipsisGlyph.glyphs[0]) {
2550  ellipsisWidth = ellipsisGlyph.advances_x[0];
2551  ellipsisText = ellipsisChar;
2552  } else {
2553  QString dotDotDot(QLatin1String("..."));
2554 
2555  QGlyphLayoutArray<3> glyphs;
2556  int nGlyphs = 3;
2557  if (!fe->stringToCMap(dotDotDot.constData(), 3, &glyphs, &nGlyphs, 0))
2558  // should never happen...
2559  return layoutData->string;
2560  for (int i = 0; i < nGlyphs; ++i)
2561  ellipsisWidth += glyphs.advances_x[i];
2562  ellipsisText = dotDotDot;
2563  }
2564  }
2565 
2566  const QFixed availableWidth = width - ellipsisWidth;
2567  if (availableWidth < 0)
2568  return QString();
2569 
2570  const HB_CharAttributes *attributes = this->attributes();
2571  if (!attributes)
2572  return QString();
2573 
2574  if (mode == Qt::ElideRight) {
2575  QFixed currentWidth;
2576  int pos;
2577  int nextBreak = 0;
2578 
2579  do {
2580  pos = nextBreak;
2581 
2582  ++nextBreak;
2583  while (nextBreak < layoutData->string.length() && !attributes[nextBreak].charStop)
2584  ++nextBreak;
2585 
2586  currentWidth += this->width(pos, nextBreak - pos);
2587  } while (nextBreak < layoutData->string.length()
2588  && currentWidth < availableWidth);
2589 
2590  if (nextCharJoins(layoutData->string, pos))
2591  ellipsisText.prepend(QChar(0x200d) /* ZWJ */);
2592 
2593  return layoutData->string.left(pos) + ellipsisText;
2594  } else if (mode == Qt::ElideLeft) {
2595  QFixed currentWidth;
2596  int pos;
2597  int nextBreak = layoutData->string.length();
2598 
2599  do {
2600  pos = nextBreak;
2601 
2602  --nextBreak;
2603  while (nextBreak > 0 && !attributes[nextBreak].charStop)
2604  --nextBreak;
2605 
2606  currentWidth += this->width(nextBreak, pos - nextBreak);
2607  } while (nextBreak > 0
2608  && currentWidth < availableWidth);
2609 
2610  if (prevCharJoins(layoutData->string, pos))
2611  ellipsisText.append(QChar(0x200d) /* ZWJ */);
2612 
2613  return ellipsisText + layoutData->string.mid(pos);
2614  } else if (mode == Qt::ElideMiddle) {
2615  QFixed leftWidth;
2616  QFixed rightWidth;
2617 
2618  int leftPos = 0;
2619  int nextLeftBreak = 0;
2620 
2621  int rightPos = layoutData->string.length();
2622  int nextRightBreak = layoutData->string.length();
2623 
2624  do {
2625  leftPos = nextLeftBreak;
2626  rightPos = nextRightBreak;
2627 
2628  ++nextLeftBreak;
2629  while (nextLeftBreak < layoutData->string.length() && !attributes[nextLeftBreak].charStop)
2630  ++nextLeftBreak;
2631 
2632  --nextRightBreak;
2633  while (nextRightBreak > 0 && !attributes[nextRightBreak].charStop)
2634  --nextRightBreak;
2635 
2636  leftWidth += this->width(leftPos, nextLeftBreak - leftPos);
2637  rightWidth += this->width(nextRightBreak, rightPos - nextRightBreak);
2638  } while (nextLeftBreak < layoutData->string.length()
2639  && nextRightBreak > 0
2640  && leftWidth + rightWidth < availableWidth);
2641 
2642  if (nextCharJoins(layoutData->string, leftPos))
2643  ellipsisText.prepend(QChar(0x200d) /* ZWJ */);
2644  if (prevCharJoins(layoutData->string, rightPos))
2645  ellipsisText.append(QChar(0x200d) /* ZWJ */);
2646 
2647  return layoutData->string.left(leftPos) + ellipsisText + layoutData->string.mid(rightPos);
2648  }
2649 
2650  return layoutData->string;
2651 }
static bool prevCharJoins(const QString &string, int pos)
QFixed * advances_x
const QChar at(int i) const
Returns the character at the given index position in the string.
Definition: qstring.h:698
HB_Glyph * glyphs
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
QScriptItemArray items
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
LayoutData * layoutData
unsigned short * logClusters(const QScriptItem *si) const
The QString class provides a Unicode character string.
Definition: qstring.h:83
virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const =0
const HB_CharAttributes * attributes() const
virtual Type type() const =0
void validate() const
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
QString left(int n) const Q_REQUIRED_RESULT
Returns a substring that contains the n leftmost characters of the string.
Definition: qstring.cpp:3664
virtual bool canRender(const QChar *string, int len)=0
QGlyphLayout shapedGlyphs(const QScriptItem *si) const
unsigned short num_glyphs
void itemize() const
static bool nextCharJoins(const QString &string, int pos)
QFontEngine * engineForScript(int script) const
Definition: qfont.cpp:294
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
Definition: qstring.cpp:3706
void shape(int item) const
QExplicitlySharedDataPointer< QFontPrivate > d
Definition: qfont.h:343
int length(int item) const
HB_GlyphAttributes * attributes
static const KeyPair *const end
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
QFixed width(int charFrom, int numChars) const

◆ endOfLine()

int QTextEngine::endOfLine ( int  lineNum)
private

Definition at line 3019 of file qtextengine.cpp.

Referenced by positionAfterVisualMovement().

3020 {
3021  QVector<int> insertionPoints;
3022  insertionPointsForLine(lineNum, insertionPoints);
3023 
3024  if (insertionPoints.size() > 0)
3025  return insertionPoints.last();
3026  return 0;
3027 }
void insertionPointsForLine(int lineNum, QVector< int > &insertionPoints)
T & last()
Returns a reference to the last item in the vector.
Definition: qvector.h:262
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137

◆ ensureSpace()

bool QTextEngine::ensureSpace ( int  nGlyphs) const
inline

Definition at line 533 of file qtextengine_p.h.

Referenced by attributes(), and shape().

533  {
534  if (layoutData->glyphLayout.numGlyphs - layoutData->used < nGlyphs)
535  return layoutData->reallocate((((layoutData->used + nGlyphs)*3/2 + 15) >> 4) << 4);
536  return true;
537  }
LayoutData * layoutData
bool reallocate(int totalGlyphs)

◆ findItem()

int QTextEngine::findItem ( int  strPos) const

Definition at line 1655 of file qtextengine.cpp.

Referenced by QTextLine::cursorToX(), justify(), QTextLine::layout_helper(), and QTextLine::xToCursor().

1656 {
1657  itemize();
1658 
1659  int left = 1;
1660  int right = layoutData->items.size()-1;
1661  while (left <= right) {
1662  int middle = ((right-left)/2)+left;
1663  if (strPos > layoutData->items[middle].position)
1664  left = middle+1;
1665  else if (strPos < layoutData->items[middle].position)
1666  right = middle-1;
1667  else {
1668  return middle;
1669  }
1670  }
1671  return right;
1672 }
QScriptItemArray items
LayoutData * layoutData
Q_CORE_EXPORT QTextStream & right(QTextStream &s)
void itemize() const
QPointF position
Q_CORE_EXPORT QTextStream & left(QTextStream &s)
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137

◆ font() [1/2]

QFont QTextEngine::font ( const QScriptItem si) const

Definition at line 1848 of file qtextengine.cpp.

Referenced by QTextLine::draw(), QPainter::drawText(), and QTextLine::glyphs().

1849 {
1850  QFont font = fnt;
1851  if (hasFormats()) {
1852  QTextCharFormat f = format(&si);
1853  font = f.font();
1854 
1855  if (block.docHandle() && block.docHandle()->layout()) {
1856  // Make sure we get the right dpi on printers
1857  QPaintDevice *pdev = block.docHandle()->layout()->paintDevice();
1858  if (pdev)
1859  font = QFont(font, pdev);
1860  } else {
1861  font = font.resolve(fnt);
1862  }
1865  if (font.pointSize() != -1)
1866  font.setPointSize((font.pointSize() * 2) / 3);
1867  else
1868  font.setPixelSize((font.pixelSize() * 2) / 3);
1869  }
1870  }
1871 
1873  font = font.d->smallCapsFont();
1874 
1875  return font;
1876 }
QTextCharFormat format(const QScriptItem *si) const
void setPointSize(int)
Sets the point size to pointSize.
Definition: qfont.cpp:1099
QFont font() const
Returns the font for this character format.
The QTextCharFormat class provides formatting information for characters in a QTextDocument.
Definition: qtextformat.h:372
int pixelSize() const
Returns the pixel size of the font if it was set with setPixelSize().
Definition: qfont.cpp:1178
QAbstractTextDocumentLayout * layout() const
bool hasFormats() const
QFont font() const
QFont resolve(const QFont &) const
Returns a new QFont that has attributes copied from other that have not been previously set on this f...
Definition: qfont.cpp:1983
VerticalAlignment
This enum describes the ways that adjacent characters can be vertically aligned.
Definition: qtextformat.h:375
unsigned short flags
QTextBlock block
VerticalAlignment verticalAlignment() const
Returns the vertical alignment used for characters with this format.
Definition: qtextformat.h:486
The QFont class specifies a font used for drawing text.
Definition: qfont.h:64
QExplicitlySharedDataPointer< QFontPrivate > d
Definition: qfont.h:343
QPaintDevice * paintDevice() const
Returns the paint device used to render the document&#39;s layout.
int pointSize() const
Returns the point size of the font.
Definition: qfont.cpp:981
QTextDocumentPrivate * docHandle() const
Definition: qtextobject.h:283
QFont smallCapsFont() const
Definition: qfont_p.h:199
void setPixelSize(int)
Sets the font size to pixelSize pixels.
Definition: qfont.cpp:1156
QScriptAnalysis analysis

◆ font() [2/2]

QFont QTextEngine::font ( ) const
inline

Definition at line 501 of file qtextengine_p.h.

Referenced by font(), and fontEngine().

501 { return fnt; }

◆ fontEngine()

QFontEngine * QTextEngine::fontEngine ( const QScriptItem si,
QFixed ascent = 0,
QFixed descent = 0,
QFixed leading = 0 
) const

Definition at line 1885 of file qtextengine.cpp.

Referenced by boundingBox(), QTextLine::draw(), justify(), QTextLine::layout_helper(), releaseCachedFontEngine(), shape(), and tightBoundingBox().

1886 {
1887  QFontEngine *engine = 0;
1888  QFontEngine *scaledEngine = 0;
1889  int script = si.analysis.script;
1890 
1891  QFont font = fnt;
1892  if (hasFormats()) {
1894  engine = feCache.prevFontEngine;
1895  scaledEngine = feCache.prevScaledFontEngine;
1896  } else {
1897  QTextCharFormat f = format(&si);
1898  font = f.font();
1899 
1900  if (block.docHandle() && block.docHandle()->layout()) {
1901  // Make sure we get the right dpi on printers
1902  QPaintDevice *pdev = block.docHandle()->layout()->paintDevice();
1903  if (pdev)
1904  font = QFont(font, pdev);
1905  } else {
1906  font = font.resolve(fnt);
1907  }
1908  engine = font.d->engineForScript(script);
1911  if (font.pointSize() != -1)
1912  font.setPointSize((font.pointSize() * 2) / 3);
1913  else
1914  font.setPixelSize((font.pixelSize() * 2) / 3);
1915  scaledEngine = font.d->engineForScript(script);
1916  }
1917  if (engine)
1918  engine->ref.ref();
1919  if (feCache.prevFontEngine)
1921  feCache.prevFontEngine = engine;
1922 
1923  if (scaledEngine)
1924  scaledEngine->ref.ref();
1927  feCache.prevScaledFontEngine = scaledEngine;
1930  feCache.prevLength = length(&si);
1931  }
1932  } else {
1933  if (feCache.prevFontEngine && feCache.prevScript == script && feCache.prevPosition == -1)
1934  engine = feCache.prevFontEngine;
1935  else {
1936  engine = font.d->engineForScript(script);
1937  if (engine)
1938  engine->ref.ref();
1939  if (feCache.prevFontEngine)
1941  feCache.prevFontEngine = engine;
1943  feCache.prevPosition = -1;
1944  feCache.prevLength = -1;
1946  }
1947  }
1948 
1950  QFontPrivate *p = font.d->smallCapsFontPrivate();
1951  scaledEngine = p->engineForScript(script);
1952  }
1953 
1954  if (ascent) {
1955  *ascent = engine->ascent();
1956  *descent = engine->descent();
1957  *leading = engine->leading();
1958  }
1959 
1960  if (scaledEngine)
1961  return scaledEngine;
1962  return engine;
1963 }
QAtomicInt ref
QTextCharFormat format(const QScriptItem *si) const
void setPointSize(int)
Sets the point size to pointSize.
Definition: qfont.cpp:1099
QFont font() const
Returns the font for this character format.
The QTextCharFormat class provides formatting information for characters in a QTextDocument.
Definition: qtextformat.h:372
int pixelSize() const
Returns the pixel size of the font if it was set with setPixelSize().
Definition: qfont.cpp:1178
QAbstractTextDocumentLayout * layout() const
bool ref()
Atomically increments the value of this QAtomicInt.
bool hasFormats() const
QFontPrivate * smallCapsFontPrivate() const
Definition: qfont.cpp:323
QFont font() const
QFont resolve(const QFont &) const
Returns a new QFont that has attributes copied from other that have not been previously set on this f...
Definition: qfont.cpp:1983
VerticalAlignment
This enum describes the ways that adjacent characters can be vertically aligned.
Definition: qtextformat.h:375
FontEngineCache feCache
virtual QFixed ascent() const =0
virtual QFixed descent() const =0
Q_CORE_EXPORT int QT_FASTCALL script(uint ucs4)
QFontEngine * engineForScript(int script) const
Definition: qfont.cpp:294
unsigned short flags
QTextBlock block
VerticalAlignment verticalAlignment() const
Returns the vertical alignment used for characters with this format.
Definition: qtextformat.h:486
unsigned short script
The QFont class specifies a font used for drawing text.
Definition: qfont.h:64
QExplicitlySharedDataPointer< QFontPrivate > d
Definition: qfont.h:343
int length(int item) const
QPaintDevice * paintDevice() const
Returns the paint device used to render the document&#39;s layout.
int pointSize() const
Returns the point size of the font.
Definition: qfont.cpp:981
QTextDocumentPrivate * docHandle() const
Definition: qtextobject.h:283
void setPixelSize(int)
Sets the font size to pixelSize pixels.
Definition: qfont.cpp:1156
QFontEngine * prevScaledFontEngine
virtual QFixed leading() const =0
static void releaseCachedFontEngine(QFontEngine *fontEngine)
QScriptAnalysis analysis

◆ format()

QTextCharFormat QTextEngine::format ( const QScriptItem si) const

Definition at line 2362 of file qtextengine.cpp.

Referenced by QTextLine::draw(), font(), fontEngine(), resolveAdditionalFormats(), and shape().

2363 {
2365  const QTextFormatCollection *formats = 0;
2366  if (block.docHandle()) {
2367  formats = this->formats();
2368  format = formats->charFormat(formatIndex(si));
2369  }
2371  int end = si->position + length(si);
2372  for (int i = 0; i < specialData->addFormats.size(); ++i) {
2374  if (r.start <= si->position && r.start + r.length >= end) {
2376  format.merge(formats->format(specialData->addFormatIndices.at(i)));
2377  else
2378  format.merge(r.format);
2379  }
2380  }
2381  }
2382  return format;
2383 }
QTextCharFormat format(const QScriptItem *si) const
QTextCharFormat charFormat(int index) const
Definition: qtextformat_p.h:85
The QTextLayout::FormatRange structure is used to apply extra formatting information for a specified ...
Definition: qtextlayout.h:128
The QTextCharFormat class provides formatting information for characters in a QTextDocument.
Definition: qtextformat.h:372
SpecialData * specialData
int start
Specifies the beginning of the format range within the text layout&#39;s text.
Definition: qtextlayout.h:129
QTextFormat format(int idx) const
QList< QTextLayout::FormatRange > addFormats
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
QTextBlock block
void merge(const QTextFormat &other)
Merges the other format with this format; where there are conflicts the other format takes precedence...
QVector< int > addFormatIndices
QVector< int > resolvedFormatIndices
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
int length(int item) const
int formatIndex(const QScriptItem *si) const
int length
Specifies the numer of characters the format range spans.
Definition: qtextlayout.h:130
QTextCharFormat format
Specifies the format to apply.
Definition: qtextlayout.h:131
bool isEmpty() const
Returns true if the vector has size 0; otherwise returns false.
Definition: qvector.h:139
QTextDocumentPrivate * docHandle() const
Definition: qtextobject.h:283
static const KeyPair *const end
QTextFormatCollection * formats() const

◆ formatIndex()

int QTextEngine::formatIndex ( const QScriptItem si) const

Definition at line 2343 of file qtextengine.cpp.

Referenced by QTextInlineObject::format(), format(), QTextInlineObject::formatIndex(), QTextLine::layout_helper(), and shape().

2344 {
2348  if (!p)
2349  return -1;
2350  int pos = si->position;
2353  pos = qMax(specialData->preeditPosition - 1, 0);
2354  else
2355  pos -= specialData->preeditText.length();
2356  }
2358  return it.value()->format;
2359 }
#define it(className, varName)
SpecialData * specialData
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
QScriptItemArray items
LayoutData * layoutData
FragmentMap::ConstIterator FragmentIterator
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
int position() const
Returns the index of the block&#39;s first character within the document.
FragmentIterator find(int pos) const
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
QTextBlock block
QVector< int > resolvedFormatIndices
bool isEmpty() const
Returns true if the vector has size 0; otherwise returns false.
Definition: qvector.h:139
QTextDocumentPrivate * docHandle() const
Definition: qtextobject.h:283

◆ formats()

QTextFormatCollection* QTextEngine::formats ( ) const
inline

Definition at line 542 of file qtextengine_p.h.

Referenced by QTextInlineObject::format(), format(), indexAdditionalFormats(), itemize(), QTextLine::layout_helper(), resolveAdditionalFormats(), and shape().

542  {
543 #ifdef QT_BUILD_COMPAT_LIB
544  return 0; // Compat should never reference this symbol
545 #else
546  return block.docHandle()->formatCollection();
547 #endif
548  }
QTextFormatCollection * formatCollection()
QTextBlock block
QTextDocumentPrivate * docHandle() const
Definition: qtextobject.h:283

◆ freeMemory()

void QTextEngine::freeMemory ( )

Definition at line 2326 of file qtextengine.cpp.

Referenced by invalidate().

2327 {
2328  if (!stackEngine) {
2329  delete layoutData;
2330  layoutData = 0;
2331  } else {
2332  layoutData->used = 0;
2333  layoutData->hasBidi = false;
2335  layoutData->haveCharAttributes = false;
2336  }
2337  for (int i = 0; i < lines.size(); ++i) {
2338  lines[i].justified = 0;
2339  lines[i].gridfitted = 0;
2340  }
2341 }
LayoutData * layoutData
QScriptLineArray lines
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137

◆ getClusterLength()

int QTextEngine::getClusterLength ( unsigned short *  logClusters,
const HB_CharAttributes *  attributes,
int  from,
int  to,
int  glyph_pos,
int *  start 
)
private

Definition at line 2880 of file qtextengine.cpp.

Referenced by positionInLigature().

2883 {
2884  int clusterLength = 0;
2885  for (int i = from; i < to; i++) {
2886  if (logClusters[i] == glyph_pos && attributes[i].charStop) {
2887  if (*start < 0)
2888  *start = i;
2889  clusterLength++;
2890  }
2891  else if (clusterLength)
2892  break;
2893  }
2894  return clusterLength;
2895 }
unsigned short * logClusters(const QScriptItem *si) const
const HB_CharAttributes * attributes() const

◆ hasFormats()

bool QTextEngine::hasFormats ( ) const
inline

Definition at line 600 of file qtextengine_p.h.

Referenced by QTextLine::draw(), font(), and fontEngine().

600 { return (block.docHandle() || specialData); }
SpecialData * specialData
QTextBlock block
QTextDocumentPrivate * docHandle() const
Definition: qtextobject.h:283

◆ indexAdditionalFormats()

void QTextEngine::indexAdditionalFormats ( )

Definition at line 2449 of file qtextengine.cpp.

2450 {
2451  if (!block.docHandle())
2452  return;
2453 
2455  QTextFormatCollection * const formats = this->formats();
2456 
2457  for (int i = 0; i < specialData->addFormats.count(); ++i) {
2459  specialData->addFormats[i].format = QTextCharFormat();
2460  }
2461 }
The QTextCharFormat class provides formatting information for characters in a QTextDocument.
Definition: qtextformat.h:372
SpecialData * specialData
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
QList< QTextLayout::FormatRange > addFormats
void resize(int size)
Sets the size of the vector to size.
Definition: qvector.h:342
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
QTextBlock block
QVector< int > addFormatIndices
QTextCharFormat format
Specifies the format to apply.
Definition: qtextlayout.h:131
QTextDocumentPrivate * docHandle() const
Definition: qtextobject.h:283
QTextFormatCollection * formats() const
int indexForFormat(const QTextFormat &f)

◆ insertionPointsForLine()

void QTextEngine::insertionPointsForLine ( int  lineNum,
QVector< int > &  insertionPoints 
)

Definition at line 2994 of file qtextengine.cpp.

Referenced by beginningOfLine(), endOfLine(), positionAfterVisualMovement(), and QTextLine::xToCursor().

2995 {
2996  QTextLineItemIterator iterator(this, lineNum);
2997  bool rtl = isRightToLeft();
2998  bool lastLine = lineNum >= lines.size() - 1;
2999 
3000  while (!iterator.atEnd()) {
3001  iterator.next();
3002  const QScriptItem *si = &layoutData->items[iterator.item];
3003  if (si->analysis.bidiLevel % 2) {
3004  int i = iterator.itemEnd - 1, min = iterator.itemStart;
3005  if (lastLine && (rtl ? iterator.atBeginning() : iterator.atEnd()))
3006  i++;
3007  for (; i >= min; i--)
3008  insertionPoints.push_back(i);
3009  } else {
3010  int i = iterator.itemStart, max = iterator.itemEnd;
3011  if (lastLine && (rtl ? iterator.atBeginning() : iterator.atEnd()))
3012  max++;
3013  for (; i < max; i++)
3014  insertionPoints.push_back(i);
3015  }
3016  }
3017 }
bool isRightToLeft() const
QScriptItemArray items
LayoutData * layoutData
unsigned short bidiLevel
QScriptLineArray lines
void push_back(const T &t)
This function is provided for STL compatibility.
Definition: qvector.h:281
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
QScriptAnalysis analysis

◆ invalidate()

void QTextEngine::invalidate ( )

Definition at line 1470 of file qtextengine.cpp.

Referenced by QTextBlockData::invalidate().

1471 {
1472  freeMemory();
1473  minWidth = 0;
1474  maxWidth = 0;
1475  if (specialData)
1477 
1479 }
SpecialData * specialData
void clear()
Removes all the elements from the vector and releases the memory used by the vector.
Definition: qvector.h:347
void resetFontEngineCache()
QFixed maxWidth
QVector< int > resolvedFormatIndices
void freeMemory()
QFixed minWidth

◆ isRightToLeft()

bool QTextEngine::isRightToLeft ( ) const

Definition at line 1636 of file qtextengine.cpp.

Referenced by alignLine(), calculateTabWidth(), QTextLine::cursorToX(), insertionPointsForLine(), itemize(), leadingSpaceWidth(), positionAfterVisualMovement(), and QTextLine::xToCursor().

1637 {
1638  switch (option.textDirection()) {
1639  case Qt::LeftToRight:
1640  return false;
1641  case Qt::RightToLeft:
1642  return true;
1643  default:
1644  break;
1645  }
1646  if (!layoutData)
1647  itemize();
1648  // this places the cursor in the right position depending on the keyboard layout
1649  if (layoutData->string.isEmpty())
1651  return layoutData->string.isRightToLeft();
1652 }
LayoutData * layoutData
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
bool isRightToLeft() const
Returns true if the string is read right to left.
Definition: qstring.cpp:7528
void itemize() const
QTextOption option
Qt::LayoutDirection textDirection() const
Returns the direction of the text layout defined by the option.
Definition: qtextoption.h:100
static Qt::LayoutDirection keyboardInputDirection()
Returns the current keyboard input direction.

◆ itemize()

void QTextEngine::itemize ( ) const

Definition at line 1502 of file qtextengine.cpp.

Referenced by attributes(), boundingBox(), QTextLine::cursorToX(), QPainter::drawText(), elidedText(), findItem(), isRightToLeft(), justify(), lineNumberForTextPosition(), positionAfterVisualMovement(), tightBoundingBox(), width(), and QTextLine::xToCursor().

1503 {
1504  validate();
1505  if (layoutData->items.size())
1506  return;
1507 
1508  int length = layoutData->string.length();
1509  if (!length)
1510  return;
1511 #if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
1512  // ATSUI requires RTL flags to correctly identify the character stops.
1513  bool ignore = false;
1514 #else
1515  bool ignore = ignoreBidi;
1516 #endif
1517 
1518  bool rtl = isRightToLeft();
1519 
1520  if (!ignore && !rtl) {
1521  ignore = true;
1522  const QChar *start = layoutData->string.unicode();
1523  const QChar * const end = start + length;
1524  while (start < end) {
1525  if (start->unicode() >= 0x590) {
1526  ignore = false;
1527  break;
1528  }
1529  ++start;
1530  }
1531  }
1532 
1533  QVarLengthArray<QScriptAnalysis, 4096> scriptAnalysis(length);
1534  QScriptAnalysis *analysis = scriptAnalysis.data();
1535 
1536  QBidiControl control(rtl);
1537 
1538  if (ignore) {
1539  memset(analysis, 0, length*sizeof(QScriptAnalysis));
1541  for (int i = 0; i < length; ++i)
1542  analysis[i].bidiLevel = 1;
1543  layoutData->hasBidi = true;
1544  }
1545  } else {
1546  layoutData->hasBidi = bidiItemize(const_cast<QTextEngine *>(this), analysis, control);
1547  }
1548 
1549  const ushort *uc = reinterpret_cast<const ushort *>(layoutData->string.unicode());
1550  const ushort *e = uc + length;
1551  int lastScript = QUnicodeTables::Common;
1552  while (uc < e) {
1553  switch (*uc) {
1555  analysis->script = QUnicodeTables::Common;
1556  analysis->flags = QScriptAnalysis::Object;
1557  break;
1558  case QChar::LineSeparator:
1559  if (analysis->bidiLevel % 2)
1560  --analysis->bidiLevel;
1561  analysis->script = QUnicodeTables::Common;
1564  *const_cast<ushort*>(uc) = 0x21B5; // visual line separator
1565  break;
1566  case 9: // Tab
1567  analysis->script = QUnicodeTables::Common;
1568  analysis->flags = QScriptAnalysis::Tab;
1569  analysis->bidiLevel = control.baseLevel();
1570  break;
1571  case 32: // Space
1572  case QChar::Nbsp:
1574  analysis->script = QUnicodeTables::Common;
1575  analysis->flags = QScriptAnalysis::Space;
1576  analysis->bidiLevel = control.baseLevel();
1577  break;
1578  }
1579  // fall through
1580  default:
1581  int script = QUnicodeTables::script(*uc);
1582  analysis->script = script == QUnicodeTables::Inherited ? lastScript : script;
1583  analysis->flags = QScriptAnalysis::None;
1584  break;
1585  }
1586  lastScript = analysis->script;
1587  ++uc;
1588  ++analysis;
1589  }
1591  (analysis-1)->flags = QScriptAnalysis::LineOrParagraphSeparator; // to exclude it from width
1592  }
1593 
1594  Itemizer itemizer(layoutData->string, scriptAnalysis.data(), layoutData->items);
1595 
1596  const QTextDocumentPrivate *p = block.docHandle();
1597  if (p) {
1598  SpecialData *s = specialData;
1599 
1601  QTextDocumentPrivate::FragmentIterator end = p->find(block.position() + block.length() - 1); // -1 to omit the block separator char
1602  int format = it.value()->format;
1603 
1604  int prevPosition = 0;
1605  int position = prevPosition;
1606  while (1) {
1607  const QTextFragmentData * const frag = it.value();
1608  if (it == end || format != frag->format) {
1609  if (s && position >= s->preeditPosition) {
1610  position += s->preeditText.length();
1611  s = 0;
1612  }
1613  Q_ASSERT(position <= length);
1614  itemizer.generate(prevPosition, position - prevPosition,
1615  formats()->charFormat(format).fontCapitalization());
1616  if (it == end) {
1617  if (position < length)
1618  itemizer.generate(position, length - position,
1619  formats()->charFormat(format).fontCapitalization());
1620  break;
1621  }
1622  format = frag->format;
1623  prevPosition = position;
1624  }
1625  position += frag->size_array[0];
1626  ++it;
1627  }
1628  } else {
1629  itemizer.generate(0, length, static_cast<QFont::Capitalization> (fnt.d->capital));
1630  }
1631 
1634 }
bool isRightToLeft() const
ushort unicode() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qchar.h:251
#define it(className, varName)
SpecialData * specialData
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
Flags flags() const
Returns the flags associated with the option.
Definition: qtextoption.h:121
static bool ignore(const char *test, const char *const *table)
Definition: qaxserver.cpp:660
QScriptItemArray items
LayoutData * layoutData
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
void addRequiredBoundaries() const
void validate() const
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
QChar * data()
Returns a pointer to the data stored in the QString.
Definition: qstring.h:710
FragmentMap::ConstIterator FragmentIterator
int position() const
Returns the index of the block&#39;s first character within the document.
const QChar * unicode() const
Returns a &#39;\0&#39;-terminated Unicode representation of the string.
Definition: qstring.h:706
uint capital
Definition: qfont_p.h:192
unsigned short bidiLevel
int length() const
Returns the length of the block in characters.
QTextOption option
Q_CORE_EXPORT int QT_FASTCALL script(uint ucs4)
unsigned short flags
QTextBlock block
static bool bidiItemize(QTextEngine *engine, QScriptAnalysis *analysis, QBidiControl &control)
unsigned short script
unsigned short ushort
Definition: qglobal.h:995
Qt::LayoutDirection textDirection() const
Returns the direction of the text layout defined by the option.
Definition: qtextoption.h:100
quint32 size_array[N]
QPointF position
QExplicitlySharedDataPointer< QFontPrivate > d
Definition: qfont.h:343
int length(int item) const
QTextDocumentPrivate * docHandle() const
Definition: qtextobject.h:283
static const KeyPair *const end
QTextFormatCollection * formats() const
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
void resolveAdditionalFormats() const

◆ justify()

void QTextEngine::justify ( const QScriptLine si)

Definition at line 1995 of file qtextengine.cpp.

Referenced by alignLine(), and QPainter::drawText().

1996 {
1997 // qDebug("justify: line.gridfitted = %d, line.justified=%d", line.gridfitted, line.justified);
1998  if (line.gridfitted && line.justified)
1999  return;
2000 
2001  if (!line.gridfitted) {
2002  // redo layout in device metrics, then adjust
2003  const_cast<QScriptLine &>(line).gridfitted = true;
2004  }
2005 
2007  return;
2008 
2009  itemize();
2010 
2011  if (!forceJustification) {
2012  int end = line.from + (int)line.length;
2013  if (end == layoutData->string.length())
2014  return; // no justification at end of paragraph
2015  if (end && layoutData->items[findItem(end-1)].analysis.flags == QScriptAnalysis::LineOrParagraphSeparator)
2016  return; // no justification at the end of an explicitly separated line
2017  }
2018 
2019  // justify line
2020  int maxJustify = 0;
2021 
2022  // don't include trailing white spaces when doing justification
2023  int line_length = line.length;
2024  const HB_CharAttributes *a = attributes();
2025  if (! a)
2026  return;
2027  a += line.from;
2028  while (line_length && a[line_length-1].whiteSpace)
2029  --line_length;
2030  // subtract one char more, as we can't justfy after the last character
2031  --line_length;
2032 
2033  if (!line_length)
2034  return;
2035 
2036  int firstItem = findItem(line.from);
2037  int nItems = findItem(line.from + line_length - 1) - firstItem + 1;
2038 
2039  QVarLengthArray<QJustificationPoint> justificationPoints;
2040  int nPoints = 0;
2041 // qDebug("justifying from %d len %d, firstItem=%d, nItems=%d (%s)", line.from, line_length, firstItem, nItems, layoutData->string.mid(line.from, line_length).toUtf8().constData());
2042  QFixed minKashida = 0x100000;
2043 
2044  // we need to do all shaping before we go into the next loop, as we there
2045  // store pointers to the glyph data that could get reallocated by the shaping
2046  // process.
2047  for (int i = 0; i < nItems; ++i) {
2048  QScriptItem &si = layoutData->items[firstItem + i];
2049  if (!si.num_glyphs)
2050  shape(firstItem + i);
2051  }
2052 
2053  for (int i = 0; i < nItems; ++i) {
2054  QScriptItem &si = layoutData->items[firstItem + i];
2055 
2056  int kashida_type = HB_Arabic_Normal;
2057  int kashida_pos = -1;
2058 
2059  int start = qMax(line.from - si.position, 0);
2060  int end = qMin(line.from + line_length - (int)si.position, length(firstItem+i));
2061 
2062  unsigned short *log_clusters = logClusters(&si);
2063 
2064  int gs = log_clusters[start];
2065  int ge = (end == length(firstItem+i) ? si.num_glyphs : log_clusters[end]);
2066 
2067  const QGlyphLayout g = shapedGlyphs(&si);
2068 
2069  for (int i = gs; i < ge; ++i) {
2071  g.justifications[i].nKashidas = 0;
2072  g.justifications[i].space_18d6 = 0;
2073 
2074  justificationPoints.resize(nPoints+3);
2075  int justification = g.attributes[i].justification;
2076 
2077  switch(justification) {
2078  case HB_NoJustification:
2079  break;
2080  case HB_Space :
2081  // fall through
2082  case HB_Arabic_Space :
2083  if (kashida_pos >= 0) {
2084 // qDebug("kashida position at %d in word", kashida_pos);
2085  set(&justificationPoints[nPoints], kashida_type, g.mid(kashida_pos), fontEngine(si));
2086  if (justificationPoints[nPoints].kashidaWidth > 0) {
2087  minKashida = qMin(minKashida, justificationPoints[nPoints].kashidaWidth);
2088  maxJustify = qMax(maxJustify, justificationPoints[nPoints].type);
2089  ++nPoints;
2090  }
2091  }
2092  kashida_pos = -1;
2093  kashida_type = HB_Arabic_Normal;
2094  // fall through
2095  case HB_Character :
2096  set(&justificationPoints[nPoints++], justification, g.mid(i), fontEngine(si));
2097  maxJustify = qMax(maxJustify, justification);
2098  break;
2099  case HB_Arabic_Normal :
2100  case HB_Arabic_Waw :
2101  case HB_Arabic_BaRa :
2102  case HB_Arabic_Alef :
2103  case HB_Arabic_HaaDal :
2104  case HB_Arabic_Seen :
2105  case HB_Arabic_Kashida :
2106  if (justification >= kashida_type) {
2107  kashida_pos = i;
2108  kashida_type = justification;
2109  }
2110  }
2111  }
2112  if (kashida_pos >= 0) {
2113  set(&justificationPoints[nPoints], kashida_type, g.mid(kashida_pos), fontEngine(si));
2114  if (justificationPoints[nPoints].kashidaWidth > 0) {
2115  minKashida = qMin(minKashida, justificationPoints[nPoints].kashidaWidth);
2116  maxJustify = qMax(maxJustify, justificationPoints[nPoints].type);
2117  ++nPoints;
2118  }
2119  }
2120  }
2121 
2122  QFixed leading = leadingSpaceWidth(line);
2123  QFixed need = line.width - line.textWidth - leading;
2124  if (need < 0) {
2125  // line overflows already!
2126  const_cast<QScriptLine &>(line).justified = true;
2127  return;
2128  }
2129 
2130 // qDebug("doing justification: textWidth=%x, requested=%x, maxJustify=%d", line.textWidth.value(), line.width.value(), maxJustify);
2131 // qDebug(" minKashida=%f, need=%f", minKashida.toReal(), need.toReal());
2132 
2133  // distribute in priority order
2134  if (maxJustify >= HB_Arabic_Normal) {
2135  while (need >= minKashida) {
2136  for (int type = maxJustify; need >= minKashida && type >= HB_Arabic_Normal; --type) {
2137  for (int i = 0; need >= minKashida && i < nPoints; ++i) {
2138  if (justificationPoints[i].type == type && justificationPoints[i].kashidaWidth <= need) {
2139  justificationPoints[i].glyph.justifications->nKashidas++;
2140  // ############
2141  justificationPoints[i].glyph.justifications->space_18d6 += justificationPoints[i].kashidaWidth.value();
2142  need -= justificationPoints[i].kashidaWidth;
2143 // qDebug("adding kashida type %d with width %x, neednow %x", type, justificationPoints[i].kashidaWidth, need.value());
2144  }
2145  }
2146  }
2147  }
2148  }
2149  Q_ASSERT(need >= 0);
2150  if (!need)
2151  goto end;
2152 
2153  maxJustify = qMin(maxJustify, (int)HB_Space);
2154  for (int type = maxJustify; need != 0 && type > 0; --type) {
2155  int n = 0;
2156  for (int i = 0; i < nPoints; ++i) {
2157  if (justificationPoints[i].type == type)
2158  ++n;
2159  }
2160 // qDebug("number of points for justification type %d: %d", type, n);
2161 
2162 
2163  if (!n)
2164  continue;
2165 
2166  for (int i = 0; i < nPoints; ++i) {
2167  if (justificationPoints[i].type == type) {
2168  QFixed add = need/n;
2169 // qDebug("adding %x to glyph %x", add.value(), justificationPoints[i].glyph->glyph);
2170  justificationPoints[i].glyph.justifications[0].space_18d6 = add.value();
2171  need -= add;
2172  --n;
2173  }
2174  }
2175 
2176  Q_ASSERT(!need);
2177  }
2178  end:
2179  const_cast<QScriptLine &>(line).justified = true;
2180 }
void resize(int size)
QGlyphJustification * justifications
int type
Definition: qmetatype.cpp:239
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
int value() const
Definition: qfixed_p.h:73
#define add(aName)
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
int findItem(int strPos) const
QFontEngine * fontEngine(const QScriptItem &si, QFixed *ascent=0, QFixed *descent=0, QFixed *leading=0) const
QScriptItemArray items
long ASN1_INTEGER_get ASN1_INTEGER * a
LayoutData * layoutData
unsigned short * logClusters(const QScriptItem *si) const
QGlyphLayout mid(int position, int n=-1) const
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
uint forceJustification
const HB_CharAttributes * attributes() const
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
QGlyphLayout shapedGlyphs(const QScriptItem *si) const
unsigned short num_glyphs
void itemize() const
QTextOption option
T value(int i) const
void shape(int item) const
int length(int item) const
if(void) toggleToolbarShown
Qt::Alignment alignment() const
Returns the text alignment defined by the option.
Definition: qtextoption.h:97
HB_GlyphAttributes * attributes
static const KeyPair *const end
QFixed leadingSpaceWidth(const QScriptLine &line)

◆ leadingSpaceWidth()

QFixed QTextEngine::leadingSpaceWidth ( const QScriptLine line)

Definition at line 2822 of file qtextengine.cpp.

Referenced by QTextLine::cursorToX(), justify(), and qt_format_text().

2823 {
2824  if (!line.hasTrailingSpaces
2826  || !isRightToLeft())
2827  return QFixed();
2828 
2829  return width(line.from + line.length, line.trailingSpaces);
2830 }
bool isRightToLeft() const
unsigned short trailingSpaces
Flags flags() const
Returns the flags associated with the option.
Definition: qtextoption.h:121
uint hasTrailingSpaces
QTextOption option
signed int length
QFixed width(int charFrom, int numChars) const

◆ length() [1/2]

int QTextEngine::length ( int  item) const
inline

◆ length() [2/2]

int QTextEngine::length ( const QScriptItem si) const
inline

Definition at line 490 of file qtextengine_p.h.

490  {
491  int end;
492  if (si + 1 < layoutData->items.constData()+ layoutData->items.size())
493  end = (si+1)->position;
494  else
495  end = layoutData->string.length();
496  return end - si->position;
497  }
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
QScriptItemArray items
LayoutData * layoutData
const T * constData() const
Returns a const pointer to the data stored in the vector.
Definition: qvector.h:154
static const KeyPair *const end
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137

◆ lineNumberForTextPosition()

int QTextEngine::lineNumberForTextPosition ( int  pos)

Definition at line 2980 of file qtextengine.cpp.

Referenced by positionAfterVisualMovement().

2981 {
2982  if (!layoutData)
2983  itemize();
2984  if (pos == layoutData->string.length() && lines.size())
2985  return lines.size() - 1;
2986  for (int i = 0; i < lines.size(); ++i) {
2987  const QScriptLine& line = lines[i];
2988  if (line.from + line.length + line.trailingSpaces > pos)
2989  return i;
2990  }
2991  return -1;
2992 }
unsigned short trailingSpaces
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
LayoutData * layoutData
QScriptLineArray lines
void itemize() const
signed int length
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137

◆ logClusters()

unsigned short* QTextEngine::logClusters ( const QScriptItem si) const
inline

Returns a pointer to an array of log clusters, offset at the script item. Each item in the array is a unsigned short. For each character in the original string there is an entry in the table so there is a one to one correlation in indexes between the original text and the index in the logcluster. The value of each item is the position in the glyphs array. Multiple similar pointers in the logclusters array imply that one glyph is used for more than one character.

See also
glyphs()

Definition at line 511 of file qtextengine_p.h.

Referenced by boundingBox(), QTextLine::cursorToX(), QTextLine::draw(), drawMenuText(), QPainter::drawText(), elidedText(), QTextLineItemIterator::getSelectionBounds(), justify(), QTextLineItemIterator::next(), offsetInLigature(), positionInLigature(), splitItem(), tightBoundingBox(), width(), and QTextLine::xToCursor().

512  { return layoutData->logClustersPtr+si->position; }
LayoutData * layoutData
unsigned short * logClustersPtr

◆ nextLogicalPosition()

int QTextEngine::nextLogicalPosition ( int  oldPos) const

Definition at line 2965 of file qtextengine.cpp.

Referenced by positionAfterVisualMovement().

2966 {
2967  const HB_CharAttributes *attrs = attributes();
2968  int len = block.isValid() ? block.length() - 1
2969  : layoutData->string.length();
2970  Q_ASSERT(len <= layoutData->string.length());
2971  if (!attrs || oldPos < 0 || oldPos >= len)
2972  return oldPos;
2973 
2974  oldPos++;
2975  while (oldPos < len && !attrs[oldPos].charStop)
2976  oldPos++;
2977  return oldPos;
2978 }
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
LayoutData * layoutData
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
const HB_CharAttributes * attributes() const
int length() const
Returns the length of the block in characters.
QTextBlock block
int length(int item) const
bool isValid() const
Returns true if this text block is valid; otherwise returns false.
Definition: qtextobject.h:208

◆ offsetInLigature()

QFixed QTextEngine::offsetInLigature ( const QScriptItem si,
int  pos,
int  max,
int  glyph_pos 
)

Definition at line 2849 of file qtextengine.cpp.

Referenced by QTextLine::cursorToX(), and QTextLineItemIterator::getSelectionBounds().

2850 {
2851  unsigned short *logClusters = this->logClusters(si);
2852  const QGlyphLayout &glyphs = shapedGlyphs(si);
2853 
2854  int offsetInCluster = 0;
2855  for (int i = pos - 1; i >= 0; i--) {
2856  if (logClusters[i] == glyph_pos)
2857  offsetInCluster++;
2858  else
2859  break;
2860  }
2861 
2862  // in the case that the offset is inside a (multi-character) glyph,
2863  // interpolate the position.
2864  if (offsetInCluster > 0) {
2865  int clusterLength = 0;
2866  for (int i = pos - offsetInCluster; i < max; i++) {
2867  if (logClusters[i] == glyph_pos)
2868  clusterLength++;
2869  else
2870  break;
2871  }
2872  if (clusterLength)
2873  return glyphs.advances_x[glyph_pos] * offsetInCluster / clusterLength;
2874  }
2875 
2876  return 0;
2877 }
QFixed * advances_x
unsigned short * logClusters(const QScriptItem *si) const
QGlyphLayout shapedGlyphs(const QScriptItem *si) const

◆ positionAfterVisualMovement()

int QTextEngine::positionAfterVisualMovement ( int  oldPos,
QTextCursor::MoveOperation  op 
)

Definition at line 3039 of file qtextengine.cpp.

3040 {
3041  if (!layoutData)
3042  itemize();
3043 
3044  bool moveRight = (op == QTextCursor::Right);
3045  bool alignRight = isRightToLeft();
3046  if (!layoutData->hasBidi)
3047  return moveRight ^ alignRight ? nextLogicalPosition(pos) : previousLogicalPosition(pos);
3048 
3049  int lineNum = lineNumberForTextPosition(pos);
3050  Q_ASSERT(lineNum >= 0);
3051 
3052  QVector<int> insertionPoints;
3053  insertionPointsForLine(lineNum, insertionPoints);
3054  int i, max = insertionPoints.size();
3055  for (i = 0; i < max; i++)
3056  if (pos == insertionPoints[i]) {
3057  if (moveRight) {
3058  if (i + 1 < max)
3059  return insertionPoints[i + 1];
3060  } else {
3061  if (i > 0)
3062  return insertionPoints[i - 1];
3063  }
3064 
3065  if (moveRight ^ alignRight) {
3066  if (lineNum + 1 < lines.size())
3067  return alignRight ? endOfLine(lineNum + 1) : beginningOfLine(lineNum + 1);
3068  }
3069  else {
3070  if (lineNum > 0)
3071  return alignRight ? beginningOfLine(lineNum - 1) : endOfLine(lineNum - 1);
3072  }
3073  }
3074 
3075  return pos;
3076 }
bool isRightToLeft() const
int lineNumberForTextPosition(int pos)
void insertionPointsForLine(int lineNum, QVector< int > &insertionPoints)
int endOfLine(int lineNum)
LayoutData * layoutData
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QScriptLineArray lines
void itemize() const
int previousLogicalPosition(int oldPos) const
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
int beginningOfLine(int lineNum)
int nextLogicalPosition(int oldPos) const

◆ positionInLigature()

int QTextEngine::positionInLigature ( const QScriptItem si,
int  end,
QFixed  x,
QFixed  edge,
int  glyph_pos,
bool  cursorOnCharacter 
)

Definition at line 2897 of file qtextengine.cpp.

Referenced by QTextLine::xToCursor().

2900 {
2901  unsigned short *logClusters = this->logClusters(si);
2902  int clusterStart = -1;
2903  int clusterLength = 0;
2904 
2905  if (si->analysis.script != QUnicodeTables::Common &&
2907  if (glyph_pos == -1)
2908  return si->position + end;
2909  else {
2910  int i;
2911  for (i = 0; i < end; i++)
2912  if (logClusters[i] == glyph_pos)
2913  break;
2914  return si->position + i;
2915  }
2916  }
2917 
2918  if (glyph_pos == -1 && end > 0)
2919  glyph_pos = logClusters[end - 1];
2920  else {
2921  if (x <= edge)
2922  glyph_pos--;
2923  }
2924 
2925  const HB_CharAttributes *attrs = attributes();
2926  logClusters = this->logClusters(si);
2927  clusterLength = getClusterLength(logClusters, attrs, 0, end, glyph_pos, &clusterStart);
2928 
2929  if (clusterLength) {
2930  const QGlyphLayout &glyphs = shapedGlyphs(si);
2931  QFixed glyphWidth = glyphs.effectiveAdvance(glyph_pos);
2932  // the approximate width of each individual element of the ligature
2933  QFixed perItemWidth = glyphWidth / clusterLength;
2934  if (perItemWidth <= 0)
2935  return si->position + clusterStart;
2936  QFixed left = x > edge ? edge : edge - glyphWidth;
2937  int n = ((x - left) / perItemWidth).floor().toInt();
2938  QFixed dist = x - left - n * perItemWidth;
2939  int closestItem = dist > (perItemWidth / 2) ? n + 1 : n;
2940  if (cursorOnCharacter && closestItem > 0)
2941  closestItem--;
2942  int pos = si->position + clusterStart + closestItem;
2943  // Jump to the next charStop
2944  while (pos < end && !attrs[pos].charStop)
2945  pos++;
2946  return pos;
2947  }
2948  return si->position + end;
2949 }
int getClusterLength(unsigned short *logClusters, const HB_CharAttributes *attributes, int from, int to, int glyph_pos, int *start)
unsigned short * logClusters(const QScriptItem *si) const
const HB_CharAttributes * attributes() const
QFixed floor() const
Definition: qfixed_p.h:81
QGlyphLayout shapedGlyphs(const QScriptItem *si) const
int toInt() const
Definition: qfixed_p.h:76
unsigned short script
QFixed effectiveAdvance(int item) const
static const KeyPair *const end
Q_CORE_EXPORT QTextStream & left(QTextStream &s)
QScriptAnalysis analysis

◆ previousLogicalPosition()

int QTextEngine::previousLogicalPosition ( int  oldPos) const

Definition at line 2951 of file qtextengine.cpp.

Referenced by positionAfterVisualMovement().

2952 {
2953  const HB_CharAttributes *attrs = attributes();
2954  if (!attrs || oldPos < 0)
2955  return oldPos;
2956 
2957  if (oldPos <= 0)
2958  return 0;
2959  oldPos--;
2960  while (oldPos && !attrs[oldPos].charStop)
2961  oldPos--;
2962  return oldPos;
2963 }
const HB_CharAttributes * attributes() const

◆ resetFontEngineCache()

void QTextEngine::resetFontEngineCache ( )

Definition at line 1463 of file qtextengine.cpp.

Referenced by invalidate(), and ~QTextEngine().

1464 {
1467  feCache.reset();
1468 }
FontEngineCache feCache
QFontEngine * prevScaledFontEngine
static void releaseCachedFontEngine(QFontEngine *fontEngine)

◆ resolveAdditionalFormats()

void QTextEngine::resolveAdditionalFormats ( ) const
private

Definition at line 2804 of file qtextengine.cpp.

Referenced by itemize().

2805 {
2807  || !block.docHandle()
2809  return;
2810 
2811  QTextFormatCollection *collection = this->formats();
2812 
2814  QVector<int> indices(layoutData->items.count());
2815  for (int i = 0; i < layoutData->items.count(); ++i) {
2817  indices[i] = collection->indexForFormat(f);
2818  }
2820 }
QTextCharFormat format(const QScriptItem *si) const
The QTextCharFormat class provides formatting information for characters in a QTextDocument.
Definition: qtextformat.h:372
int count(const T &t) const
Returns the number of occurrences of value in the vector.
Definition: qvector.h:742
SpecialData * specialData
QScriptItemArray items
LayoutData * layoutData
QList< QTextLayout::FormatRange > addFormats
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
void clear()
Removes all the elements from the vector and releases the memory used by the vector.
Definition: qvector.h:347
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
QTextBlock block
QVector< int > resolvedFormatIndices
bool isEmpty() const
Returns true if the vector has size 0; otherwise returns false.
Definition: qvector.h:139
QTextDocumentPrivate * docHandle() const
Definition: qtextobject.h:283
QTextFormatCollection * formats() const
int indexForFormat(const QTextFormat &f)

◆ setBoundary()

void QTextEngine::setBoundary ( int  strPos) const
private

Definition at line 2661 of file qtextengine.cpp.

Referenced by addRequiredBoundaries().

2662 {
2663  if (strPos <= 0 || strPos >= layoutData->string.length())
2664  return;
2665 
2667  strPos, QScriptItemComparator());
2669  --it;
2670  if (it->position == strPos) {
2671  // already a split at the requested position
2672  return;
2673  }
2674  splitItem(it - layoutData->items.constBegin(), strPos - it->position);
2675 }
Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
Definition: qalgorithms.h:262
#define it(className, varName)
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the vector...
Definition: qvector.h:252
QScriptItemArray items
LayoutData * layoutData
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the vector.
Definition: qvector.h:249
void splitItem(int item, int pos) const

◆ shape()

void QTextEngine::shape ( int  item) const

Definition at line 1434 of file qtextengine.cpp.

Referenced by boundingBox(), calculateTabWidth(), QTextLine::cursorToX(), elidedText(), justify(), QTextLine::layout_helper(), QTextLineItemIterator::next(), tightBoundingBox(), width(), and QTextLine::xToCursor().

1435 {
1436  if (layoutData->items[item].analysis.flags == QScriptAnalysis::Object) {
1437  ensureSpace(1);
1438  if (block.docHandle()) {
1440  docLayout()->resizeInlineObject(QTextInlineObject(item, const_cast<QTextEngine *>(this)),
1441  layoutData->items[item].position + block.position(), format);
1442  }
1443  } else if (layoutData->items[item].analysis.flags == QScriptAnalysis::Tab) {
1444  // set up at least the ascent/descent/leading of the script item for the tab
1445  fontEngine(layoutData->items[item],
1446  &layoutData->items[item].ascent,
1447  &layoutData->items[item].descent,
1448  &layoutData->items[item].leading);
1449  } else {
1450  shapeText(item);
1451  }
1452 }
QTextCharFormat format(const QScriptItem *si) const
virtual void resizeInlineObject(QTextInlineObject item, int posInDocument, const QTextFormat &format)
Sets the size of the inline object item corresponding to the text format.
QFontEngine * fontEngine(const QScriptItem &si, QFixed *ascent=0, QFixed *descent=0, QFixed *leading=0) const
bool ensureSpace(int nGlyphs) const
QScriptItemArray items
LayoutData * layoutData
QTextFormat format(int idx) const
int position() const
Returns the index of the block&#39;s first character within the document.
The QTextFormat class provides formatting information for a QTextDocument.
Definition: qtextformat.h:129
QTextBlock block
The QTextInlineObject class represents an inline object in a QTextLayout.
Definition: qtextlayout.h:69
int formatIndex(const QScriptItem *si) const
QTextDocumentPrivate * docHandle() const
Definition: qtextobject.h:283
QTextFormatCollection * formats() const
QAbstractTextDocumentLayout * docLayout() const
void shapeText(int item) const

◆ shapedGlyphs()

QGlyphLayout QTextEngine::shapedGlyphs ( const QScriptItem si) const
inline

Returns an array of QGlyphLayout items, offset at the script item. Each item in the array matches one glyph in the text, storing the advance, position etc. The returned item's length equals to the number of shaped glyphs.

See also
logClusters()

Definition at line 529 of file qtextengine_p.h.

Referenced by QPainterPath::addText(), boundingBox(), calculateTabWidth(), QTextLine::cursorToX(), QTextLine::draw(), drawMenuText(), QPainter::drawText(), elidedText(), QTextLineItemIterator::getSelectionBounds(), QTextLine::glyphs(), justify(), QTextLine::layout_helper(), QTextLineItemIterator::next(), offsetInLigature(), positionInLigature(), splitItem(), tightBoundingBox(), width(), and QTextLine::xToCursor().

529  {
531  }
LayoutData * layoutData
QGlyphLayout mid(int position, int n=-1) const
unsigned short num_glyphs
int glyph_data_offset

◆ shapeLine()

void QTextEngine::shapeLine ( const QScriptLine line)

Definition at line 861 of file qtextengine.cpp.

Referenced by QTextLine::cursorToX(), QPainter::drawText(), QTextLineItemIterator::QTextLineItemIterator(), and QTextLine::xToCursor().

862 {
863  QFixed x;
864  bool first = true;
865  const int end = findItem(line.from + line.length - 1);
866  int item = findItem(line.from);
867  if (item == -1)
868  return;
869  for (item = findItem(line.from); item <= end; ++item) {
870  QScriptItem &si = layoutData->items[item];
871  if (si.analysis.flags == QScriptAnalysis::Tab) {
872  ensureSpace(1);
873  si.width = calculateTabWidth(item, x);
874  } else {
875  shape(item);
876  }
877  if (first && si.position != line.from) { // that means our x position has to be offset
878  QGlyphLayout glyphs = shapedGlyphs(&si);
879  Q_ASSERT(line.from > si.position);
880  for (int i = line.from - si.position - 1; i >= 0; i--) {
881  x -= glyphs.effectiveAdvance(i);
882  }
883  }
884  first = false;
885 
886  x += si.width;
887  }
888 }
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 ...
int findItem(int strPos) const
bool ensureSpace(int nGlyphs) const
QScriptItemArray items
LayoutData * layoutData
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QGlyphLayout shapedGlyphs(const QScriptItem *si) const
unsigned short flags
void shape(int item) const
signed int length
QFixed effectiveAdvance(int item) const
static const KeyPair *const end
QScriptAnalysis analysis

◆ shapeText()

void QTextEngine::shapeText ( int  item) const
private

Definition at line 905 of file qtextengine.cpp.

Referenced by shape().

906 {
907  Q_ASSERT(item < layoutData->items.size());
908  QScriptItem &si = layoutData->items[item];
909 
910  if (si.num_glyphs)
911  return;
912 
913 #if defined(Q_WS_MAC)
914 #if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC)
915  if (enableHarfBuzz()) {
916 #endif
917  QFontEngine *actualFontEngine = fontEngine(si, &si.ascent, &si.descent, &si.leading);
918  if (actualFontEngine->type() == QFontEngine::Multi)
919  actualFontEngine = static_cast<QFontEngineMulti *>(actualFontEngine)->engine(0);
920 
921  HB_Face face = actualFontEngine->harfbuzzFace();
922  HB_Script script = (HB_Script) si.analysis.script;
923  if (face->supported_scripts[script])
924  shapeTextWithHarfbuzz(item);
925  else
926  shapeTextMac(item);
927 #if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC)
928  } else {
929  shapeTextMac(item);
930  }
931 #endif
932 #elif defined(Q_WS_WINCE)
933  shapeTextWithCE(item);
934 #else
935  shapeTextWithHarfbuzz(item);
936 #endif
937 
938  si.width = 0;
939 
940  if (!si.num_glyphs)
941  return;
942  QGlyphLayout glyphs = shapedGlyphs(&si);
943 
944  QFont font = this->font(si);
945  bool letterSpacingIsAbsolute = font.d->letterSpacingIsAbsolute;
946  QFixed letterSpacing = font.d->letterSpacing;
947  QFixed wordSpacing = font.d->wordSpacing;
948 
949  if (letterSpacingIsAbsolute && letterSpacing.value())
950  letterSpacing *= font.d->dpi / qt_defaultDpiY();
951 
952  if (letterSpacing != 0) {
953  for (int i = 1; i < si.num_glyphs; ++i) {
954  if (glyphs.attributes[i].clusterStart) {
955  if (letterSpacingIsAbsolute)
956  glyphs.advances_x[i-1] += letterSpacing;
957  else {
958  QFixed &advance = glyphs.advances_x[i-1];
959  advance += (letterSpacing - 100) * advance / 100;
960  }
961  }
962  }
963  if (letterSpacingIsAbsolute)
964  glyphs.advances_x[si.num_glyphs-1] += letterSpacing;
965  else {
966  QFixed &advance = glyphs.advances_x[si.num_glyphs-1];
967  advance += (letterSpacing - 100) * advance / 100;
968  }
969  }
970  if (wordSpacing != 0) {
971  for (int i = 0; i < si.num_glyphs; ++i) {
972  if (glyphs.attributes[i].justification == HB_Space
973  || glyphs.attributes[i].justification == HB_Arabic_Space) {
974  // word spacing only gets added once to a consecutive run of spaces (see CSS spec)
975  if (i + 1 == si.num_glyphs
976  ||(glyphs.attributes[i+1].justification != HB_Space
977  && glyphs.attributes[i+1].justification != HB_Arabic_Space))
978  glyphs.advances_x[i] += wordSpacing;
979  }
980  }
981  }
982 
983  for (int i = 0; i < si.num_glyphs; ++i)
984  si.width += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint;
985 }
void shapeTextMac(int item) const
int value() const
Definition: qfixed_p.h:73
QFixed * advances_x
bool letterSpacingIsAbsolute
Definition: qfont_p.h:193
Q_GUI_EXPORT int qt_defaultDpiY()
Definition: qfont.cpp:201
QFontEngine * fontEngine(const QScriptItem &si, QFixed *ascent=0, QFixed *descent=0, QFixed *leading=0) const
QScriptItemArray items
LayoutData * layoutData
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
virtual Type type() const =0
QFixed wordSpacing
Definition: qfont_p.h:196
QFont font() const
QGlyphLayout shapedGlyphs(const QScriptItem *si) const
QFixed letterSpacing
Definition: qfont_p.h:195
void shapeTextWithHarfbuzz(int item) const
take the item from layoutData->items and
Q_CORE_EXPORT int QT_FASTCALL script(uint ucs4)
static bool enableHarfBuzz()
void shapeTextWithCE(int item) const
The QFont class specifies a font used for drawing text.
Definition: qfont.h:64
QExplicitlySharedDataPointer< QFontPrivate > d
Definition: qfont.h:343
if(void) toggleToolbarShown
HB_GlyphAttributes * attributes
HB_Face harfbuzzFace() const

◆ shapeTextMac()

void QTextEngine::shapeTextMac ( int  item) const
private

Definition at line 557 of file qtextengine_mac.cpp.

558 {
559  QScriptItem &si = layoutData->items[item];
560 
562 
563  QFontEngine *font = fontEngine(si, &si.ascent, &si.descent, &si.leading);
564  if (font->type() != QFontEngine::Multi) {
565  shapeTextWithHarfbuzz(item);
566  return;
567  }
568 
569 #ifndef QT_MAC_USE_COCOA
570  QFontEngineMacMulti *fe = static_cast<QFontEngineMacMulti *>(font);
571 #else
573 #endif
574  QTextEngine::ShaperFlags flags;
575  if (si.analysis.bidiLevel % 2)
576  flags |= RightToLeft;
577  if (option.useDesignMetrics())
578  flags |= DesignMetrics;
579 
580  attributes(); // pre-initialize char attributes
581 
582  const int len = length(item);
583  int num_glyphs = length(item);
584  const QChar *str = layoutData->string.unicode() + si.position;
585  ushort upperCased[256];
588  ushort *uc = upperCased;
589  if (len > 256)
590  uc = new ushort[len];
591  for (int i = 0; i < len; ++i) {
593  uc[i] = str[i].toLower().unicode();
594  else
595  uc[i] = str[i].toUpper().unicode();
596  }
597  str = reinterpret_cast<const QChar *>(uc);
598  }
599 
600  ensureSpace(num_glyphs);
602 
603  QGlyphLayout g = availableGlyphs(&si);
604  g.numGlyphs = num_glyphs;
605  unsigned short *log_clusters = logClusters(&si);
606 
607  bool stringToCMapFailed = false;
608  // Skip shaping of line or paragraph separators since we are not
609  // going to draw them anyway
612  memset(log_clusters, 0, len * sizeof(unsigned short));
613  goto cleanUp;
614  }
615 
616  if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes(), &si)) {
617  ensureSpace(num_glyphs);
618  g = availableGlyphs(&si);
619  stringToCMapFailed = !fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters,
620  attributes(), &si);
621  }
622 
623  if (!stringToCMapFailed) {
624  heuristicSetGlyphAttributes(str, len, &g, log_clusters, num_glyphs);
625 
626  si.num_glyphs = num_glyphs;
627 
628  layoutData->used += si.num_glyphs;
629 
630  QGlyphLayout g = shapedGlyphs(&si);
631 
633  QVarLengthArray<QArabicProperties> props(len + 2);
634  QArabicProperties *properties = props.data();
635  int f = si.position;
636  int l = len;
637  if (f > 0) {
638  --f;
639  ++l;
640  ++properties;
641  }
642  if (f + l < layoutData->string.length()) {
643  ++l;
644  }
645  qt_getArabicProperties((const unsigned short *)(layoutData->string.unicode()+f), l, props.data());
646 
647  unsigned short *log_clusters = logClusters(&si);
648 
649  for (int i = 0; i < len; ++i) {
650  int gpos = log_clusters[i];
651  g.attributes[gpos].justification = properties[i].justification;
652  }
653  }
654  }
655 
656 cleanUp:
657  const ushort *uc = reinterpret_cast<const ushort *>(str);
658 
661  && uc != upperCased)
662  delete [] uc;
663 }
static void heuristicSetGlyphAttributes(const QChar *uc, int length, QGlyphLayout *glyphs, unsigned short *logClusters, int num_glyphs)
ushort unicode() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qchar.h:251
Flags flags() const
Returns the flags associated with the option.
Definition: qtextoption.h:121
QFontEngine * fontEngine(const QScriptItem &si, QFixed *ascent=0, QFixed *descent=0, QFixed *leading=0) const
bool ensureSpace(int nGlyphs) const
QScriptItemArray items
unsigned char justification
LayoutData * layoutData
unsigned short * logClusters(const QScriptItem *si) const
const HB_CharAttributes * attributes() const
virtual Type type() const =0
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
QFont font() const
const QChar * unicode() const
Returns a &#39;\0&#39;-terminated Unicode representation of the string.
Definition: qstring.h:706
QGlyphLayout shapedGlyphs(const QScriptItem *si) const
unsigned short bidiLevel
unsigned short num_glyphs
virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
QChar toUpper() const
Returns the uppercase equivalent if the character is lowercase or titlecase; otherwise returns the ch...
Definition: qchar.cpp:1287
QTextOption option
void qt_getArabicProperties(const unsigned short *chars, int len, QArabicProperties *properties)
QGlyphLayout availableGlyphs(const QScriptItem *si) const
void shapeTextWithHarfbuzz(int item) const
take the item from layoutData->items and
QFixed descent
unsigned short flags
QFixed leading
unsigned short script
unsigned short ushort
Definition: qglobal.h:995
int length(int item) const
QFactoryLoader * l
static const QCssKnownValue properties[NumProperties - 1]
Definition: qcssparser.cpp:67
bool useDesignMetrics() const
Returns true if the layout uses design rather than device metrics; otherwise returns false...
Definition: qtextoption.h:133
HB_GlyphAttributes * attributes
int glyph_data_offset
QChar toLower() const
Returns the lowercase equivalent if the character is uppercase or titlecase; otherwise returns the ch...
Definition: qchar.cpp:1239
QScriptAnalysis analysis

◆ shapeTextWithCE()

void QTextEngine::shapeTextWithCE ( int  item) const
private

Definition at line 1107 of file qtextengine.cpp.

1108 {
1109  QScriptItem &si = layoutData->items[item];
1111 
1112  QFontEngine *fe = fontEngine(si, &si.ascent, &si.descent, &si.leading);
1113 
1114  QTextEngine::ShaperFlags flags;
1115  if (si.analysis.bidiLevel % 2)
1116  flags |= RightToLeft;
1117  if (option.useDesignMetrics())
1118  flags |= DesignMetrics;
1119 
1120  // pre-initialize char attributes
1121  if (! attributes())
1122  return;
1123 
1124  const int len = length(item);
1125  int num_glyphs = length(item);
1126  const QChar *str = layoutData->string.unicode() + si.position;
1127  ushort upperCased[256];
1128  if (hasCaseChange(si)) {
1129  ushort *uc = upperCased;
1130  if (len > 256)
1131  uc = new ushort[len];
1132  for (int i = 0; i < len; ++i) {
1134  uc[i] = str[i].toLower().unicode();
1135  else
1136  uc[i] = str[i].toUpper().unicode();
1137  }
1138  str = reinterpret_cast<const QChar *>(uc);
1139  }
1140 
1141  while (true) {
1142  if (! ensureSpace(num_glyphs)) {
1143  // If str is converted to uppercase/lowercase form with a new buffer,
1144  // we need to delete that buffer before return for error
1145  const ushort *uc = reinterpret_cast<const ushort *>(str);
1146  if (hasCaseChange(si) && uc != upperCased)
1147  delete [] uc;
1148  return;
1149  }
1150  num_glyphs = layoutData->glyphLayout.numGlyphs - layoutData->used;
1151 
1152  QGlyphLayout g = availableGlyphs(&si);
1153  unsigned short *log_clusters = logClusters(&si);
1154 
1155  if (fe->stringToCMap(str,
1156  len,
1157  &g,
1158  &num_glyphs,
1159  flags)) {
1160  heuristicSetGlyphAttributes(str, len, &g, log_clusters, num_glyphs);
1161  break;
1162  }
1163  }
1164 
1165  si.num_glyphs = num_glyphs;
1166 
1167  layoutData->used += si.num_glyphs;
1168 
1169  const ushort *uc = reinterpret_cast<const ushort *>(str);
1170  if (hasCaseChange(si) && uc != upperCased)
1171  delete [] uc;
1172 }
ushort unicode() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qchar.h:251
static bool hasCaseChange(const QScriptItem &si)
QFontEngine * fontEngine(const QScriptItem &si, QFixed *ascent=0, QFixed *descent=0, QFixed *leading=0) const
bool ensureSpace(int nGlyphs) const
QScriptItemArray items
LayoutData * layoutData
unsigned short * logClusters(const QScriptItem *si) const
virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const =0
const HB_CharAttributes * attributes() const
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
const QChar * unicode() const
Returns a &#39;\0&#39;-terminated Unicode representation of the string.
Definition: qstring.h:706
unsigned short bidiLevel
unsigned short num_glyphs
QChar toUpper() const
Returns the uppercase equivalent if the character is lowercase or titlecase; otherwise returns the ch...
Definition: qchar.cpp:1287
QTextOption option
QGlyphLayout availableGlyphs(const QScriptItem *si) const
QFixed descent
unsigned short flags
static void heuristicSetGlyphAttributes(const QChar *uc, int length, QGlyphLayout *glyphs, unsigned short *logClusters, int num_glyphs)
QFixed leading
unsigned short ushort
Definition: qglobal.h:995
int length(int item) const
bool useDesignMetrics() const
Returns true if the layout uses design rather than device metrics; otherwise returns false...
Definition: qtextoption.h:133
int glyph_data_offset
QChar toLower() const
Returns the lowercase equivalent if the character is uppercase or titlecase; otherwise returns the ch...
Definition: qchar.cpp:1239
QScriptAnalysis analysis

◆ shapeTextWithHarfbuzz()

void QTextEngine::shapeTextWithHarfbuzz ( int  item) const
private

take the item from layoutData->items and

Definition at line 1186 of file qtextengine.cpp.

1187 {
1188  Q_ASSERT(sizeof(HB_Fixed) == sizeof(QFixed));
1189  Q_ASSERT(sizeof(HB_FixedPoint) == sizeof(QFixedPoint));
1190 
1191  QScriptItem &si = layoutData->items[item];
1192 
1194 
1195  QFontEngine *font = fontEngine(si, &si.ascent, &si.descent, &si.leading);
1196 
1197  bool kerningEnabled = this->font(si).d->kerning;
1198 
1199  HB_ShaperItem entire_shaper_item;
1200  qMemSet(&entire_shaper_item, 0, sizeof(entire_shaper_item));
1201  entire_shaper_item.string = reinterpret_cast<const HB_UChar16 *>(layoutData->string.constData());
1202  entire_shaper_item.stringLength = layoutData->string.length();
1203  entire_shaper_item.item.script = (HB_Script)si.analysis.script;
1204  entire_shaper_item.item.pos = si.position;
1205  entire_shaper_item.item.length = length(item);
1206  entire_shaper_item.item.bidiLevel = si.analysis.bidiLevel;
1207 
1208  HB_UChar16 upperCased[256]; // XXX what about making this 4096, so we don't have to extend it ever.
1209  if (hasCaseChange(si)) {
1210  HB_UChar16 *uc = upperCased;
1211  if (entire_shaper_item.item.length > 256)
1212  uc = new HB_UChar16[entire_shaper_item.item.length];
1213  for (uint i = 0; i < entire_shaper_item.item.length; ++i) {
1215  uc[i] = QChar::toLower(entire_shaper_item.string[si.position + i]);
1216  else
1217  uc[i] = QChar::toUpper(entire_shaper_item.string[si.position + i]);
1218  }
1219  entire_shaper_item.item.pos = 0;
1220  entire_shaper_item.string = uc;
1221  entire_shaper_item.stringLength = entire_shaper_item.item.length;
1222  }
1223 
1224  entire_shaper_item.shaperFlags = 0;
1225  if (!kerningEnabled)
1226  entire_shaper_item.shaperFlags |= HB_ShaperFlag_NoKerning;
1227  if (option.useDesignMetrics())
1228  entire_shaper_item.shaperFlags |= HB_ShaperFlag_UseDesignMetrics;
1229 
1230  entire_shaper_item.num_glyphs = qMax(layoutData->glyphLayout.numGlyphs - layoutData->used, int(entire_shaper_item.item.length));
1231  if (! ensureSpace(entire_shaper_item.num_glyphs)) {
1232  if (hasCaseChange(si))
1233  delete [] const_cast<HB_UChar16 *>(entire_shaper_item.string);
1234  return;
1235  }
1236  QGlyphLayout initialGlyphs = availableGlyphs(&si).mid(0, entire_shaper_item.num_glyphs);
1237 
1238  if (!stringToGlyphs(&entire_shaper_item, &initialGlyphs, font)) {
1239  if (! ensureSpace(entire_shaper_item.num_glyphs)) {
1240  if (hasCaseChange(si))
1241  delete [] const_cast<HB_UChar16 *>(entire_shaper_item.string);
1242  return;
1243  }
1244  initialGlyphs = availableGlyphs(&si).mid(0, entire_shaper_item.num_glyphs);
1245 
1246  if (!stringToGlyphs(&entire_shaper_item, &initialGlyphs, font)) {
1247  // ############ if this happens there's a bug in the fontengine
1248  if (hasCaseChange(si) && entire_shaper_item.string != upperCased)
1249  delete [] const_cast<HB_UChar16 *>(entire_shaper_item.string);
1250  return;
1251  }
1252  }
1253 
1254  // split up the item into parts that come from different font engines.
1255  QVarLengthArray<int> itemBoundaries(2);
1256  // k * 2 entries, array[k] == index in string, array[k + 1] == index in glyphs
1257  itemBoundaries[0] = entire_shaper_item.item.pos;
1258  itemBoundaries[1] = 0;
1259 
1260  if (font->type() == QFontEngine::Multi) {
1261  uint lastEngine = 0;
1262  int charIdx = entire_shaper_item.item.pos;
1263  const int stringEnd = charIdx + entire_shaper_item.item.length;
1264  for (quint32 i = 0; i < entire_shaper_item.num_glyphs; ++i, ++charIdx) {
1265  uint engineIdx = initialGlyphs.glyphs[i] >> 24;
1266  if (engineIdx != lastEngine && i > 0) {
1267  itemBoundaries.append(charIdx);
1268  itemBoundaries.append(i);
1269  }
1270  lastEngine = engineIdx;
1271  if (HB_IsHighSurrogate(entire_shaper_item.string[charIdx])
1272  && charIdx < stringEnd - 1
1273  && HB_IsLowSurrogate(entire_shaper_item.string[charIdx + 1]))
1274  ++charIdx;
1275  }
1276  }
1277 
1278 
1279 
1280  int remaining_glyphs = entire_shaper_item.num_glyphs;
1281  int glyph_pos = 0;
1282  // for each item shape using harfbuzz and store the results in our layoutData's glyphs array.
1283  for (int k = 0; k < itemBoundaries.size(); k += 2) { // for the +2, see the comment at the definition of itemBoundaries
1284 
1285  HB_ShaperItem shaper_item = entire_shaper_item;
1286 
1287  shaper_item.item.pos = itemBoundaries[k];
1288  if (k < itemBoundaries.size() - 3) {
1289  shaper_item.item.length = itemBoundaries[k + 2] - shaper_item.item.pos;
1290  shaper_item.num_glyphs = itemBoundaries[k + 3] - itemBoundaries[k + 1];
1291  } else { // last combo in the list, avoid out of bounds access.
1292  shaper_item.item.length -= shaper_item.item.pos - entire_shaper_item.item.pos;
1293  shaper_item.num_glyphs -= itemBoundaries[k + 1];
1294  }
1295  shaper_item.initialGlyphCount = shaper_item.num_glyphs;
1296  if (shaper_item.num_glyphs < shaper_item.item.length)
1297  shaper_item.num_glyphs = shaper_item.item.length;
1298 
1299  QFontEngine *actualFontEngine = font;
1300  uint engineIdx = 0;
1301  if (font->type() == QFontEngine::Multi) {
1302  engineIdx = uint(availableGlyphs(&si).glyphs[glyph_pos] >> 24);
1303 
1304  actualFontEngine = static_cast<QFontEngineMulti *>(font)->engine(engineIdx);
1305  }
1306 
1307  si.ascent = qMax(actualFontEngine->ascent(), si.ascent);
1308  si.descent = qMax(actualFontEngine->descent(), si.descent);
1309  si.leading = qMax(actualFontEngine->leading(), si.leading);
1310 
1311  shaper_item.font = actualFontEngine->harfbuzzFont();
1312  shaper_item.face = actualFontEngine->harfbuzzFace();
1313 
1314  shaper_item.glyphIndicesPresent = true;
1315 
1316  remaining_glyphs -= shaper_item.initialGlyphCount;
1317 
1318  do {
1319  if (! ensureSpace(glyph_pos + shaper_item.num_glyphs + remaining_glyphs)) {
1320  if (hasCaseChange(si))
1321  delete [] const_cast<HB_UChar16 *>(entire_shaper_item.string);
1322  return;
1323  }
1324 
1325  const QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos);
1326  if (shaper_item.num_glyphs > shaper_item.item.length)
1327  moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs);
1328 
1329  shaper_item.glyphs = g.glyphs;
1330  shaper_item.attributes = g.attributes;
1331  shaper_item.advances = reinterpret_cast<HB_Fixed *>(g.advances_x);
1332  shaper_item.offsets = reinterpret_cast<HB_FixedPoint *>(g.offsets);
1333 
1334  if (shaper_item.glyphIndicesPresent) {
1335  for (hb_uint32 i = 0; i < shaper_item.initialGlyphCount; ++i)
1336  shaper_item.glyphs[i] &= 0x00ffffff;
1337  }
1338 
1339  shaper_item.log_clusters = logClusters(&si) + shaper_item.item.pos - entire_shaper_item.item.pos;
1340 
1341 // qDebug(" .. num_glyphs=%d, used=%d, item.num_glyphs=%d", num_glyphs, used, shaper_item.num_glyphs);
1342  } while (!qShapeItem(&shaper_item)); // this does the actual shaping via harfbuzz.
1343 
1344  QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos, shaper_item.num_glyphs);
1345  moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs);
1346 
1347  for (hb_uint32 i = 0; i < shaper_item.num_glyphs; ++i)
1348  g.glyphs[i] = g.glyphs[i] | (engineIdx << 24);
1349 
1350  for (hb_uint32 i = 0; i < shaper_item.item.length; ++i)
1351  shaper_item.log_clusters[i] += glyph_pos;
1352 
1353  if (kerningEnabled && !shaper_item.kerning_applied)
1355 
1356  glyph_pos += shaper_item.num_glyphs;
1357  }
1358 
1359 // qDebug(" -> item: script=%d num_glyphs=%d", shaper_item.script, shaper_item.num_glyphs);
1360  si.num_glyphs = glyph_pos;
1361 
1362  layoutData->used += si.num_glyphs;
1363 
1364  if (hasCaseChange(si) && entire_shaper_item.string != upperCased)
1365  delete [] const_cast<HB_UChar16 *>(entire_shaper_item.string);
1366 }
QFixed * advances_x
The QFlag class is a helper data type for QFlags.
Definition: qglobal.h:2289
HB_Glyph * glyphs
virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const
static bool hasCaseChange(const QScriptItem &si)
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
QFontEngine * fontEngine(const QScriptItem &si, QFixed *ascent=0, QFixed *descent=0, QFixed *leading=0) const
bool ensureSpace(int nGlyphs) const
QScriptItemArray items
LayoutData * layoutData
unsigned short * logClusters(const QScriptItem *si) const
QGlyphLayout mid(int position, int n=-1) const
static bool stringToGlyphs(HB_ShaperItem *item, QGlyphLayout *glyphs, QFontEngine *fontEngine)
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
virtual Type type() const =0
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
QFont font() const
virtual QFixed ascent() const =0
virtual QFixed descent() const =0
unsigned short bidiLevel
unsigned int uint
Definition: qglobal.h:996
unsigned short num_glyphs
QChar toUpper() const
Returns the uppercase equivalent if the character is lowercase or titlecase; otherwise returns the ch...
Definition: qchar.cpp:1287
QTextOption option
QGlyphLayout availableGlyphs(const QScriptItem *si) const
QFixed descent
HB_Font harfbuzzFont() const
unsigned short flags
QFixed leading
void * qMemSet(void *dest, int c, size_t n)
Definition: qglobal.cpp:2509
unsigned short script
QExplicitlySharedDataPointer< QFontPrivate > d
Definition: qfont.h:343
unsigned int quint32
Definition: qglobal.h:938
int length(int item) const
if(void) toggleToolbarShown
bool useDesignMetrics() const
Returns true if the layout uses design rather than device metrics; otherwise returns false...
Definition: qtextoption.h:133
HB_GlyphAttributes * attributes
int glyph_data_offset
uint kerning
Definition: qfont_p.h:191
HB_Bool qShapeItem(HB_ShaperItem *item)
Definition: qharfbuzz.cpp:118
QFixedPoint * offsets
QChar toLower() const
Returns the lowercase equivalent if the character is uppercase or titlecase; otherwise returns the ch...
Definition: qchar.cpp:1239
const QChar * constData() const
Returns a pointer to the data stored in the QString.
Definition: qstring.h:712
static void moveGlyphData(const QGlyphLayout &destination, const QGlyphLayout &source, int num)
virtual QFixed leading() const =0
HB_Face harfbuzzFace() const
QScriptAnalysis analysis

◆ splitItem()

void QTextEngine::splitItem ( int  item,
int  pos 
) const
private

Definition at line 2677 of file qtextengine.cpp.

Referenced by setBoundary().

2678 {
2679  if (pos <= 0)
2680  return;
2681 
2682  layoutData->items.insert(item + 1, layoutData->items[item]);
2683  QScriptItem &oldItem = layoutData->items[item];
2684  QScriptItem &newItem = layoutData->items[item+1];
2685  newItem.position += pos;
2686 
2687  if (oldItem.num_glyphs) {
2688  // already shaped, break glyphs aswell
2689  int breakGlyph = logClusters(&oldItem)[pos];
2690 
2691  newItem.num_glyphs = oldItem.num_glyphs - breakGlyph;
2692  oldItem.num_glyphs = breakGlyph;
2693  newItem.glyph_data_offset = oldItem.glyph_data_offset + breakGlyph;
2694 
2695  for (int i = 0; i < newItem.num_glyphs; i++)
2696  logClusters(&newItem)[i] -= breakGlyph;
2697 
2698  QFixed w = 0;
2699  const QGlyphLayout g = shapedGlyphs(&oldItem);
2700  for(int j = 0; j < breakGlyph; ++j)
2701  w += g.advances_x[j] * !g.attributes[j].dontPrint;
2702 
2703  newItem.width = oldItem.width - w;
2704  oldItem.width = w;
2705  }
2706 
2707 // qDebug("split at position %d itempos=%d", pos, item);
2708 }
QFixed * advances_x
QScriptItemArray items
LayoutData * layoutData
unsigned short * logClusters(const QScriptItem *si) const
QGlyphLayout shapedGlyphs(const QScriptItem *si) const
unsigned short num_glyphs
void insert(int i, const T &t)
Inserts value at index position i in the vector.
Definition: qvector.h:362
HB_GlyphAttributes * attributes
int glyph_data_offset

◆ tightBoundingBox()

glyph_metrics_t QTextEngine::tightBoundingBox ( int  from,
int  len 
) const

Definition at line 1797 of file qtextengine.cpp.

1798 {
1799  itemize();
1800 
1801  glyph_metrics_t gm;
1802 
1803  for (int i = 0; i < layoutData->items.size(); i++) {
1804  const QScriptItem *si = layoutData->items.constData() + i;
1805  int pos = si->position;
1806  int ilen = length(i);
1807  if (pos > from + len)
1808  break;
1809  if (pos + len > from) {
1810  if (!si->num_glyphs)
1811  shape(i);
1812  unsigned short *logClusters = this->logClusters(si);
1813  QGlyphLayout glyphs = shapedGlyphs(si);
1814 
1815  // do the simple thing for now and give the first glyph in a cluster the full width, all other ones 0.
1816  int charFrom = from - pos;
1817  if (charFrom < 0)
1818  charFrom = 0;
1819  int glyphStart = logClusters[charFrom];
1820  if (charFrom > 0 && logClusters[charFrom-1] == glyphStart)
1821  while (charFrom < ilen && logClusters[charFrom] == glyphStart)
1822  charFrom++;
1823  if (charFrom < ilen) {
1824  glyphStart = logClusters[charFrom];
1825  int charEnd = from + len - 1 - pos;
1826  if (charEnd >= ilen)
1827  charEnd = ilen-1;
1828  int glyphEnd = logClusters[charEnd];
1829  while (charEnd < ilen && logClusters[charEnd] == glyphEnd)
1830  charEnd++;
1831  glyphEnd = (charEnd == ilen) ? si->num_glyphs : logClusters[charEnd];
1832  if (glyphStart <= glyphEnd ) {
1833  QFontEngine *fe = fontEngine(*si);
1834  glyph_metrics_t m = fe->tightBoundingBox(glyphs.mid(glyphStart, glyphEnd - glyphStart));
1835  gm.x = qMin(gm.x, m.x + gm.xoff);
1836  gm.y = qMin(gm.y, m.y + gm.yoff);
1837  gm.width = qMax(gm.width, m.width+gm.xoff);
1838  gm.height = qMax(gm.height, m.height+gm.yoff);
1839  gm.xoff += m.xoff;
1840  gm.yoff += m.yoff;
1841  }
1842  }
1843  }
1844  }
1845  return gm;
1846 }
glyph_metrics_t tightBoundingBox(const QGlyphLayout &glyphs)
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
QFontEngine * fontEngine(const QScriptItem &si, QFixed *ascent=0, QFixed *descent=0, QFixed *leading=0) const
QScriptItemArray items
LayoutData * layoutData
unsigned short * logClusters(const QScriptItem *si) const
QGlyphLayout mid(int position, int n=-1) const
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
QGlyphLayout shapedGlyphs(const QScriptItem *si) const
unsigned short num_glyphs
void itemize() const
void shape(int item) const
int length(int item) const
if(void) toggleToolbarShown
const T * constData() const
Returns a const pointer to the data stored in the vector.
Definition: qvector.h:154
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137

◆ validate()

void QTextEngine::validate ( ) const

Definition at line 1486 of file qtextengine.cpp.

Referenced by elidedText(), and itemize().

1487 {
1488  if (layoutData)
1489  return;
1490  layoutData = new LayoutData();
1491  if (block.docHandle()) {
1492  layoutData->string = block.text();
1494  layoutData->string += QLatin1Char(block.next().isValid() ? 0xb6 : 0x20);
1495  } else {
1496  layoutData->string = text;
1497  }
1498  if (specialData && specialData->preeditPosition != -1)
1500 }
QString text() const
Returns the block&#39;s contents as plain text.
SpecialData * specialData
Flags flags() const
Returns the flags associated with the option.
Definition: qtextoption.h:121
LayoutData * layoutData
QTextBlock next() const
Returns the text block in the document after this block, or an empty text block if this is the last o...
QTextOption option
QTextBlock block
bool isValid() const
Returns true if this text block is valid; otherwise returns false.
Definition: qtextobject.h:208
QString text
QTextDocumentPrivate * docHandle() const
Definition: qtextobject.h:283
QString & insert(int i, QChar c)
Definition: qstring.cpp:1671
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55

◆ visualCursorMovement()

bool QTextEngine::visualCursorMovement ( ) const
inline

Definition at line 601 of file qtextengine_p.h.

Referenced by QTextLine::cursorToX(), and QTextLine::xToCursor().

602  {
603  return (visualMovement ||
605  }
QTextBlock block
uint visualMovement
Qt::CursorMoveStyle defaultCursorMoveStyle
QTextDocumentPrivate * docHandle() const
Definition: qtextobject.h:283

◆ width()

QFixed QTextEngine::width ( int  charFrom,
int  numChars 
) const

Definition at line 1674 of file qtextengine.cpp.

Referenced by elidedText(), and leadingSpaceWidth().

1675 {
1676  itemize();
1677 
1678  QFixed w = 0;
1679 
1680 // qDebug("QTextEngine::width(from = %d, len = %d), numItems=%d, strleng=%d", from, len, items.size(), string.length());
1681  for (int i = 0; i < layoutData->items.size(); i++) {
1682  const QScriptItem *si = layoutData->items.constData() + i;
1683  int pos = si->position;
1684  int ilen = length(i);
1685 // qDebug("item %d: from %d len %d", i, pos, ilen);
1686  if (pos >= from + len)
1687  break;
1688  if (pos + ilen > from) {
1689  if (!si->num_glyphs)
1690  shape(i);
1691 
1692  if (si->analysis.flags == QScriptAnalysis::Object) {
1693  w += si->width;
1694  continue;
1695  } else if (si->analysis.flags == QScriptAnalysis::Tab) {
1696  w += calculateTabWidth(i, w);
1697  continue;
1698  }
1699 
1700 
1701  QGlyphLayout glyphs = shapedGlyphs(si);
1702  unsigned short *logClusters = this->logClusters(si);
1703 
1704 // fprintf(stderr, " logclusters:");
1705 // for (int k = 0; k < ilen; k++)
1706 // fprintf(stderr, " %d", logClusters[k]);
1707 // fprintf(stderr, "\n");
1708  // do the simple thing for now and give the first glyph in a cluster the full width, all other ones 0.
1709  int charFrom = from - pos;
1710  if (charFrom < 0)
1711  charFrom = 0;
1712  int glyphStart = logClusters[charFrom];
1713  if (charFrom > 0 && logClusters[charFrom-1] == glyphStart)
1714  while (charFrom < ilen && logClusters[charFrom] == glyphStart)
1715  charFrom++;
1716  if (charFrom < ilen) {
1717  glyphStart = logClusters[charFrom];
1718  int charEnd = from + len - 1 - pos;
1719  if (charEnd >= ilen)
1720  charEnd = ilen-1;
1721  int glyphEnd = logClusters[charEnd];
1722  while (charEnd < ilen && logClusters[charEnd] == glyphEnd)
1723  charEnd++;
1724  glyphEnd = (charEnd == ilen) ? si->num_glyphs : logClusters[charEnd];
1725 
1726 // qDebug("char: start=%d end=%d / glyph: start = %d, end = %d", charFrom, charEnd, glyphStart, glyphEnd);
1727  for (int i = glyphStart; i < glyphEnd; i++)
1728  w += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint;
1729  }
1730  }
1731  }
1732 // qDebug(" --> w= %d ", w);
1733  return w;
1734 }
QFixed * advances_x
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 ...
QScriptItemArray items
LayoutData * layoutData
unsigned short * logClusters(const QScriptItem *si) const
for(int ii=mo->methodOffset();ii< mo->methodCount();++ii)
QGlyphLayout shapedGlyphs(const QScriptItem *si) const
unsigned short num_glyphs
void itemize() const
unsigned short flags
void shape(int item) const
int length(int item) const
HB_GlyphAttributes * attributes
const T * constData() const
Returns a const pointer to the data stored in the vector.
Definition: qvector.h:154
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
QScriptAnalysis analysis

Properties

◆ block

QTextBlock QTextEngine::block

◆ cacheGlyphs

uint QTextEngine::cacheGlyphs

Definition at line 591 of file qtextengine_p.h.

Referenced by init().

◆ feCache

FontEngineCache QTextEngine::feCache
mutable

Definition at line 579 of file qtextengine_p.h.

Referenced by fontEngine(), and resetFontEngineCache().

◆ fnt

QFont QTextEngine::fnt

◆ forceJustification

uint QTextEngine::forceJustification

Definition at line 593 of file qtextengine_p.h.

Referenced by QPainter::drawText(), init(), justify(), and qt_format_text().

◆ ignoreBidi

uint QTextEngine::ignoreBidi

Definition at line 590 of file qtextengine_p.h.

Referenced by QPainter::drawText(), init(), itemize(), and qt_format_text().

◆ layoutData

LayoutData* QTextEngine::layoutData
mutable

◆ lines

QScriptLineArray QTextEngine::lines
mutable

◆ maxWidth

QFixed QTextEngine::maxWidth

Definition at line 588 of file qtextengine_p.h.

Referenced by init(), invalidate(), and QTextLine::layout_helper().

◆ minWidth

QFixed QTextEngine::minWidth

Definition at line 587 of file qtextengine_p.h.

Referenced by init(), invalidate(), and QTextLine::layout_helper().

◆ option

QTextOption QTextEngine::option

◆ position

QPointF QTextEngine::position

Definition at line 589 of file qtextengine_p.h.

Referenced by calculateTabWidth(), findItem(), and itemize().

◆ specialData

SpecialData* QTextEngine::specialData

◆ stackEngine

uint QTextEngine::stackEngine

◆ text

QString QTextEngine::text

Definition at line 581 of file qtextengine_p.h.

Referenced by validate().

◆ underlinePositions

int* QTextEngine::underlinePositions

Definition at line 596 of file qtextengine_p.h.

Referenced by QTextLine::draw(), drawMenuText(), init(), and qt_format_text().

◆ visualMovement

uint QTextEngine::visualMovement

Definition at line 594 of file qtextengine_p.h.

Referenced by init().


The documentation for this class was generated from the following files: