1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the text module of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
29
#ifndef QTEXTENGINE_P_H
30
#define QTEXTENGINE_P_H
36
// This file is not part of the Qt API. It exists for the convenience
37
// of other Qt classes. This header file may change from version to
38
// version without notice, or even be removed.
45
#include "qnamespace.h"
46
#include "qtextlayout.h"
47
#include "qtextformat_p.h"
50
#include <qpaintengine.h>
51
#include "qtextobject.h"
52
#include "qtextoption.h"
53
#include "qtextdocument_p.h"
68
class QAbstractTextDocumentLayout;
70
class QTextItemInt : public QTextItem
84
QFontEngine *fontEngine;
88
// this uses the same coordinate system as Qt, but a different one to freetype.
89
// * y is usually negative, and is equal to the ascent.
90
// * negative yoff means the following stuff is drawn higher up.
91
// the characters bounding rect is given by QRect(x,y,width,height), it's advance by
93
struct glyph_metrics_t
95
inline glyph_metrics_t()
96
: x(100000), y(100000),
97
width(0), height(0), xoff(0), yoff(0)
99
inline glyph_metrics_t(qreal _x, qreal _y, qreal _width, qreal _height, qreal _xoff, qreal _yoff)
114
Q_DECLARE_TYPEINFO(glyph_metrics_t, Q_PRIMITIVE_TYPE);
116
typedef unsigned int glyph_t;
118
#if defined(Q_WS_X11) || defined (Q_WS_QWS) || defined (Q_WS_MAC)
121
struct QScriptAnalysis
123
unsigned short script : 7;
124
unsigned short override : 1; // Set when in LRO/RLO embedding
125
unsigned short bidiLevel : 6; // Unicode Bidi algorithm embedding level (0-61)
126
unsigned short reserved : 2;
127
bool operator == (const QScriptAnalysis &other) {
129
script == other.script &&
130
bidiLevel == other.bidiLevel;
132
// && override == other.override;
136
Q_DECLARE_TYPEINFO(QScriptAnalysis, Q_PRIMITIVE_TYPE);
138
#elif defined(Q_WS_WIN)
140
struct QScriptAnalysis {
141
unsigned short script :10;
142
unsigned short rtl :1;
143
unsigned short layoutRTL :1;
144
unsigned short linkBefore :1;
145
unsigned short linkAfter :1;
146
unsigned short logicalOrder :1;
147
unsigned short noGlyphIndex :1;
148
unsigned short bidiLevel :5;
149
unsigned short override :1;
150
unsigned short inhibitSymSwap :1;
151
unsigned short charShape :1;
152
unsigned short digitSubstitute :1;
153
unsigned short inhibitLigate :1;
154
unsigned short fDisplayZWG :1;
155
unsigned short arabicNumContext :1;
156
unsigned short gcpClusters :1;
157
unsigned short reserved :1;
158
unsigned short engineReserved :2;
160
Q_DECLARE_TYPEINFO(QScriptAnalysis, Q_PRIMITIVE_TYPE);
162
inline bool operator == (const QScriptAnalysis &sa1, const QScriptAnalysis &sa2)
165
sa1.script == sa2.script &&
166
sa1.bidiLevel == sa2.bidiLevel;
168
// && override == other.override;
175
inline QGlyphLayout()
176
: glyph(0), justificationType(0), nKashidas(0), space_18d6(0)
179
// highest value means highest priority for justification. Justification is done by first inserting kashidas
180
// starting with the highest priority positions, then stretching spaces, afterwards extending inter char
181
// spacing, and last spacing between arabic words.
182
// NoJustification is for example set for arabic where no Kashida can be inserted or for diacritics.
184
NoJustification= 0, // Justification can't be applied after this glyph
185
Arabic_Space = 1, // This glyph represents a space inside arabic text
186
Character = 2, // Inter-character justification point follows this glyph
187
Space = 4, // This glyph represents a blank outside an Arabic run
188
Arabic_Normal = 7, // Normal Middle-Of-Word glyph that connects to the right (begin)
189
Arabic_Waw = 8, // Next character is final form of Waw/Ain/Qaf/Fa
190
Arabic_BaRa = 9, // Next two chars are Ba + Ra/Ya/AlefMaksura
191
Arabic_Alef = 10, // Next character is final form of Alef/Tah/Lam/Kaf/Gaf
192
Arabic_HaaDal = 11, // Next character is final form of Haa/Dal/Taa Marbutah
193
Arabic_Seen = 12, // Initial or Medial form Of Seen/Sad
194
Arabic_Kashida = 13 // Kashida(U+640) in middle of word
199
unsigned short justification :4; // Justification class
200
unsigned short clusterStart :1; // First glyph of representation of cluster
201
unsigned short mark :1; // needs to be positioned around base char
202
unsigned short zeroWidth :1; // ZWJ, ZWNJ etc, with no width
203
unsigned short dontPrint :1;
204
unsigned short combiningClass :8;
206
Attributes attributes;
210
enum JustificationType {
215
uint justificationType :2;
216
uint nKashidas : 6; // more do not make sense...
217
uint space_18d6 : 24;
219
Q_DECLARE_TYPEINFO(QGlyphLayout, Q_PRIMITIVE_TYPE);
221
// also this is compatible to uniscribe. Do not change.
222
struct QCharAttributes {
223
uchar softBreak :1; // Potential linebreak point _before_ this character
224
uchar whiteSpace :1; // A unicode whitespace character, except NBSP, ZWNBSP
225
uchar charStop :1; // Valid cursor position (for left/right arrow)
226
uchar wordStop :1; // Valid cursor position (for ctrl + left/right arrow)
230
Q_DECLARE_TYPEINFO(QCharAttributes, Q_PRIMITIVE_TYPE);
234
inline QScriptItem() : position(0), isSpace(false), isTab(false),
236
num_glyphs(0), descent(-1), ascent(-1), width(-1),
241
QScriptAnalysis analysis;
242
unsigned short isSpace : 1;
243
unsigned short isTab : 1;
244
unsigned short isObject : 1;
249
int glyph_data_offset;
250
qreal height() const { return ascent + descent; }
254
Q_DECLARE_TYPEINFO(QScriptItem, Q_MOVABLE_TYPE);
256
typedef QVector<QScriptItem> QScriptItemArray;
261
: descent(0), ascent(0), x(0), y(0), width(0), textWidth(0) {}
269
signed int length : 30;
270
mutable uint justified : 1;
271
mutable uint gridfitted : 1;
272
qreal height() const { return ascent + descent + 1.; }
273
void setDefaultHeight(QTextEngine *eng);
275
Q_DECLARE_TYPEINFO(QScriptLine, Q_PRIMITIVE_TYPE);
277
typedef QVector<QScriptLine> QScriptLineArray;
280
class QTextFormatCollection;
282
class Q_GUI_EXPORT QTextEngine {
285
QTextEngine(const QString &str, QFontPrivate *f);
293
RightToLeft = 0x0001,
295
DesignMetrics = 0x0002
297
Q_DECLARE_FLAGS(ShaperFlags, ShaperFlag)
301
void validate() const;
302
void itemize() const;
304
static void bidiReorder(int numRuns, const quint8 *levels, int *visualOrder);
306
const QCharAttributes *attributes();
308
void shape(int item) const;
310
void justify(const QScriptLine &si);
312
qreal width(int charFrom, int numChars) const;
313
glyph_metrics_t boundingBox(int from, int len) const;
315
int length(int item) const {
316
const QScriptItem &si = layoutData->items[item];
317
int from = si.position;
319
return (item < layoutData->items.size() ? layoutData->items[item].position : layoutData->string.length()) - from;
321
int length(const QScriptItem *si) const {
323
if (si + 1 < layoutData->items.constData()+ layoutData->items.size())
324
end = (si+1)->position;
326
end = layoutData->string.length();
327
return end - si->position;
330
QFontEngine *fontEngine(const QScriptItem &si) const;
331
QFont font(const QScriptItem &si) const;
334
unsigned short *logClustersPtr;
335
QGlyphLayout *glyphPtr;
337
inline unsigned short *logClusters(const QScriptItem *si) const
338
{ return logClustersPtr+si->position; }
339
inline QGlyphLayout *glyphs(const QScriptItem *si) const
340
{ return glyphPtr + si->glyph_data_offset; }
342
void reallocate(int totalGlyphs);
343
inline void ensureSpace(int nGlyphs) const {
344
if (layoutData->num_glyphs - layoutData->used < nGlyphs)
345
const_cast<QTextEngine *>(this)->reallocate((((layoutData->used + nGlyphs)*3/2 + 15) >> 4) << 4);
350
int findItem(int strPos) const;
351
inline QTextFormatCollection *formats() const {
352
return block.docHandle()->formatCollection();
354
QTextFormat format(const QScriptItem *si) const;
355
inline QAbstractTextDocumentLayout *docLayout() const {
356
return block.docHandle()->document()->documentLayout();
358
int formatIndex(const QScriptItem *si) const;
360
qreal nextTab(const QScriptItem *si, qreal x);
362
mutable QScriptLineArray lines;
374
uint cacheGlyphs : 1;
376
int *underlinePositions;
381
mutable QScriptItemArray items;
388
bool haveCharAttributes;
391
mutable LayoutData *layoutData;
396
QList<QTextLayout::FormatRange> addFormats;
398
SpecialData *specialData;
400
bool atWordSeparator(int position) const;
403
void setBoundary(int strPos) const;
404
void addRequiredBoundaries() const;
405
void shapeText(int item) const;
406
void splitItem(int item, int pos) const;
410
#endif // QTEXTENGINE_P_H