Qt 4.8
Classes | Macros | Enumerations | Functions
qtextengine.cpp File Reference
#include "qdebug.h"
#include "qtextformat.h"
#include "qtextformat_p.h"
#include "qtextengine_p.h"
#include "qabstracttextdocumentlayout.h"
#include "qtextlayout.h"
#include "qtextboundaryfinder.h"
#include "qvarlengtharray.h"
#include "qfont.h"
#include "qfont_p.h"
#include "qfontengine_p.h"
#include "qstring.h"
#include <private/qunicodetables_p.h>
#include "qtextdocument_p.h"
#include <qapplication.h>
#include <stdlib.h>
#include "qfontengine_ft_p.h"
#include <private/qharfbuzz_p.h>

Go to the source code of this file.

Classes

struct  QBidiControl
 
struct  QBidiStatus
 
struct  QJustificationPoint
 

Macros

#define BIDI_DEBUG   0
 

Enumerations

enum  { MaxBidiLevel = 61 }
 

Functions

static void appendItems (QScriptAnalysis *analysis, int &start, int &stop, const QBidiControl &control, QChar::Direction dir)
 
static bool bidiItemize (QTextEngine *engine, QScriptAnalysis *analysis, QBidiControl &control)
 
static bool enableHarfBuzz ()
 
static bool hasCaseChange (const QScriptItem &si)
 
static void heuristicSetGlyphAttributes (const QChar *uc, int length, QGlyphLayout *glyphs, unsigned short *logClusters, int num_glyphs)
 
static void init (QTextEngine *e)
 
static void moveGlyphData (const QGlyphLayout &destination, const QGlyphLayout &source, int num)
 
static bool nextCharJoins (const QString &string, int pos)
 
static bool prevCharJoins (const QString &string, int pos)
 
 Q_DECLARE_TYPEINFO (QJustificationPoint, Q_PRIMITIVE_TYPE)
 
QTransform qt_true_matrix (qreal w, qreal h, QTransform x)
 
static void releaseCachedFontEngine (QFontEngine *fontEngine)
 
static void set (QJustificationPoint *point, int type, const QGlyphLayout &glyph, QFontEngine *fe)
 
static QChar::Direction skipBoundryNeutrals (QScriptAnalysis *analysis, const ushort *unicode, int length, int &sor, int &eor, QBidiControl &control)
 
static bool stringToGlyphs (HB_ShaperItem *item, QGlyphLayout *glyphs, QFontEngine *fontEngine)
 

Macro Definition Documentation

◆ BIDI_DEBUG

#define BIDI_DEBUG   0

Definition at line 227 of file qtextengine.cpp.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
MaxBidiLevel 

Definition at line 254 of file qtextengine.cpp.

254 { MaxBidiLevel = 61 };

Function Documentation

◆ appendItems()

static void appendItems ( QScriptAnalysis analysis,
int &  start,
int &  stop,
const QBidiControl control,
QChar::Direction  dir 
)
static

Definition at line 302 of file qtextengine.cpp.

Referenced by bidiItemize().

303 {
304  if (start > stop)
305  return;
306 
307  int level = control.level;
308 
309  if(dir != QChar::DirON && !control.override) {
310  // add level of run (cases I1 & I2)
311  if(level % 2) {
312  if(dir == QChar::DirL || dir == QChar::DirAN || dir == QChar::DirEN)
313  level++;
314  } else {
315  if(dir == QChar::DirR)
316  level++;
317  else if(dir == QChar::DirAN || dir == QChar::DirEN)
318  level += 2;
319  }
320  }
321 
322 #if (BIDI_DEBUG >= 1)
323  qDebug("new run: dir=%s from %d, to %d level = %d override=%d", directions[dir], start, stop, level, control.override);
324 #endif
325  QScriptAnalysis *s = analysis + start;
326  const QScriptAnalysis *e = analysis + stop;
327  while (s <= e) {
328  s->bidiLevel = level;
329  ++s;
330  }
331  ++stop;
332  start = stop;
333 }
unsigned int level
Q_CORE_EXPORT void qDebug(const char *,...)
unsigned short bidiLevel

◆ bidiItemize()

static bool bidiItemize ( QTextEngine engine,
QScriptAnalysis analysis,
QBidiControl control 
)
static

Definition at line 357 of file qtextengine.cpp.

Referenced by QTextEngine::itemize().

358 {
359  bool rightToLeft = (control.basicDirection() == 1);
360  bool hasBidi = rightToLeft;
361 #if BIDI_DEBUG >= 2
362  qDebug() << "bidiItemize: rightToLeft=" << rightToLeft << engine->layoutData->string;
363 #endif
364 
365  int sor = 0;
366  int eor = -1;
367 
368 
369  int length = engine->layoutData->string.length();
370 
371  const ushort *unicode = (const ushort *)engine->layoutData->string.unicode();
372  int current = 0;
373 
374  QChar::Direction dir = rightToLeft ? QChar::DirR : QChar::DirL;
376 
377  QChar::Direction sdir = QChar::direction(*unicode);
378  if (sdir != QChar::DirL && sdir != QChar::DirR && sdir != QChar::DirEN && sdir != QChar::DirAN)
379  sdir = QChar::DirON;
380  else
381  dir = QChar::DirON;
382  status.eor = sdir;
383  status.lastStrong = rightToLeft ? QChar::DirR : QChar::DirL;
384  status.last = status.lastStrong;
385  status.dir = sdir;
386 
387 
388  while (current <= length) {
389 
390  QChar::Direction dirCurrent;
391  if (current == (int)length)
392  dirCurrent = control.basicDirection();
393  else
394  dirCurrent = QChar::direction(unicode[current]);
395 
396 #if (BIDI_DEBUG >= 2)
397 // qDebug() << "pos=" << current << " dir=" << directions[dir]
398 // << " current=" << directions[dirCurrent] << " last=" << directions[status.last]
399 // << " eor=" << eor << '/' << directions[status.eor]
400 // << " sor=" << sor << " lastStrong="
401 // << directions[status.lastStrong]
402 // << " level=" << (int)control.level << " override=" << (bool)control.override;
403 #endif
404 
405  switch(dirCurrent) {
406 
407  // embedding and overrides (X1-X9 in the BiDi specs)
408  case QChar::DirRLE:
409  case QChar::DirRLO:
410  case QChar::DirLRE:
411  case QChar::DirLRO:
412  {
413  bool rtl = (dirCurrent == QChar::DirRLE || dirCurrent == QChar::DirRLO);
414  hasBidi |= rtl;
415  bool override = (dirCurrent == QChar::DirLRO || dirCurrent == QChar::DirRLO);
416 
417  unsigned int level = control.level+1;
418  if ((level%2 != 0) == rtl) ++level;
419  if(level < MaxBidiLevel) {
420  eor = current-1;
421  appendItems(analysis, sor, eor, control, dir);
422  eor = current;
423  control.embed(rtl, override);
424  QChar::Direction edir = (rtl ? QChar::DirR : QChar::DirL);
425  dir = status.eor = edir;
426  status.lastStrong = edir;
427  }
428  break;
429  }
430  case QChar::DirPDF:
431  {
432  if (control.canPop()) {
433  if (dir != control.direction()) {
434  eor = current-1;
435  appendItems(analysis, sor, eor, control, dir);
436  dir = control.direction();
437  }
438  eor = current;
439  appendItems(analysis, sor, eor, control, dir);
440  control.pdf();
441  dir = QChar::DirON; status.eor = QChar::DirON;
442  status.last = control.direction();
443  if (control.override)
444  dir = control.direction();
445  else
446  dir = QChar::DirON;
447  status.lastStrong = control.direction();
448  }
449  break;
450  }
451 
452  // strong types
453  case QChar::DirL:
454  if(dir == QChar::DirON)
455  dir = QChar::DirL;
456  switch(status.last)
457  {
458  case QChar::DirL:
459  eor = current; status.eor = QChar::DirL; break;
460  case QChar::DirR:
461  case QChar::DirAL:
462  case QChar::DirEN:
463  case QChar::DirAN:
464  if (eor >= 0) {
465  appendItems(analysis, sor, eor, control, dir);
466  status.eor = dir = skipBoundryNeutrals(analysis, unicode, length, sor, eor, control);
467  } else {
468  eor = current; status.eor = dir;
469  }
470  break;
471  case QChar::DirES:
472  case QChar::DirET:
473  case QChar::DirCS:
474  case QChar::DirBN:
475  case QChar::DirB:
476  case QChar::DirS:
477  case QChar::DirWS:
478  case QChar::DirON:
479  if(dir != QChar::DirL) {
480  //last stuff takes embedding dir
481  if(control.direction() == QChar::DirR) {
482  if(status.eor != QChar::DirR) {
483  // AN or EN
484  appendItems(analysis, sor, eor, control, dir);
485  status.eor = QChar::DirON;
486  dir = QChar::DirR;
487  }
488  eor = current - 1;
489  appendItems(analysis, sor, eor, control, dir);
490  status.eor = dir = skipBoundryNeutrals(analysis, unicode, length, sor, eor, control);
491  } else {
492  if(status.eor != QChar::DirL) {
493  appendItems(analysis, sor, eor, control, dir);
494  status.eor = QChar::DirON;
495  dir = QChar::DirL;
496  } else {
497  eor = current; status.eor = QChar::DirL; break;
498  }
499  }
500  } else {
501  eor = current; status.eor = QChar::DirL;
502  }
503  default:
504  break;
505  }
506  status.lastStrong = QChar::DirL;
507  break;
508  case QChar::DirAL:
509  case QChar::DirR:
510  hasBidi = true;
511  if(dir == QChar::DirON) dir = QChar::DirR;
512  switch(status.last)
513  {
514  case QChar::DirL:
515  case QChar::DirEN:
516  case QChar::DirAN:
517  if (eor >= 0)
518  appendItems(analysis, sor, eor, control, dir);
519  // fall through
520  case QChar::DirR:
521  case QChar::DirAL:
522  dir = QChar::DirR; eor = current; status.eor = QChar::DirR; break;
523  case QChar::DirES:
524  case QChar::DirET:
525  case QChar::DirCS:
526  case QChar::DirBN:
527  case QChar::DirB:
528  case QChar::DirS:
529  case QChar::DirWS:
530  case QChar::DirON:
531  if(status.eor != QChar::DirR && status.eor != QChar::DirAL) {
532  //last stuff takes embedding dir
533  if(control.direction() == QChar::DirR
534  || status.lastStrong == QChar::DirR || status.lastStrong == QChar::DirAL) {
535  appendItems(analysis, sor, eor, control, dir);
536  dir = QChar::DirR; status.eor = QChar::DirON;
537  eor = current;
538  } else {
539  eor = current - 1;
540  appendItems(analysis, sor, eor, control, dir);
541  dir = QChar::DirR; status.eor = QChar::DirON;
542  }
543  } else {
544  eor = current; status.eor = QChar::DirR;
545  }
546  default:
547  break;
548  }
549  status.lastStrong = dirCurrent;
550  break;
551 
552  // weak types:
553 
554  case QChar::DirNSM:
555  if (eor == current-1)
556  eor = current;
557  break;
558  case QChar::DirEN:
559  // if last strong was AL change EN to AN
560  if(status.lastStrong != QChar::DirAL) {
561  if(dir == QChar::DirON) {
562  if(status.lastStrong == QChar::DirL)
563  dir = QChar::DirL;
564  else
565  dir = QChar::DirEN;
566  }
567  switch(status.last)
568  {
569  case QChar::DirET:
570  if (status.lastStrong == QChar::DirR || status.lastStrong == QChar::DirAL) {
571  appendItems(analysis, sor, eor, control, dir);
572  status.eor = QChar::DirON;
573  dir = QChar::DirAN;
574  }
575  // fall through
576  case QChar::DirEN:
577  case QChar::DirL:
578  eor = current;
579  status.eor = dirCurrent;
580  break;
581  case QChar::DirR:
582  case QChar::DirAL:
583  case QChar::DirAN:
584  if (eor >= 0)
585  appendItems(analysis, sor, eor, control, dir);
586  else
587  eor = current;
588  status.eor = QChar::DirEN;
589  dir = QChar::DirAN; break;
590  case QChar::DirES:
591  case QChar::DirCS:
592  if(status.eor == QChar::DirEN || dir == QChar::DirAN) {
593  eor = current; break;
594  }
595  case QChar::DirBN:
596  case QChar::DirB:
597  case QChar::DirS:
598  case QChar::DirWS:
599  case QChar::DirON:
600  if(status.eor == QChar::DirR) {
601  // neutrals go to R
602  eor = current - 1;
603  appendItems(analysis, sor, eor, control, dir);
604  dir = QChar::DirON; status.eor = QChar::DirEN;
605  dir = QChar::DirAN;
606  }
607  else if(status.eor == QChar::DirL ||
608  (status.eor == QChar::DirEN && status.lastStrong == QChar::DirL)) {
609  eor = current; status.eor = dirCurrent;
610  } else {
611  // numbers on both sides, neutrals get right to left direction
612  if(dir != QChar::DirL) {
613  appendItems(analysis, sor, eor, control, dir);
614  dir = QChar::DirON; status.eor = QChar::DirON;
615  eor = current - 1;
616  dir = QChar::DirR;
617  appendItems(analysis, sor, eor, control, dir);
618  dir = QChar::DirON; status.eor = QChar::DirON;
619  dir = QChar::DirAN;
620  } else {
621  eor = current; status.eor = dirCurrent;
622  }
623  }
624  default:
625  break;
626  }
627  break;
628  }
629  case QChar::DirAN:
630  hasBidi = true;
631  dirCurrent = QChar::DirAN;
632  if(dir == QChar::DirON) dir = QChar::DirAN;
633  switch(status.last)
634  {
635  case QChar::DirL:
636  case QChar::DirAN:
637  eor = current; status.eor = QChar::DirAN; break;
638  case QChar::DirR:
639  case QChar::DirAL:
640  case QChar::DirEN:
641  if (eor >= 0){
642  appendItems(analysis, sor, eor, control, dir);
643  } else {
644  eor = current;
645  }
646  dir = QChar::DirAN; status.eor = QChar::DirAN;
647  break;
648  case QChar::DirCS:
649  if(status.eor == QChar::DirAN) {
650  eor = current; break;
651  }
652  case QChar::DirES:
653  case QChar::DirET:
654  case QChar::DirBN:
655  case QChar::DirB:
656  case QChar::DirS:
657  case QChar::DirWS:
658  case QChar::DirON:
659  if(status.eor == QChar::DirR) {
660  // neutrals go to R
661  eor = current - 1;
662  appendItems(analysis, sor, eor, control, dir);
663  status.eor = QChar::DirAN;
664  dir = QChar::DirAN;
665  } else if(status.eor == QChar::DirL ||
666  (status.eor == QChar::DirEN && status.lastStrong == QChar::DirL)) {
667  eor = current; status.eor = dirCurrent;
668  } else {
669  // numbers on both sides, neutrals get right to left direction
670  if(dir != QChar::DirL) {
671  appendItems(analysis, sor, eor, control, dir);
672  status.eor = QChar::DirON;
673  eor = current - 1;
674  dir = QChar::DirR;
675  appendItems(analysis, sor, eor, control, dir);
676  status.eor = QChar::DirAN;
677  dir = QChar::DirAN;
678  } else {
679  eor = current; status.eor = dirCurrent;
680  }
681  }
682  default:
683  break;
684  }
685  break;
686  case QChar::DirES:
687  case QChar::DirCS:
688  break;
689  case QChar::DirET:
690  if(status.last == QChar::DirEN) {
691  dirCurrent = QChar::DirEN;
692  eor = current; status.eor = dirCurrent;
693  }
694  break;
695 
696  // boundary neutrals should be ignored
697  case QChar::DirBN:
698  break;
699  // neutrals
700  case QChar::DirB:
701  // ### what do we do with newline and paragraph separators that come to here?
702  break;
703  case QChar::DirS:
704  // ### implement rule L1
705  break;
706  case QChar::DirWS:
707  case QChar::DirON:
708  break;
709  default:
710  break;
711  }
712 
713  //qDebug() << " after: dir=" << // dir << " current=" << dirCurrent << " last=" << status.last << " eor=" << status.eor << " lastStrong=" << status.lastStrong << " embedding=" << control.direction();
714 
715  if(current >= (int)length) break;
716 
717  // set status.last as needed.
718  switch(dirCurrent) {
719  case QChar::DirET:
720  case QChar::DirES:
721  case QChar::DirCS:
722  case QChar::DirS:
723  case QChar::DirWS:
724  case QChar::DirON:
725  switch(status.last)
726  {
727  case QChar::DirL:
728  case QChar::DirR:
729  case QChar::DirAL:
730  case QChar::DirEN:
731  case QChar::DirAN:
732  status.last = dirCurrent;
733  break;
734  default:
735  status.last = QChar::DirON;
736  }
737  break;
738  case QChar::DirNSM:
739  case QChar::DirBN:
740  // ignore these
741  break;
742  case QChar::DirLRO:
743  case QChar::DirLRE:
744  status.last = QChar::DirL;
745  break;
746  case QChar::DirRLO:
747  case QChar::DirRLE:
748  status.last = QChar::DirR;
749  break;
750  case QChar::DirEN:
751  if (status.last == QChar::DirL) {
752  status.last = QChar::DirL;
753  break;
754  }
755  // fall through
756  default:
757  status.last = dirCurrent;
758  }
759 
760  ++current;
761  }
762 
763 #if (BIDI_DEBUG >= 1)
764  qDebug() << "reached end of line current=" << current << ", eor=" << eor;
765 #endif
766  eor = current - 1; // remove dummy char
767 
768  if (sor <= eor)
769  appendItems(analysis, sor, eor, control, dir);
770 
771  return hasBidi;
772 }
QChar::Direction direction() const
unsigned int level
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
static LibLoadStatus status
Definition: qlocale_icu.cpp:69
QChar::Direction eor
QChar::Direction dir
LayoutData * layoutData
QChar::Direction lastStrong
bool canPop() const
Q_CORE_EXPORT void qDebug(const char *,...)
const QChar * unicode() const
Returns a &#39;\0&#39;-terminated Unicode representation of the string.
Definition: qstring.h:706
static void appendItems(QScriptAnalysis *analysis, int &start, int &stop, const QBidiControl &control, QChar::Direction dir)
QChar::Direction last
Direction
This enum type defines the Unicode direction attributes.
Definition: qchar.h:150
unsigned short ushort
Definition: qglobal.h:995
static QChar::Direction skipBoundryNeutrals(QScriptAnalysis *analysis, const ushort *unicode, int length, int &sor, int &eor, QBidiControl &control)
QChar::Direction basicDirection() const
Direction direction() const
Returns the character&#39;s direction.
Definition: qchar.cpp:889
void embed(bool rtl, bool o=false)

◆ enableHarfBuzz()

static bool enableHarfBuzz ( )
static

Definition at line 891 of file qtextengine.cpp.

Referenced by QTextEngine::shapeText().

892 {
893  static enum { Yes, No, Unknown } status = Unknown;
894 
895  if (status == Unknown) {
896  QByteArray v = qgetenv("QT_ENABLE_HARFBUZZ");
897  bool value = !v.isEmpty() && v != "0" && v != "false";
898  if (value) status = Yes;
899  else status = No;
900  }
901  return status == Yes;
902 }
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
static LibLoadStatus status
Definition: qlocale_icu.cpp:69
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421

◆ hasCaseChange()

static bool hasCaseChange ( const QScriptItem si)
inlinestatic

◆ heuristicSetGlyphAttributes()

static void heuristicSetGlyphAttributes ( const QChar uc,
int  length,
QGlyphLayout glyphs,
unsigned short *  logClusters,
int  num_glyphs 
)
static

Definition at line 998 of file qtextengine.cpp.

Referenced by QTextEngine::shapeTextWithCE().

999 {
1000  // ### zeroWidth and justification are missing here!!!!!
1001 
1002  Q_UNUSED(num_glyphs);
1003  Q_ASSERT(num_glyphs <= length);
1004 
1005 // qDebug("QScriptEngine::heuristicSetGlyphAttributes, num_glyphs=%d", item->num_glyphs);
1006 
1007  int glyph_pos = 0;
1008  for (int i = 0; i < length; i++) {
1009  if (uc[i].isHighSurrogate() && i < length-1 && uc[i+1].isLowSurrogate()) {
1010  logClusters[i] = glyph_pos;
1011  logClusters[++i] = glyph_pos;
1012  } else {
1013  logClusters[i] = glyph_pos;
1014  }
1015  ++glyph_pos;
1016  }
1017 
1018  // first char in a run is never (treated as) a mark
1019  int cStart = 0;
1020 
1021  const bool symbolFont = false; // ####
1022  glyphs->attributes[0].mark = false;
1023  glyphs->attributes[0].clusterStart = true;
1024  glyphs->attributes[0].dontPrint = (!symbolFont && uc[0].unicode() == 0x00ad) || qIsControlChar(uc[0].unicode());
1025 
1026  int pos = 0;
1027  int lastCat = QChar::category(uc[0].unicode());
1028  for (int i = 1; i < length; ++i) {
1029  if (logClusters[i] == pos)
1030  // same glyph
1031  continue;
1032  ++pos;
1033  while (pos < logClusters[i]) {
1034  glyphs[pos].attributes = glyphs[pos-1].attributes;
1035  ++pos;
1036  }
1037  // hide soft-hyphens by default
1038  if ((!symbolFont && uc[i].unicode() == 0x00ad) || qIsControlChar(uc[i].unicode()))
1039  glyphs->attributes[pos].dontPrint = true;
1040  const QUnicodeTables::Properties *prop = QUnicodeTables::properties(uc[i].unicode());
1041  int cat = prop->category;
1042  if (cat != QChar::Mark_NonSpacing) {
1043  glyphs->attributes[pos].mark = false;
1044  glyphs->attributes[pos].clusterStart = true;
1045  glyphs->attributes[pos].combiningClass = 0;
1046  cStart = logClusters[i];
1047  } else {
1048  int cmb = prop->combiningClass;
1049 
1050  if (cmb == 0) {
1051  // Fix 0 combining classes
1052  if ((uc[pos].unicode() & 0xff00) == 0x0e00) {
1053  // thai or lao
1054  unsigned char col = uc[pos].cell();
1055  if (col == 0x31 ||
1056  col == 0x34 ||
1057  col == 0x35 ||
1058  col == 0x36 ||
1059  col == 0x37 ||
1060  col == 0x47 ||
1061  col == 0x4c ||
1062  col == 0x4d ||
1063  col == 0x4e) {
1065  } else if (col == 0xb1 ||
1066  col == 0xb4 ||
1067  col == 0xb5 ||
1068  col == 0xb6 ||
1069  col == 0xb7 ||
1070  col == 0xbb ||
1071  col == 0xcc ||
1072  col == 0xcd) {
1073  cmb = QChar::Combining_Above;
1074  } else if (col == 0xbc) {
1075  cmb = QChar::Combining_Below;
1076  }
1077  }
1078  }
1079 
1080  glyphs->attributes[pos].mark = true;
1081  glyphs->attributes[pos].clusterStart = false;
1082  glyphs->attributes[pos].combiningClass = cmb;
1083  logClusters[i] = cStart;
1084  glyphs->advances_x[pos] = 0;
1085  glyphs->advances_y[pos] = 0;
1086  }
1087 
1088  // one gets an inter character justification point if the current char is not a non spacing mark.
1089  // as then the current char belongs to the last one and one gets a space justification point
1090  // after the space char.
1091  if (lastCat == QChar::Separator_Space)
1092  glyphs->attributes[pos-1].justification = HB_Space;
1093  else if (cat != QChar::Mark_NonSpacing)
1094  glyphs->attributes[pos-1].justification = HB_Character;
1095  else
1096  glyphs->attributes[pos-1].justification = HB_NoJustification;
1097 
1098  lastCat = cat;
1099  }
1100  pos = logClusters[length-1];
1101  if (lastCat == QChar::Separator_Space)
1102  glyphs->attributes[pos].justification = HB_Space;
1103  else
1104  glyphs->attributes[pos].justification = HB_Character;
1105 }
QFixed * advances_y
QFixed * advances_x
bool qIsControlChar(ushort uc)
ushort unicode() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qchar.h:251
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
Category category() const
Returns the character&#39;s category.
Definition: qchar.cpp:853
uchar cell() const
Returns the cell (least significant byte) of the Unicode character.
Definition: qchar.h:283
HB_GlyphAttributes * attributes
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
Q_CORE_EXPORT const Properties *QT_FASTCALL properties(uint ucs4)

◆ init()

static void init ( QTextEngine e)
static

Definition at line 1368 of file qtextengine.cpp.

Referenced by QTextEngine::QTextEngine().

1369 {
1370  e->ignoreBidi = false;
1371  e->cacheGlyphs = false;
1372  e->forceJustification = false;
1373  e->visualMovement = false;
1374 
1375  e->layoutData = 0;
1376 
1377  e->minWidth = 0;
1378  e->maxWidth = 0;
1379 
1380  e->underlinePositions = 0;
1381  e->specialData = 0;
1382  e->stackEngine = false;
1383 }
SpecialData * specialData
int * underlinePositions
LayoutData * layoutData
uint forceJustification
QFixed maxWidth
uint visualMovement
QFixed minWidth

◆ moveGlyphData()

static void moveGlyphData ( const QGlyphLayout destination,
const QGlyphLayout source,
int  num 
)
inlinestatic

Definition at line 1175 of file qtextengine.cpp.

Referenced by QTextEngine::shapeTextWithHarfbuzz().

1176 {
1177  if (num > 0 && destination.glyphs != source.glyphs) {
1178  memmove(destination.glyphs, source.glyphs, num * sizeof(HB_Glyph));
1179  memmove(destination.attributes, source.attributes, num * sizeof(HB_GlyphAttributes));
1180  memmove(destination.advances_x, source.advances_x, num * sizeof(HB_Fixed));
1181  memmove(destination.offsets, source.offsets, num * sizeof(HB_FixedPoint));
1182  }
1183 }
QFixed * advances_x
HB_Glyph * glyphs
HB_GlyphAttributes * attributes
QFixedPoint * offsets

◆ nextCharJoins()

static bool nextCharJoins ( const QString string,
int  pos 
)
inlinestatic

Definition at line 2467 of file qtextengine.cpp.

Referenced by QTextEngine::elidedText().

2468 {
2469  while (pos < string.length() && string.at(pos).category() == QChar::Mark_NonSpacing)
2470  ++pos;
2471  if (pos == string.length())
2472  return false;
2473  return string.at(pos).joining() != QChar::OtherJoining;
2474 }
#define at(className, varName)

◆ prevCharJoins()

static bool prevCharJoins ( const QString string,
int  pos 
)
inlinestatic

Definition at line 2476 of file qtextengine.cpp.

Referenced by QTextEngine::elidedText().

2477 {
2478  while (pos > 0 && string.at(pos - 1).category() == QChar::Mark_NonSpacing)
2479  --pos;
2480  if (pos == 0)
2481  return false;
2482  QChar::Joining joining = string.at(pos - 1).joining();
2483  return (joining == QChar::Dual || joining == QChar::Center);
2484 }
Joining
This enum type defines the Unicode joining attributes.
Definition: qchar.h:182
#define at(className, varName)

◆ Q_DECLARE_TYPEINFO()

Q_DECLARE_TYPEINFO ( QJustificationPoint  ,
Q_PRIMITIVE_TYPE   
)

◆ qt_true_matrix()

QTransform qt_true_matrix ( qreal  w,
qreal  h,
QTransform  x 
)

Definition at line 3154 of file qtextengine.cpp.

Referenced by glyph_metrics_t::transformed().

3155 {
3156  QRectF rect = x.mapRect(QRectF(0, 0, w, h));
3157  return x * QTransform::fromTranslate(-rect.x(), -rect.y());
3158 }
qreal y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:667
QRect mapRect(const QRect &) const
Creates and returns a QRect object that is a copy of the given rectangle, mapped into the coordinate ...
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
qreal x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:664
static QTransform fromTranslate(qreal dx, qreal dy)
Creates a matrix which corresponds to a translation of dx along the x axis and dy along the y axis...
Definition: qtransform.cpp:462

◆ releaseCachedFontEngine()

static void releaseCachedFontEngine ( QFontEngine fontEngine)
inlinestatic

Definition at line 1454 of file qtextengine.cpp.

Referenced by QTextEngine::fontEngine(), and QTextEngine::resetFontEngineCache().

1455 {
1456  if (fontEngine) {
1457  fontEngine->ref.deref();
1458  if (fontEngine->cache_count == 0 && fontEngine->ref == 0)
1459  delete fontEngine;
1460  }
1461 }
QAtomicInt ref
bool deref()
Atomically decrements the value of this QAtomicInt.

◆ set()

static void set ( QJustificationPoint point,
int  type,
const QGlyphLayout glyph,
QFontEngine fe 
)
static

Definition at line 1974 of file qtextengine.cpp.

Referenced by QX11PaintEngine::drawFreetype(), QFontEngineFT::loadFlags(), QFontEngineFT::loadGlyph(), and QFontEngineX11FT::uploadGlyphToServer().

1975 {
1976  point->type = type;
1977  point->glyph = glyph;
1978  point->fontEngine = fe;
1979 
1980  if (type >= HB_Arabic_Normal) {
1981  QChar ch(0x640); // Kashida character
1982  QGlyphLayoutArray<8> glyphs;
1983  int nglyphs = 7;
1984  fe->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
1985  if (glyphs.glyphs[0] && glyphs.advances_x[0] != 0) {
1986  point->kashidaWidth = glyphs.advances_x[0];
1987  } else {
1988  point->type = HB_NoJustification;
1989  point->kashidaWidth = 0;
1990  }
1991  }
1992 }
int type
Definition: qmetatype.cpp:239
QFixed * advances_x
HB_Glyph * glyphs
virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const =0
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
QFontEngine * fontEngine

◆ skipBoundryNeutrals()

static QChar::Direction skipBoundryNeutrals ( QScriptAnalysis analysis,
const ushort unicode,
int  length,
int &  sor,
int &  eor,
QBidiControl control 
)
static

Definition at line 335 of file qtextengine.cpp.

Referenced by bidiItemize().

338 {
339  QChar::Direction dir = control.basicDirection();
340  int level = sor > 0 ? analysis[sor - 1].bidiLevel : control.level;
341  while (sor < length) {
342  dir = QChar::direction(unicode[sor]);
343  // Keep skipping DirBN as if it doesn't exist
344  if (dir != QChar::DirBN)
345  break;
346  analysis[sor++].bidiLevel = level;
347  }
348 
349  eor = sor;
350  if (eor == length)
351  dir = control.basicDirection();
352 
353  return dir;
354 }
unsigned int level
unsigned short bidiLevel
Direction
This enum type defines the Unicode direction attributes.
Definition: qchar.h:150
QChar::Direction basicDirection() const
Direction direction() const
Returns the character&#39;s direction.
Definition: qchar.cpp:889

◆ stringToGlyphs()

static bool stringToGlyphs ( HB_ShaperItem *  item,
QGlyphLayout glyphs,
QFontEngine fontEngine 
)
static

Definition at line 846 of file qtextengine.cpp.

Referenced by QTextEngine::shapeTextWithHarfbuzz().

847 {
848  int nGlyphs = item->num_glyphs;
849 
850  QTextEngine::ShaperFlags shaperFlags(QTextEngine::GlyphIndicesOnly);
851  if (item->item.bidiLevel % 2)
852  shaperFlags |= QTextEngine::RightToLeft;
853 
854  bool result = fontEngine->stringToCMap(reinterpret_cast<const QChar *>(item->string + item->item.pos), item->item.length, glyphs, &nGlyphs, shaperFlags);
855  item->num_glyphs = nGlyphs;
856  glyphs->numGlyphs = nGlyphs;
857  return result;
858 }
virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const =0