src/gui/text/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 "qvarlengtharray.h"
#include "qscriptengine_p.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 "qtextengine_unix.cpp"

Include dependency graph for qtextengine.cpp:

Go to the source code of this file.

Classes

struct  QBidiStatus
struct  QBidiControl
struct  QJustificationPoint

Defines

#define BIDI_DEBUG   0

Typedefs

typedef void(*) fAppendItems (QTextEngine *, int &start, int &stop, QBidiControl &control, QChar::Direction dir)

Enumerations

enum  
enum  break_action

Functions

static void qAppendItems (QTextEngine *engine, int &start, int &stop, QBidiControl &control, QChar::Direction dir)
static bool bidiItemize (QTextEngine *engine, bool rightToLeft)
static void calcLineBreaks (const QString &str, QCharAttributes *charAttributes)
static void init (QTextEngine *e)
 Q_DECLARE_TYPEINFO (QJustificationPoint, Q_PRIMITIVE_TYPE)
static void set (QJustificationPoint *point, int type, QGlyphLayout *glyph, QFontEngine *fe)

Variables

static fAppendItems appendItems = qAppendItems
static const quint8 breakTable [QUnicodeTables::LineBreak_CM+1][QUnicodeTables::LineBreak_CM+1]


Define Documentation

#define BIDI_DEBUG   0

Definition at line 49 of file qtextengine.cpp.


Typedef Documentation

typedef void(* ) fAppendItems(QTextEngine *, int &start, int &stop, QBidiControl &control, QChar::Direction dir)

Definition at line 195 of file qtextengine.cpp.


Enumeration Type Documentation

anonymous enum

Definition at line 75 of file qtextengine.cpp.

00075 { MaxBidiLevel = 61 };

enum break_action

Definition at line 719 of file qtextengine.cpp.

00719                   {
00720     Dbk, // Direct break
00721     Ibk, // Indirect break; only allowed if space between the two chars
00722     Pbk // Prohibited break; no break allowed even if space between chars
00723 };


Function Documentation

static bool bidiItemize ( QTextEngine engine,
bool  rightToLeft 
) [static]

Definition at line 199 of file qtextengine.cpp.

References appendItems, QBidiControl::basicDirection(), QBidiControl::canPop(), QBidiStatus::dir, QChar::DirAL, QChar::DirAN, QChar::DirB, QChar::DirBN, QChar::DirCS, QUnicodeTables::direction(), QBidiControl::direction(), QChar::DirEN, QChar::DirES, QChar::DirET, QChar::DirL, QChar::DirLRE, QChar::DirLRO, QChar::DirNSM, QChar::DirON, QChar::DirPDF, QChar::DirR, QChar::DirRLE, QChar::DirRLO, QChar::DirS, QChar::DirWS, QBidiControl::embed(), QTextStream::endl(), QBidiStatus::eor, int, QBidiStatus::last, QBidiStatus::lastStrong, QTextEngine::layoutData, length, QBidiControl::level, level, MaxBidiLevel, QBidiControl::override, and QBidiControl::pdf().

Referenced by QTextEngine::itemize().

00200 {
00201 #if BIDI_DEBUG >= 2
00202     cout << "bidiItemize: rightToLeft=" << rightToLeft << endl;
00203 #endif
00204     QBidiControl control(rightToLeft);
00205 
00206     bool hasBidi = rightToLeft;
00207 
00208     int sor = 0;
00209     int eor = -1;
00210 
00211 
00212     int length = engine->layoutData->string.length();
00213 
00214     if (!length)
00215         return hasBidi;
00216 
00217     const QChar *unicode = engine->layoutData->string.unicode();
00218     int current = 0;
00219 
00220     QChar::Direction dir = rightToLeft ? QChar::DirR : QChar::DirL;
00221     QBidiStatus status;
00222     QChar::Direction sdir = QUnicodeTables::direction(*unicode);
00223     if (sdir != QChar::DirL && sdir != QChar::DirR && sdir != QChar::DirEN && sdir != QChar::DirAN)
00224   sdir = QChar::DirON;
00225     else
00226         dir = QChar::DirON;
00227     status.eor = sdir;
00228     status.lastStrong = rightToLeft ? QChar::DirR : QChar::DirL;
00229     status.last = status.lastStrong;
00230     status.dir = sdir;
00231 
00232 
00233 
00234     while (current <= length) {
00235 
00236         QChar::Direction dirCurrent;
00237         if (current == (int)length)
00238             dirCurrent = control.basicDirection();
00239         else
00240             dirCurrent = QUnicodeTables::direction(unicode[current]);
00241 
00242 #if (BIDI_DEBUG >= 2)
00243         cout << "pos=" << current << " dir=" << directions[dir]
00244              << " current=" << directions[dirCurrent] << " last=" << directions[status.last]
00245              << " eor=" << eor << "/" << directions[status.eor]
00246              << " sor=" << sor << " lastStrong="
00247              << directions[status.lastStrong]
00248              << " level=" << (int)control.level << " override=" << (bool)control.override << endl;
00249 #endif
00250 
00251         switch(dirCurrent) {
00252 
00253             // embedding and overrides (X1-X9 in the BiDi specs)
00254         case QChar::DirRLE:
00255         case QChar::DirRLO:
00256         case QChar::DirLRE:
00257         case QChar::DirLRO:
00258             {
00259                 bool rtl = (dirCurrent == QChar::DirRLE || dirCurrent == QChar::DirRLO);
00260                 hasBidi |= rtl;
00261                 bool override = (dirCurrent == QChar::DirLRO || dirCurrent == QChar::DirRLO);
00262 
00263                 uchar level = control.level+1;
00264                 if ((level%2 != 0) == rtl) ++level;
00265                 if(level < MaxBidiLevel) {
00266                     eor = current-1;
00267                     appendItems(engine, sor, eor, control, dir);
00268                     eor = current;
00269                     control.embed(rtl, override);
00270                     QChar::Direction edir = (rtl ? QChar::DirR : QChar::DirL);
00271                     dir = status.eor = edir;
00272                     status.lastStrong = edir;
00273                 }
00274                 break;
00275             }
00276         case QChar::DirPDF:
00277             {
00278                 if (control.canPop()) {
00279                     if (dir != control.direction()) {
00280                         eor = current-1;
00281                         appendItems(engine, sor, eor, control, dir);
00282                         dir = control.direction();
00283                     }
00284                     eor = current;
00285                     appendItems(engine, sor, eor, control, dir);
00286                     control.pdf();
00287                     dir = QChar::DirON; status.eor = QChar::DirON;
00288                     status.last = control.direction();
00289                     if (control.override)
00290                         dir = control.direction();
00291                     else
00292                         dir = QChar::DirON;
00293                     status.lastStrong = control.direction();
00294                 }
00295                 break;
00296             }
00297 
00298             // strong types
00299         case QChar::DirL:
00300             if(dir == QChar::DirON)
00301                 dir = QChar::DirL;
00302             switch(status.last)
00303                 {
00304                 case QChar::DirL:
00305                     eor = current; status.eor = QChar::DirL; break;
00306                 case QChar::DirR:
00307                 case QChar::DirAL:
00308                 case QChar::DirEN:
00309                 case QChar::DirAN:
00310                     if (eor >= 0) {
00311                         appendItems(engine, sor, eor, control, dir);
00312                         dir = eor < length ? QUnicodeTables::direction(unicode[eor]) : control.basicDirection();
00313                         status.eor = dir;
00314                     } else {
00315                         eor = current; status.eor = dir;
00316                     }
00317                     break;
00318                 case QChar::DirES:
00319                 case QChar::DirET:
00320                 case QChar::DirCS:
00321                 case QChar::DirBN:
00322                 case QChar::DirB:
00323                 case QChar::DirS:
00324                 case QChar::DirWS:
00325                 case QChar::DirON:
00326                     if(dir != QChar::DirL) {
00327                         //last stuff takes embedding dir
00328                         if(control.direction() == QChar::DirR) {
00329                             if(status.eor != QChar::DirR) {
00330                                 // AN or EN
00331                                 appendItems(engine, sor, eor, control, dir);
00332                                 status.eor = QChar::DirON;
00333                                 dir = QChar::DirR;
00334                             }
00335                             eor = current - 1;
00336                             appendItems(engine, sor, eor, control, dir);
00337                             dir = eor < length ? QUnicodeTables::direction(unicode[eor]) : control.basicDirection();
00338                             status.eor = dir;
00339                         } else {
00340                             if(status.eor != QChar::DirL) {
00341                                 appendItems(engine, sor, eor, control, dir);
00342                                 status.eor = QChar::DirON;
00343                                 dir = QChar::DirL;
00344                             } else {
00345                                 eor = current; status.eor = QChar::DirL; break;
00346                             }
00347                         }
00348                     } else {
00349                         eor = current; status.eor = QChar::DirL;
00350                     }
00351                 default:
00352                     break;
00353                 }
00354             status.lastStrong = QChar::DirL;
00355             break;
00356         case QChar::DirAL:
00357         case QChar::DirR:
00358             hasBidi = true;
00359             if(dir == QChar::DirON) dir = QChar::DirR;
00360             switch(status.last)
00361                 {
00362                 case QChar::DirL:
00363                 case QChar::DirEN:
00364                 case QChar::DirAN:
00365                     if (eor >= 0)
00366                         appendItems(engine, sor, eor, control, dir);
00367                     // fall through
00368                 case QChar::DirR:
00369                 case QChar::DirAL:
00370                     dir = QChar::DirR; eor = current; status.eor = QChar::DirR; break;
00371                 case QChar::DirES:
00372                 case QChar::DirET:
00373                 case QChar::DirCS:
00374                 case QChar::DirBN:
00375                 case QChar::DirB:
00376                 case QChar::DirS:
00377                 case QChar::DirWS:
00378                 case QChar::DirON:
00379                     if(status.eor != QChar::DirR && status.eor != QChar::DirAL) {
00380                         //last stuff takes embedding dir
00381                         if(control.direction() == QChar::DirR
00382                            || status.lastStrong == QChar::DirR || status.lastStrong == QChar::DirAL) {
00383                             appendItems(engine, sor, eor, control, dir);
00384                             dir = QChar::DirR; status.eor = QChar::DirON;
00385                             eor = current;
00386                         } else {
00387                             eor = current - 1;
00388                             appendItems(engine, sor, eor, control, dir);
00389                             dir = QChar::DirR; status.eor = QChar::DirON;
00390                         }
00391                     } else {
00392                         eor = current; status.eor = QChar::DirR;
00393                     }
00394                 default:
00395                     break;
00396                 }
00397             status.lastStrong = dirCurrent;
00398             break;
00399 
00400             // weak types:
00401 
00402         case QChar::DirNSM:
00403             if (eor == current-1)
00404                 eor = current;
00405             break;
00406         case QChar::DirEN:
00407             // if last strong was AL change EN to AN
00408             if(status.lastStrong != QChar::DirAL) {
00409                 if(dir == QChar::DirON) {
00410                     if(status.lastStrong == QChar::DirL)
00411                         dir = QChar::DirL;
00412                     else
00413                         dir = QChar::DirEN;
00414                 }
00415                 switch(status.last)
00416                     {
00417                     case QChar::DirET:
00418                         if (status.lastStrong == QChar::DirR || status.lastStrong == QChar::DirAL) {
00419                             appendItems(engine, sor, eor, control, dir);
00420                             status.eor = QChar::DirON;
00421                             dir = QChar::DirAN;
00422                         }
00423                         // fall through
00424                     case QChar::DirEN:
00425                     case QChar::DirL:
00426                         eor = current;
00427                         status.eor = dirCurrent;
00428                         break;
00429                     case QChar::DirR:
00430                     case QChar::DirAL:
00431                     case QChar::DirAN:
00432                         if (eor >= 0)
00433                             appendItems(engine, sor, eor, control, dir);
00434                         else
00435                             eor = current;
00436                         status.eor = QChar::DirEN;
00437                         dir = QChar::DirAN; break;
00438                     case QChar::DirES:
00439                     case QChar::DirCS:
00440                         if(status.eor == QChar::DirEN || dir == QChar::DirAN) {
00441                             eor = current; break;
00442                         }
00443                     case QChar::DirBN:
00444                     case QChar::DirB:
00445                     case QChar::DirS:
00446                     case QChar::DirWS:
00447                     case QChar::DirON:
00448                         if(status.eor == QChar::DirR) {
00449                             // neutrals go to R
00450                             eor = current - 1;
00451                             appendItems(engine, sor, eor, control, dir);
00452                             dir = QChar::DirON; status.eor = QChar::DirEN;
00453                             dir = QChar::DirAN;
00454                         }
00455                         else if(status.eor == QChar::DirL ||
00456                                  (status.eor == QChar::DirEN && status.lastStrong == QChar::DirL)) {
00457                             eor = current; status.eor = dirCurrent;
00458                         } else {
00459                             // numbers on both sides, neutrals get right to left direction
00460                             if(dir != QChar::DirL) {
00461                                 appendItems(engine, sor, eor, control, dir);
00462                                 dir = QChar::DirON; status.eor = QChar::DirON;
00463                                 eor = current - 1;
00464                                 dir = QChar::DirR;
00465                                 appendItems(engine, sor, eor, control, dir);
00466                                 dir = QChar::DirON; status.eor = QChar::DirON;
00467                                 dir = QChar::DirAN;
00468                             } else {
00469                                 eor = current; status.eor = dirCurrent;
00470                             }
00471                         }
00472                     default:
00473                         break;
00474                     }
00475                 break;
00476             }
00477         case QChar::DirAN:
00478             hasBidi = true;
00479             dirCurrent = QChar::DirAN;
00480             if(dir == QChar::DirON) dir = QChar::DirAN;
00481             switch(status.last)
00482                 {
00483                 case QChar::DirL:
00484                 case QChar::DirAN:
00485                     eor = current; status.eor = QChar::DirAN; break;
00486                 case QChar::DirR:
00487                 case QChar::DirAL:
00488                 case QChar::DirEN:
00489                     if (eor >= 0){
00490                         appendItems(engine, sor, eor, control, dir);
00491                     } else {
00492                         eor = current;
00493                     }
00494                     dir = QChar::DirON; status.eor = QChar::DirAN;
00495                     break;
00496                 case QChar::DirCS:
00497                     if(status.eor == QChar::DirAN) {
00498                         eor = current; break;
00499                     }
00500                 case QChar::DirES:
00501                 case QChar::DirET:
00502                 case QChar::DirBN:
00503                 case QChar::DirB:
00504                 case QChar::DirS:
00505                 case QChar::DirWS:
00506                 case QChar::DirON:
00507                     if(status.eor == QChar::DirR) {
00508                         // neutrals go to R
00509                         eor = current - 1;
00510                         appendItems(engine, sor, eor, control, dir);
00511                         status.eor = QChar::DirAN;
00512                         dir = QChar::DirAN;
00513                     } else if(status.eor == QChar::DirL ||
00514                                (status.eor == QChar::DirEN && status.lastStrong == QChar::DirL)) {
00515                         eor = current; status.eor = dirCurrent;
00516                     } else {
00517                         // numbers on both sides, neutrals get right to left direction
00518                         if(dir != QChar::DirL) {
00519                             appendItems(engine, sor, eor, control, dir);
00520                             status.eor = QChar::DirON;
00521                             eor = current - 1;
00522                             dir = QChar::DirR;
00523                             appendItems(engine, sor, eor, control, dir);
00524                             status.eor = QChar::DirAN;
00525                             dir = QChar::DirAN;
00526                         } else {
00527                             eor = current; status.eor = dirCurrent;
00528                         }
00529                     }
00530                 default:
00531                     break;
00532                 }
00533             break;
00534         case QChar::DirES:
00535         case QChar::DirCS:
00536             break;
00537         case QChar::DirET:
00538             if(status.last == QChar::DirEN) {
00539                 dirCurrent = QChar::DirEN;
00540                 eor = current; status.eor = dirCurrent;
00541             }
00542             break;
00543 
00544             // boundary neutrals should be ignored
00545         case QChar::DirBN:
00546             break;
00547             // neutrals
00548         case QChar::DirB:
00549             // ### what do we do with newline and paragraph separators that come to here?
00550             break;
00551         case QChar::DirS:
00552             // ### implement rule L1
00553             break;
00554         case QChar::DirWS:
00555         case QChar::DirON:
00556             break;
00557         default:
00558             break;
00559         }
00560 
00561         //cout << "     after: dir=" << //        dir << " current=" << dirCurrent << " last=" << status.last << " eor=" << status.eor << " lastStrong=" << status.lastStrong << " embedding=" << control.direction() << endl;
00562 
00563         if(current >= (int)length) break;
00564 
00565         // set status.last as needed.
00566         switch(dirCurrent) {
00567         case QChar::DirET:
00568         case QChar::DirES:
00569         case QChar::DirCS:
00570         case QChar::DirS:
00571         case QChar::DirWS:
00572         case QChar::DirON:
00573             switch(status.last)
00574             {
00575             case QChar::DirL:
00576             case QChar::DirR:
00577             case QChar::DirAL:
00578             case QChar::DirEN:
00579             case QChar::DirAN:
00580                 status.last = dirCurrent;
00581                 break;
00582             default:
00583                 status.last = QChar::DirON;
00584             }
00585             break;
00586         case QChar::DirNSM:
00587         case QChar::DirBN:
00588             // ignore these
00589             break;
00590         case QChar::DirLRO:
00591         case QChar::DirLRE:
00592             status.last = QChar::DirL;
00593             break;
00594         case QChar::DirRLO:
00595         case QChar::DirRLE:
00596             status.last = QChar::DirR;
00597             break;
00598         case QChar::DirEN:
00599             if (status.last == QChar::DirL) {
00600                 status.last = QChar::DirL;
00601                 break;
00602             }
00603             // fall through
00604         default:
00605             status.last = dirCurrent;
00606         }
00607 
00608         ++current;
00609     }
00610 
00611 #if (BIDI_DEBUG >= 1)
00612     cout << "reached end of line current=" << current << ", eor=" << eor << endl;
00613 #endif
00614     eor = current - 1; // remove dummy char
00615 
00616     if (sor <= eor)
00617         appendItems(engine, sor, eor, control, dir);
00618 
00619     return hasBidi;
00620 }

Here is the call graph for this function:

static void calcLineBreaks ( const QString str,
QCharAttributes charAttributes 
) [static]

Definition at line 753 of file qtextengine.cpp.

References breakTable, QCharAttributes::category, QUnicodeTables::Properties::category, QUnicodeTables::category(), QCharAttributes::charStop, Dbk, i, Ibk, len, QString::length(), QUnicodeTables::Properties::line_break_class, QUnicodeTables::LineBreak_BK, QUnicodeTables::LineBreak_CM, QUnicodeTables::LineBreak_ID, QUnicodeTables::LineBreak_SA, QUnicodeTables::LineBreak_SP, QChar::Mark_NonSpacing, QChar::Other_Surrogate, QUnicodeTables::properties(), QChar::Separator_Space, QCharAttributes::softBreak, QString::unicode(), QChar::unicode(), and QCharAttributes::whiteSpace.

Referenced by QTextEngine::attributes().

00754 {
00755     int len = str.length();
00756     if (!len)
00757         return;
00758 
00759     const QChar *uc = str.unicode();
00760     const QUnicodeTables::Properties *prop = QUnicodeTables::properties(uc->unicode());
00761     int cls = prop->line_break_class;
00762     if (cls >= QUnicodeTables::LineBreak_CM)
00763         cls = QUnicodeTables::LineBreak_ID;
00764 
00765     charAttributes[0].softBreak = false;
00766     charAttributes[0].whiteSpace = (cls == QUnicodeTables::LineBreak_SP || cls == QUnicodeTables::LineBreak_BK);
00767     charAttributes[0].charStop = true;
00768     charAttributes[0].category = prop->category;
00769 
00770     for (int i = 1; i < len; ++i) {
00771         prop = QUnicodeTables::properties(uc[i].unicode());
00772         int ncls = prop->line_break_class;
00773         int category = prop->category;
00774         if (category == QChar::Mark_NonSpacing)
00775             goto nsm;
00776 
00777         if (category == QChar::Other_Surrogate) {
00778             // char stop only on first pair
00779             if (uc[i].unicode() >= 0xd800 && uc[i].unicode() < 0xdc00 && i < len-1
00780                 && uc[i+1].unicode() >= 0xdc00 && uc[i+1].unicode() < 0xe000)
00781                 goto nsm;
00782             // ### correctly handle second surrogate
00783         }
00784 
00785         if (ncls == QUnicodeTables::LineBreak_SP || ncls == QUnicodeTables::LineBreak_BK) {
00786             charAttributes[i].softBreak = false;
00787             charAttributes[i].whiteSpace = true;
00788             charAttributes[i].charStop = true;
00789             charAttributes[i].category = QChar::Separator_Space;
00790             cls = ncls;
00791             continue;
00792         }
00793 
00794 
00795   if (cls == QUnicodeTables::LineBreak_SA && ncls == QUnicodeTables::LineBreak_SA) {
00796             // two complex chars (thai or lao), thai_attributes might override, but here
00797             // we do a best guess
00798             charAttributes[i].softBreak = true;
00799             charAttributes[i].whiteSpace = false;
00800             charAttributes[i].charStop = true;
00801             charAttributes[i].category = QChar::Separator_Space;
00802             cls = ncls;
00803             continue;
00804         }
00805         {
00806       int tcls = ncls;
00807       if (tcls >= QUnicodeTables::LineBreak_SA)
00808     tcls = QUnicodeTables::LineBreak_ID;
00809       if (cls >= QUnicodeTables::LineBreak_SA)
00810     cls = QUnicodeTables::LineBreak_ID;
00811 
00812       bool softBreak;
00813       int brk = breakTable[cls][tcls];
00814       if (brk == Ibk)
00815     softBreak = (cls == QUnicodeTables::LineBreak_SP);
00816       else
00817     softBreak = (brk == Dbk);
00818 //        qDebug("char = %c %04x, cls=%d, ncls=%d, brk=%d soft=%d", uc[i].cell(), uc[i].unicode(), cls, ncls, brk, charAttributes[i].softBreak);
00819       charAttributes[i].softBreak = softBreak;
00820       charAttributes[i].whiteSpace = false;
00821       charAttributes[i].charStop = true;
00822       charAttributes[i].category = category;
00823       cls = ncls;
00824   }
00825         continue;
00826     nsm:
00827         charAttributes[i].softBreak = false;
00828         charAttributes[i].whiteSpace = false;
00829         charAttributes[i].charStop = false;
00830         charAttributes[i].category = QChar::Mark_NonSpacing;
00831     }
00832 }

Here is the call graph for this function:

static void init ( QTextEngine e  )  [static]

Definition at line 842 of file qtextengine.cpp.

References QTextEngine::cacheGlyphs, QTextEngine::ignoreBidi, QTextEngine::layoutData, QTextEngine::maxWidth, QTextEngine::minWidth, QTextEngine::specialData, QTextEngine::stackEngine, and QTextEngine::underlinePositions.

Referenced by QThreadData::current(), qdesigner_internal::PaletteEditor::getPalette(), qdesigner_internal::StringListEditor::getStringList(), qdesigner_internal::MoveStackedWidgetCommand::init(), qdesigner_internal::DeleteContainerWidgetPageCommand::init(), qdesigner_internal::SetDockWidgetCommand::init(), qdesigner_internal::DeleteToolBoxPageCommand::init(), qdesigner_internal::DeleteTabPageCommand::init(), qdesigner_internal::MoveToolBoxPageCommand::init(), qdesigner_internal::DeleteStackedWidgetPageCommand::init(), qdesigner_internal::MoveTabPageCommand::init(), QStyleOption::initFrom(), QVectorData::malloc(), Parser::parseForStatement(), Parser::parseInitDeclarator(), Parser::parseMemInitializerList(), Parser::parseNewExpression(), Q3DockAreaLayout::Q3DockAreaLayout(), qServerInit(), and QTextEngine::QTextEngine().

00843 {
00844 #ifdef Q_WS_WIN
00845     if(!resolvedUsp10)
00846         resolveUsp10();
00847 #endif
00848     e->ignoreBidi = false;
00849     e->cacheGlyphs = false;
00850 
00851     e->layoutData = 0;
00852 
00853     e->minWidth = 0;
00854     e->maxWidth = 0;
00855 
00856     e->underlinePositions = 0;
00857     e->specialData = 0;
00858     e->stackEngine = false;
00859 }

Q_DECLARE_TYPEINFO ( QJustificationPoint  ,
Q_PRIMITIVE_TYPE   
)

static void qAppendItems ( QTextEngine engine,
int &  start,
int &  stop,
QBidiControl control,
QChar::Direction  dir 
) [static]

Definition at line 126 of file qtextengine.cpp.

References QScriptItem::analysis, QVector< T >::append(), QBidiControl::baseLevel(), QUnicodeTables::Common, QChar::DirAN, QChar::DirEN, QChar::DirL, QChar::DirON, QChar::DirR, i, QUnicodeTables::Inherited, QScriptItem::isObject, QScriptItem::isSpace, QScriptItem::isTab, QTextEngine::layoutData, QBidiControl::level, level, QChar::LineSeparator, QChar::ObjectReplacementCharacter, QBidiControl::override, QScriptItem::position, qDebug(), s, and QUnicodeTables::script().

00127 {
00128     QScriptItemArray &items = engine->layoutData->items;
00129     const QChar *text = engine->layoutData->string.unicode();
00130 
00131     if (start > stop) {
00132         // #### the algorithm is currently not really safe against this. Still needs fixing.
00133 //         qWarning("QTextEngine: BiDi internal error in qAppendItems()");
00134         return;
00135     }
00136 
00137     int level = control.level;
00138 
00139     if(dir != QChar::DirON && !control.override) {
00140         // add level of run (cases I1 & I2)
00141         if(level % 2) {
00142             if(dir == QChar::DirL || dir == QChar::DirAN || dir == QChar::DirEN)
00143                 level++;
00144         } else {
00145             if(dir == QChar::DirR)
00146                 level++;
00147             else if(dir == QChar::DirAN || dir == QChar::DirEN)
00148                 level += 2;
00149         }
00150     }
00151 
00152 #if (BIDI_DEBUG >= 1)
00153     qDebug("new run: dir=%s from %d, to %d level = %d\n", directions[dir], start, stop, level);
00154 #endif
00155     int script = -1;
00156     QScriptItem item;
00157     item.position = start;
00158     item.analysis.script = script;
00159     item.analysis.bidiLevel = level;
00160     item.analysis.override = control.override;
00161     item.analysis.reserved = 0;
00162 
00163     for (int i = start; i <= stop; i++) {
00164         unsigned short uc = text[i].unicode();
00165         int s = QUnicodeTables::script(text[i]);
00166         if (uc == QChar::ObjectReplacementCharacter || uc == QChar::LineSeparator) {
00167             item.analysis.bidiLevel = level % 2 ? level-1 : level;
00168             item.analysis.script = QUnicodeTables::Common;
00169             item.isObject = true;
00170             s = -1;
00171         } else if (uc == 9) {
00172             item.analysis.script = QUnicodeTables::Common;
00173             item.isSpace = true;
00174             item.isTab = true;
00175             item.analysis.bidiLevel = control.baseLevel();
00176             s = -1;
00177         } else if (s != script && (s != QUnicodeTables::Inherited || script == -1)) {
00178             item.analysis.script = s == QUnicodeTables::Inherited ? QUnicodeTables::Common : s;
00179             item.analysis.bidiLevel = level;
00180         } else {
00181             if (i - start < 32000)
00182                 continue;
00183             start = i;
00184         }
00185 
00186         item.position = i;
00187         items.append(item);
00188         script = s;
00189         item.isSpace = item.isTab = item.isObject = false;
00190     }
00191     ++stop;
00192     start = stop;
00193 }

Here is the call graph for this function:

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

Definition at line 1184 of file qtextengine.cpp.

References QGlyphLayout::advance, QGlyphLayout::Arabic_Normal, QJustificationPoint::fontEngine, QJustificationPoint::glyph, QJustificationPoint::kashidaWidth, QGlyphLayout::NoJustification, QFontEngine::stringToCMap(), QJustificationPoint::type, and QFixedPoint::x.

Referenced by QX11PaintEngine::core_render_glyph(), Q3ButtonGroup::fixChildren(), QList< T >::fromSet(), QObjectPrivate::isValidObject(), QTextEngine::justify(), operator<<(), operator>>(), qdesigner_internal::ConnectionEdit::paintConnection(), qt_addObject(), qt_allTopLevelWidgets(), qt_removeObject(), registerFont(), QMainWindowLayout::setGeometry(), and QSignalDumper::startDump().

01185 {
01186     point->type = type;
01187     point->glyph = glyph;
01188     point->fontEngine = fe;
01189 
01190     if (type >= QGlyphLayout::Arabic_Normal) {
01191         QChar ch(0x640); // Kashida character
01192         QGlyphLayout glyphs[8];
01193         int nglyphs = 7;
01194         fe->stringToCMap(&ch, 1, glyphs, &nglyphs, 0);
01195         if (glyphs[0].glyph && glyphs[0].advance.x != 0) {
01196             point->kashidaWidth = glyphs[0].advance.x;
01197         } else {
01198             point->type = QGlyphLayout::NoJustification;
01199             point->kashidaWidth = 0;
01200         }
01201     }
01202 }

Here is the call graph for this function:


Variable Documentation

fAppendItems appendItems = qAppendItems [static]

Definition at line 196 of file qtextengine.cpp.

Referenced by bidiItemize(), and QTextEngine::itemize().

const quint8 breakTable[QUnicodeTables::LineBreak_CM+1][QUnicodeTables::LineBreak_CM+1] [static]

Initial value:

{
    
    { Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk }, 
    { Dbk, Pbk, Ibk, Pbk, Pbk, Pbk, Pbk, Pbk, Ibk, Ibk, Dbk, Ibk, Dbk, Dbk, Ibk, Ibk, Pbk, Pbk, Pbk, Pbk }, 
    { Pbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Pbk, Pbk }, 
    { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Pbk, Pbk }, 
    { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, 
    { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Ibk, Ibk, Ibk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, 
    { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, 
    { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, 
    { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Ibk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Pbk }, 
    { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, 
    { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Dbk, Ibk, Ibk, Ibk, Dbk, Dbk, Pbk, Pbk }, 
    { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Dbk, Ibk, Ibk, Ibk, Dbk, Dbk, Pbk, Pbk }, 
    { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Ibk, Dbk, Dbk, Dbk, Ibk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, 
    { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Dbk, Dbk, Dbk, Dbk, Ibk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, 
    { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, 
    { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, 
    { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Pbk, Ibk }, 
    { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Ibk, Ibk, Dbk, Pbk, Pbk, Ibk }, 
    { Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Pbk, Ibk }, 
    { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Ibk, Dbk, Dbk, Dbk, Ibk, Ibk, Ibk, Dbk, Dbk, Pbk, Pbk }  
}

Definition at line 727 of file qtextengine.cpp.

Referenced by calcLineBreaks().


Generated on Thu Mar 15 13:44:16 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1