~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/gui/text/qtextengine_p.h

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the text module of the Qt Toolkit.
 
6
**
 
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.
 
10
**
 
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.
 
15
**
 
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.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
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.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#ifndef QTEXTENGINE_P_H
 
30
#define QTEXTENGINE_P_H
 
31
 
 
32
//
 
33
//  W A R N I N G
 
34
//  -------------
 
35
//
 
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.
 
39
//
 
40
// We mean it.
 
41
//
 
42
 
 
43
#include "qglobal.h"
 
44
#include "qstring.h"
 
45
#include "qnamespace.h"
 
46
#include "qtextlayout.h"
 
47
#include "qtextformat_p.h"
 
48
#include "qfont_p.h"
 
49
#include <qvector.h>
 
50
#include <qpaintengine.h>
 
51
#include "qtextobject.h"
 
52
#include "qtextoption.h"
 
53
#include "qtextdocument_p.h"
 
54
#include "qset.h"
 
55
 
 
56
#include <stdlib.h>
 
57
#ifndef Q_OS_TEMP
 
58
#include <assert.h>
 
59
#endif // Q_OS_TEMP
 
60
 
 
61
class QFontPrivate;
 
62
class QFontEngine;
 
63
 
 
64
class QString;
 
65
class QOpenType;
 
66
class QPainter;
 
67
 
 
68
class QAbstractTextDocumentLayout;
 
69
 
 
70
class QTextItemInt : public QTextItem
 
71
{
 
72
public:
 
73
    qreal descent;
 
74
    qreal ascent;
 
75
    qreal width;
 
76
 
 
77
    RenderFlags flags;
 
78
    int num_chars;
 
79
    const QChar *chars;
 
80
    const QFont *f;
 
81
 
 
82
    QGlyphLayout *glyphs;
 
83
    int num_glyphs;
 
84
    QFontEngine *fontEngine;
 
85
};
 
86
 
 
87
 
 
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
 
92
// xoo and yoff
 
93
struct glyph_metrics_t
 
94
{
 
95
    inline glyph_metrics_t()
 
96
        : x(100000), y(100000),
 
97
          width(0), height(0), xoff(0), yoff(0)
 
98
        {}
 
99
    inline glyph_metrics_t(qreal _x, qreal _y, qreal _width, qreal _height, qreal _xoff, qreal _yoff)
 
100
        : x(_x),
 
101
          y(_y),
 
102
          width(_width),
 
103
          height(_height),
 
104
          xoff(_xoff),
 
105
          yoff(_yoff)
 
106
        {}
 
107
    qreal x;
 
108
    qreal y;
 
109
    qreal width;
 
110
    qreal height;
 
111
    qreal xoff;
 
112
    qreal yoff;
 
113
};
 
114
Q_DECLARE_TYPEINFO(glyph_metrics_t, Q_PRIMITIVE_TYPE);
 
115
 
 
116
typedef unsigned int glyph_t;
 
117
 
 
118
#if defined(Q_WS_X11) || defined (Q_WS_QWS) || defined (Q_WS_MAC)
 
119
 
 
120
 
 
121
struct QScriptAnalysis
 
122
{
 
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) {
 
128
        return
 
129
            script == other.script &&
 
130
            bidiLevel == other.bidiLevel;
 
131
        // ###
 
132
//             && override == other.override;
 
133
    }
 
134
 
 
135
};
 
136
Q_DECLARE_TYPEINFO(QScriptAnalysis, Q_PRIMITIVE_TYPE);
 
137
 
 
138
#elif defined(Q_WS_WIN)
 
139
 
 
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;
 
159
};
 
160
Q_DECLARE_TYPEINFO(QScriptAnalysis, Q_PRIMITIVE_TYPE);
 
161
 
 
162
inline bool operator == (const QScriptAnalysis &sa1, const QScriptAnalysis &sa2)
 
163
{
 
164
    return
 
165
        sa1.script == sa2.script &&
 
166
        sa1.bidiLevel == sa2.bidiLevel;
 
167
        // ###
 
168
//             && override == other.override;
 
169
}
 
170
 
 
171
#endif
 
172
 
 
173
struct QGlyphLayout
 
174
{
 
175
    inline QGlyphLayout()
 
176
        : glyph(0), justificationType(0), nKashidas(0), space_18d6(0)
 
177
        {}
 
178
 
 
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.
 
183
    enum Justification {
 
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
 
195
    };
 
196
 
 
197
    glyph_t glyph;
 
198
    struct Attributes {
 
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;
 
205
    };
 
206
    Attributes attributes;
 
207
    QPointF advance;
 
208
    QPointF offset;
 
209
 
 
210
    enum JustificationType {
 
211
        JustifyNone,
 
212
        JustifySpace,
 
213
        JustifyKashida
 
214
    };
 
215
    uint justificationType :2;
 
216
    uint nKashidas : 6; // more do not make sense...
 
217
    uint space_18d6 : 24;
 
218
};
 
219
Q_DECLARE_TYPEINFO(QGlyphLayout, Q_PRIMITIVE_TYPE);
 
220
 
 
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)
 
227
    uchar invalid        :1;
 
228
    uchar reserved       :3;
 
229
};
 
230
Q_DECLARE_TYPEINFO(QCharAttributes, Q_PRIMITIVE_TYPE);
 
231
 
 
232
struct QScriptItem
 
233
{
 
234
    inline QScriptItem() : position(0), isSpace(false), isTab(false),
 
235
                           isObject(false),
 
236
                           num_glyphs(0), descent(-1), ascent(-1), width(-1),
 
237
                           glyph_data_offset(0)
 
238
        { }
 
239
 
 
240
    int position;
 
241
    QScriptAnalysis analysis;
 
242
    unsigned short isSpace  : 1;
 
243
    unsigned short isTab    : 1;
 
244
    unsigned short isObject : 1;
 
245
    int num_glyphs;
 
246
    qreal descent;
 
247
    qreal ascent;
 
248
    qreal width;
 
249
    int glyph_data_offset;
 
250
    qreal height() const { return ascent + descent; }
 
251
};
 
252
 
 
253
 
 
254
Q_DECLARE_TYPEINFO(QScriptItem, Q_MOVABLE_TYPE);
 
255
 
 
256
typedef QVector<QScriptItem> QScriptItemArray;
 
257
 
 
258
struct QScriptLine
 
259
{
 
260
    QScriptLine()
 
261
        : descent(0), ascent(0), x(0), y(0), width(0), textWidth(0) {}
 
262
    qreal descent;
 
263
    qreal ascent;
 
264
    qreal x;
 
265
    qreal y;
 
266
    qreal width;
 
267
    qreal textWidth;
 
268
    int from;
 
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);
 
274
};
 
275
Q_DECLARE_TYPEINFO(QScriptLine, Q_PRIMITIVE_TYPE);
 
276
 
 
277
typedef QVector<QScriptLine> QScriptLineArray;
 
278
 
 
279
class QFontPrivate;
 
280
class QTextFormatCollection;
 
281
 
 
282
class Q_GUI_EXPORT QTextEngine {
 
283
public:
 
284
    QTextEngine();
 
285
    QTextEngine(const QString &str, QFontPrivate *f);
 
286
    ~QTextEngine();
 
287
 
 
288
    enum Mode {
 
289
        WidthOnly = 0x07
 
290
    };
 
291
 
 
292
    enum ShaperFlag {
 
293
        RightToLeft = 0x0001,
 
294
        Mirrored = 0x0001,
 
295
        DesignMetrics = 0x0002
 
296
    };
 
297
    Q_DECLARE_FLAGS(ShaperFlags, ShaperFlag)
 
298
 
 
299
    void invalidate();
 
300
 
 
301
    void validate() const;
 
302
    void itemize() const;
 
303
 
 
304
    static void bidiReorder(int numRuns, const quint8 *levels, int *visualOrder);
 
305
 
 
306
    const QCharAttributes *attributes();
 
307
 
 
308
    void shape(int item) const;
 
309
 
 
310
    void justify(const QScriptLine &si);
 
311
 
 
312
    qreal width(int charFrom, int numChars) const;
 
313
    glyph_metrics_t boundingBox(int from,  int len) const;
 
314
 
 
315
    int length(int item) const {
 
316
        const QScriptItem &si = layoutData->items[item];
 
317
        int from = si.position;
 
318
        item++;
 
319
        return (item < layoutData->items.size() ? layoutData->items[item].position : layoutData->string.length()) - from;
 
320
    }
 
321
    int length(const QScriptItem *si) const {
 
322
        int end;
 
323
        if (si + 1 < layoutData->items.constData()+ layoutData->items.size())
 
324
            end = (si+1)->position;
 
325
        else
 
326
            end = layoutData->string.length();
 
327
        return end - si->position;
 
328
    }
 
329
 
 
330
    QFontEngine *fontEngine(const QScriptItem &si) const;
 
331
    QFont font(const QScriptItem &si) const;
 
332
    QFont font() const;
 
333
 
 
334
    unsigned short *logClustersPtr;
 
335
    QGlyphLayout *glyphPtr;
 
336
 
 
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; }
 
341
 
 
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);
 
346
    }
 
347
 
 
348
    void freeMemory();
 
349
 
 
350
    int findItem(int strPos) const;
 
351
    inline QTextFormatCollection *formats() const {
 
352
        return block.docHandle()->formatCollection();
 
353
    }
 
354
    QTextFormat format(const QScriptItem *si) const;
 
355
    inline QAbstractTextDocumentLayout *docLayout() const {
 
356
        return block.docHandle()->document()->documentLayout();
 
357
    }
 
358
    int formatIndex(const QScriptItem *si) const;
 
359
 
 
360
    qreal nextTab(const QScriptItem *si, qreal x);
 
361
 
 
362
    mutable QScriptLineArray lines;
 
363
 
 
364
    QString text;
 
365
    QFontPrivate *fnt;
 
366
    QTextBlock block;
 
367
 
 
368
    QTextOption option;
 
369
 
 
370
    qreal minWidth;
 
371
    qreal maxWidth;
 
372
    QPointF position;
 
373
    uint ignoreBidi : 1;
 
374
    uint cacheGlyphs : 1;
 
375
 
 
376
    int *underlinePositions;
 
377
 
 
378
    struct LayoutData {
 
379
        LayoutData();
 
380
        ~LayoutData();
 
381
        mutable QScriptItemArray items;
 
382
        int allocated;
 
383
        void **memory;
 
384
        int num_glyphs;
 
385
        mutable int used;
 
386
        uint hasBidi : 1;
 
387
        uint inLayout : 1;
 
388
        bool haveCharAttributes;
 
389
        QString string;
 
390
    };
 
391
    mutable LayoutData *layoutData;
 
392
 
 
393
    struct SpecialData {
 
394
        int preeditPosition;
 
395
        QString preeditText;
 
396
        QList<QTextLayout::FormatRange> addFormats;
 
397
    };
 
398
    SpecialData *specialData;
 
399
 
 
400
    bool atWordSeparator(int position) const;
 
401
 
 
402
private:
 
403
    void setBoundary(int strPos) const;
 
404
    void addRequiredBoundaries() const;
 
405
    void shapeText(int item) const;
 
406
    void splitItem(int item, int pos) const;
 
407
 
 
408
};
 
409
 
 
410
#endif // QTEXTENGINE_P_H