source: trunk/src/gui/text/qfontengine_qws.cpp@ 563

Last change on this file since 563 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

  • Property svn:eol-style set to native
File size: 16.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qfontengine_p.h"
43#include <private/qunicodetables_p.h>
44#include <qwsdisplay_qws.h>
45#include <qvarlengtharray.h>
46#include <private/qpainter_p.h>
47#include <private/qpaintengine_raster_p.h>
48#include <private/qpdf_p.h>
49#include "qtextengine_p.h"
50#include "private/qcore_unix_p.h" // overrides QT_OPEN
51
52#include <qdebug.h>
53
54
55#ifndef QT_NO_QWS_QPF
56
57#include "qfile.h"
58#include "qdir.h"
59
60#define QT_USE_MMAP
61#include <stdlib.h>
62
63#ifdef QT_USE_MMAP
64// for mmap
65#include <unistd.h>
66#include <sys/types.h>
67#include <sys/stat.h>
68#include <sys/mman.h>
69#include <fcntl.h>
70#include <errno.h>
71
72# if defined(QT_LINUXBASE) && !defined(MAP_FILE)
73 // LSB 3.2 does not define MAP_FILE
74# define MAP_FILE 0
75# endif
76
77#endif
78
79#endif // QT_NO_QWS_QPF
80
81QT_BEGIN_NAMESPACE
82
83#ifndef QT_NO_QWS_QPF
84QT_BEGIN_INCLUDE_NAMESPACE
85#include "qplatformdefs.h"
86QT_END_INCLUDE_NAMESPACE
87
88static inline unsigned int getChar(const QChar *str, int &i, const int len)
89{
90 unsigned int uc = str[i].unicode();
91 if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {
92 uint low = str[i+1].unicode();
93 if (low >= 0xdc00 && low < 0xe000) {
94 uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
95 ++i;
96 }
97 }
98 return uc;
99}
100
101#define FM_SMOOTH 1
102
103
104class Q_PACKED QPFGlyphMetrics {
105
106public:
107 quint8 linestep;
108 quint8 width;
109 quint8 height;
110 quint8 flags;
111
112 qint8 bearingx; // Difference from pen position to glyph's left bbox
113 quint8 advance; // Difference between pen positions
114 qint8 bearingy; // Used for putting characters on baseline
115
116 qint8 reserved; // Do not use
117
118 // Flags:
119 // RendererOwnsData - the renderer is responsible for glyph data
120 // memory deletion otherwise QPFGlyphTree must
121 // delete [] the data when the glyph is deleted.
122 enum Flags { RendererOwnsData=0x01 };
123};
124
125class QPFGlyph {
126public:
127 QPFGlyph() { metrics=0; data=0; }
128 QPFGlyph(QPFGlyphMetrics* m, uchar* d) :
129 metrics(m), data(d) { }
130 ~QPFGlyph() {}
131
132 QPFGlyphMetrics* metrics;
133 uchar* data;
134};
135
136struct Q_PACKED QPFFontMetrics{
137 qint8 ascent,descent;
138 qint8 leftbearing,rightbearing;
139 quint8 maxwidth;
140 qint8 leading;
141 quint8 flags;
142 quint8 underlinepos;
143 quint8 underlinewidth;
144 quint8 reserved3;
145};
146
147
148class QPFGlyphTree {
149public:
150 /* reads in a tree like this:
151
152 A-Z
153 / \
154 0-9 a-z
155
156 etc.
157
158 */
159 glyph_t min,max;
160 QPFGlyphTree* less;
161 QPFGlyphTree* more;
162 QPFGlyph* glyph;
163public:
164#ifdef QT_USE_MMAP
165 QPFGlyphTree(uchar*& data)
166 {
167 read(data);
168 }
169#else
170 QPFGlyphTree(QIODevice& f)
171 {
172 read(f);
173 }
174#endif
175
176 ~QPFGlyphTree()
177 {
178 // NOTE: does not delete glyph[*].metrics or .data.
179 // the caller does this (only they know who owns
180 // the data). See clear().
181 delete less;
182 delete more;
183 delete [] glyph;
184 }
185
186 bool inFont(glyph_t g) const
187 {
188 if ( g < min ) {
189 if ( !less )
190 return false;
191 return less->inFont(g);
192 } else if ( g > max ) {
193 if ( !more )
194 return false;
195 return more->inFont(g);
196 }
197 return true;
198 }
199
200 QPFGlyph* get(glyph_t g)
201 {
202 if ( g < min ) {
203 if ( !less )
204 return 0;
205 return less->get(g);
206 } else if ( g > max ) {
207 if ( !more )
208 return 0;
209 return more->get(g);
210 }
211 return &glyph[g - min];
212 }
213 int totalChars() const
214 {
215 if ( !this ) return 0;
216 return max-min+1 + less->totalChars() + more->totalChars();
217 }
218 int weight() const
219 {
220 if ( !this ) return 0;
221 return 1 + less->weight() + more->weight();
222 }
223
224 void dump(int indent=0)
225 {
226 for (int i=0; i<indent; i++) printf(" ");
227 printf("%d..%d",min,max);
228 //if ( indent == 0 )
229 printf(" (total %d)",totalChars());
230 printf("\n");
231 if ( less ) less->dump(indent+1);
232 if ( more ) more->dump(indent+1);
233 }
234
235private:
236 QPFGlyphTree()
237 {
238 }
239
240#ifdef QT_USE_MMAP
241 void read(uchar*& data)
242 {
243 // All node data first
244 readNode(data);
245 // Then all non-video data
246 readMetrics(data);
247 // Then all video data
248 readData(data);
249 }
250#else
251 void read(QIODevice& f)
252 {
253 // All node data first
254 readNode(f);
255 // Then all non-video data
256 readMetrics(f);
257 // Then all video data
258 readData(f);
259 }
260#endif
261
262#ifdef QT_USE_MMAP
263 void readNode(uchar*& data)
264 {
265 uchar rw = *data++;
266 uchar cl = *data++;
267 min = (rw << 8) | cl;
268 rw = *data++;
269 cl = *data++;
270 max = (rw << 8) | cl;
271 int flags = *data++;
272 if ( flags & 1 )
273 less = new QPFGlyphTree;
274 else
275 less = 0;
276 if ( flags & 2 )
277 more = new QPFGlyphTree;
278 else
279 more = 0;
280 int n = max-min+1;
281 glyph = new QPFGlyph[n];
282
283 if ( less )
284 less->readNode(data);
285 if ( more )
286 more->readNode(data);
287 }
288#else
289 void readNode(QIODevice& f)
290 {
291 uchar rw = f.getch();
292 uchar cl = f.getch();
293 min = (rw << 8) | cl;