Qt 4.8
qfontengine_qws.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qfontengine_p.h"
43 #include <qwsdisplay_qws.h>
44 #include <qvarlengtharray.h>
45 #include <private/qpainter_p.h>
46 #include <private/qpaintengine_raster_p.h>
47 #include <private/qpdf_p.h>
48 #include "qtextengine_p.h"
49 #include "private/qcore_unix_p.h" // overrides QT_OPEN
50 
51 #include <qdebug.h>
52 
53 #ifndef QT_NO_QWS_QPF
54 
55 #include "qplatformdefs.h"
56 #include "qfile.h"
57 
58 #include <stdlib.h>
59 
60 #if !defined(Q_OS_INTEGRITY)
61 #define QT_USE_MMAP
62 #endif
63 
64 #ifdef QT_USE_MMAP
65 // for mmap
66 #include <unistd.h>
67 #include <sys/types.h>
68 #include <sys/stat.h>
69 #include <sys/mman.h>
70 #include <fcntl.h>
71 #include <errno.h>
72 
73 #ifndef MAP_FILE
74 # define MAP_FILE 0
75 #endif
76 #ifndef MAP_FAILED
77 # define MAP_FAILED (void *)-1
78 #endif
79 
80 #endif // QT_USE_MMAP
81 
83 
84 static inline unsigned int getChar(const QChar *str, int &i, const int len)
85 {
86  uint ucs4 = str[i].unicode();
87  if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) {
88  ++i;
89  ucs4 = QChar::surrogateToUcs4(ucs4, str[i].unicode());
90  }
91  return ucs4;
92 }
93 
94 #define FM_SMOOTH 1
95 
96 
98 
99 public:
104 
105  qint8 bearingx; // Difference from pen position to glyph's left bbox
106  quint8 advance; // Difference between pen positions
107  qint8 bearingy; // Used for putting characters on baseline
108 
109  qint8 reserved; // Do not use
110 
111  // Flags:
112  // RendererOwnsData - the renderer is responsible for glyph data
113  // memory deletion otherwise QPFGlyphTree must
114  // delete [] the data when the glyph is deleted.
115  enum Flags { RendererOwnsData=0x01 };
116 };
117 
118 class QPFGlyph {
119 public:
120  QPFGlyph() { metrics=0; data=0; }
122  metrics(m), data(d) { }
124 
127 };
128 
130  qint8 ascent,descent;
131  qint8 leftbearing,rightbearing;
138 };
139 
140 
142 public:
143  /* reads in a tree like this:
144 
145  A-Z
146  / \
147  0-9 a-z
148 
149  etc.
150 
151  */
156 public:
158  {
159  read(data);
160  }
161 
163  {
164  // NOTE: does not delete glyph[*].metrics or .data.
165  // the caller does this (only they know who owns
166  // the data). See clear().
167  delete less;
168  delete more;
169  delete [] glyph;
170  }
171 
172  bool inFont(glyph_t g) const
173  {
174  if ( g < min ) {
175  if ( !less )
176  return false;
177  return less->inFont(g);
178  } else if ( g > max ) {
179  if ( !more )
180  return false;
181  return more->inFont(g);
182  }
183  return true;
184  }
185 
187  {
188  if ( g < min ) {
189  if ( !less )
190  return 0;
191  return less->get(g);
192  } else if ( g > max ) {
193  if ( !more )
194  return 0;
195  return more->get(g);
196  }
197  return &glyph[g - min];
198  }
199  int totalChars() const
200  {
201  if ( !this ) return 0;
202  return max-min+1 + less->totalChars() + more->totalChars();
203  }
204  int weight() const
205  {
206  if ( !this ) return 0;
207  return 1 + less->weight() + more->weight();
208  }
209 
210  void dump(int indent=0)
211  {
212  for (int i=0; i<indent; i++) printf(" ");
213  printf("%d..%d",min,max);
214  //if ( indent == 0 )
215  printf(" (total %d)",totalChars());
216  printf("\n");
217  if ( less ) less->dump(indent+1);
218  if ( more ) more->dump(indent+1);
219  }
220 
221 private:
223  {
224  }
225 
226  void read(uchar*& data)
227  {
228  // All node data first
229  readNode(data);
230  // Then all non-video data
231  readMetrics(data);
232  // Then all video data
233  readData(data);
234  }
235 
237  {
238  uchar rw = *data++;
239  uchar cl = *data++;
240  min = (rw << 8) | cl;
241  rw = *data++;
242  cl = *data++;
243  max = (rw << 8) | cl;
244  int flags = *data++;
245  if ( flags & 1 )
246  less = new QPFGlyphTree;
247  else
248  less = 0;
249  if ( flags & 2 )
250  more = new QPFGlyphTree;
251  else
252  more = 0;
253  int n = max-min+1;
254  glyph = new QPFGlyph[n];
255 
256  if ( less )
257  less->readNode(data);
258  if ( more )
259  more->readNode(data);
260  }
261 
263  {
264  int n = max-min+1;
265  for (int i=0; i<n; i++) {
266  glyph[i].metrics = (QPFGlyphMetrics*)data;
267  data += sizeof(QPFGlyphMetrics);
268  }
269  if ( less )
270  less->readMetrics(data);
271  if ( more )
272  more->readMetrics(data);
273  }
274 
276  {
277  int n = max-min+1;
278  for (int i=0; i<n; i++) {
279  QSize s( glyph[i].metrics->width, glyph[i].metrics->height );
280  //######### s = qt_screen->mapToDevice( s );
281  uint datasize = glyph[i].metrics->linestep * s.height();
282  glyph[i].data = data; data += datasize;
283  }
284  if ( less )
285  less->readData(data);
286  if ( more )
287  more->readData(data);
288  }
289 };
290 
292 {
293 public:
297  size_t mmapLength;
298 #ifdef QT_USE_MMAP
299  bool used_mmap;
300 #endif
301 };
302 
304 {
305  cache_cost = 1;
306 
307  int fd = QT_OPEN(QFile::encodeName(fn).constData(), O_RDONLY, 0);
308  if (fd == -1)
309  qFatal("Failed to open '%s'", QFile::encodeName(fn).constData());
310 
311  QT_STATBUF st;
312  if (QT_FSTAT(fd, &st) != 0)
313  qFatal("Failed to stat '%s'", QFile::encodeName(fn).constData());
314 
315  d = new QFontEngineQPF1Data;
316  d->mmapStart = 0;
317  d->mmapLength = st.st_size;
318 
319 #ifdef QT_USE_MMAP
320  d->used_mmap = true;
321  d->mmapStart = (uchar *)::mmap(0, st.st_size, // any address, whole file
322  PROT_READ, // read-only memory
323  MAP_FILE | MAP_PRIVATE, // swap-backed map from file
324  fd, 0); // from offset 0 of fd
325  if (d->mmapStart == (uchar *)MAP_FAILED)
326  d->mmapStart = 0;
327 #endif
328 
329  if (!d->mmapStart) {
330 #ifdef QT_USE_MMAP
331  d->used_mmap = false;
332 #endif
333  d->mmapStart = new uchar[d->mmapLength];
334  if (QT_READ(fd, d->mmapStart, d->mmapLength) != (qint64)d->mmapLength)
335  qFatal("Failed to read '%s'", QFile::encodeName(fn).constData());
336  }
337  QT_CLOSE(fd);
338 
339  if (d->mmapStart) {
340  uchar* data = d->mmapStart;
341 
342  memcpy(reinterpret_cast<char*>(&d->fm), data, sizeof(d->fm));
343  data += sizeof(d->fm);
344 
345  d->tree = new QPFGlyphTree(data);
346  glyphFormat = (d->fm.flags & FM_SMOOTH) ? QFontEngineGlyphCache::Raster_A8
348 #if 0
349  qDebug() << "font file" << fn
350  << "ascent" << d->fm.ascent << "descent" << d->fm.descent
351  << "leftbearing" << d->fm.leftbearing
352  << "rightbearing" << d->fm.rightbearing
353  << "maxwidth" << d->fm.maxwidth
354  << "leading" << d->fm.leading
355  << "flags" << d->fm.flags
356  << "underlinepos" << d->fm.underlinepos
357  << "underlinewidth" << d->fm.underlinewidth;
358 #endif
359  }
360 }
361 
363 {
364  if (d->mmapStart) {
365 #if defined(QT_USE_MMAP)
366  if (d->used_mmap)
367  ::munmap(d->mmapStart, d->mmapLength);
368  else
369 #endif
370  delete [] d->mmapStart;
371  }
372  delete d->tree;
373  delete d;
374 }
375 
376 
377 bool QFontEngineQPF1::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
378 {
379  if(*nglyphs < len) {
380  *nglyphs = len;
381  return false;
382  }
383  *nglyphs = 0;
384 
385  bool mirrored = flags & QTextEngine::RightToLeft;
386  for(int i = 0; i < len; i++) {
387  unsigned int uc = getChar(str, i, len);
388  if (mirrored)
389  uc = QChar::mirroredChar(uc);
390  glyphs->glyphs[*nglyphs] = uc < 0x10000 ? uc : 0;
391  ++*nglyphs;
392  }
393 
394  glyphs->numGlyphs = *nglyphs;
395 
396  if (flags & QTextEngine::GlyphIndicesOnly)
397  return true;
398 
399  recalcAdvances(glyphs, flags);
400 
401  return true;
402 }
403 
404 void QFontEngineQPF1::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags) const
405 {
406  for(int i = 0; i < glyphs->numGlyphs; i++) {
407  QPFGlyph *glyph = d->tree->get(glyphs->glyphs[i]);
408 
409  glyphs->advances_x[i] = glyph ? glyph->metrics->advance : 0;
410  glyphs->advances_y[i] = 0;
411 
412  if (!glyph)
413  glyphs->glyphs[i] = 0;
414  }
415 }
416 
418 {
419  QPaintEngineState *pState = p->state;
420  QRasterPaintEngine *paintEngine = static_cast<QRasterPaintEngine*>(p);
421 
422  QTransform matrix = pState->transform();
423  matrix.translate(_x, _y);
424  QFixed x = QFixed::fromReal(matrix.dx());
425  QFixed y = QFixed::fromReal(matrix.dy());
426 
429  getGlyphPositions(si.glyphs, matrix, si.flags, glyphs, positions);
430  if (glyphs.size() == 0)
431  return;
432 
433  int depth = (d->fm.flags & FM_SMOOTH) ? 8 : 1;
434  for(int i = 0; i < glyphs.size(); i++) {
435  const QPFGlyph *glyph = d->tree->get(glyphs[i]);
436  if (!glyph)
437  continue;
438 
439  int bpl = glyph->metrics->linestep;
440 
441  if(glyph->data)
442  paintEngine->alphaPenBlt(glyph->data, bpl, depth,
443  qRound(positions[i].x) + glyph->metrics->bearingx,
444  qRound(positions[i].y) - glyph->metrics->bearingy,
445  glyph->metrics->width,glyph->metrics->height);
446  }
447 }
448 
449 
451 {
452  const QPFGlyph *glyph = d->tree->get(g);
453  if (!glyph)
454  return QImage();
455 
456  int mono = !(d->fm.flags & FM_SMOOTH);
457 
458  const uchar *bits = glyph->data;//((const uchar *) glyph);
459 
460  QImage image;
461  if (mono) {
462  image = QImage((glyph->metrics->width+7)&~7, glyph->metrics->height, QImage::Format_Mono);
463  image.setColor(0, qRgba(0, 0, 0, 0));
464  image.setColor(1, qRgba(0, 0, 0, 255));
465  } else {
466  image = QImage(glyph->metrics->width, glyph->metrics->height, QImage::Format_Indexed8);
467  for (int j=0; j<256; ++j)
468  image.setColor(j, qRgba(0, 0, 0, j));
469  }
470  for (int i=0; i<glyph->metrics->height; ++i) {
471  memcpy(image.scanLine(i), bits, glyph->metrics->linestep);
472  bits += glyph->metrics->linestep;
473  }
474  return image;
475 }
476 
477 
478 
479 void QFontEngineQPF1::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
480 {
481  addBitmapFontToPath(x, y, glyphs, path, flags);
482 }
483 
485 {
486  if (glyphs.numGlyphs == 0)
487  return glyph_metrics_t();
488 
489  QFixed w = 0;
490  for (int i = 0; i < glyphs.numGlyphs; ++i)
491  w += glyphs.effectiveAdvance(i);
492  return glyph_metrics_t(0, -ascent(), w - lastRightBearing(glyphs), ascent()+descent()+1, w, 0);
493 }
494 
496 {
497  const QPFGlyph *g = d->tree->get(glyph);
498  if (!g)
499  return glyph_metrics_t();
500  Q_ASSERT(g);
502  g->metrics->width, g->metrics->height,
503  g->metrics->advance, 0);
504 }
505 
507 {
508  return d->fm.ascent;
509 }
510 
512 {
513  return d->fm.descent;
514 }
515 
517 {
518  return d->fm.leading;
519 }
520 
522 {
523  return d->fm.maxwidth;
524 }
525 /*
526 const char *QFontEngineQPF1::name() const
527 {
528  return "qt";
529 }
530 */
531 bool QFontEngineQPF1::canRender(const QChar *str, int len)
532 {
533  for(int i = 0; i < len; i++)
534  if (!d->tree->inFont(str[i].unicode()))
535  return false;
536  return true;
537 }
538 
540 {
541  return QPF1;
542 }
543 
545 {
546  return d->fm.leftbearing;
547 }
548 
550 {
551  return d->fm.rightbearing;
552 }
553 
555 {
556  return d->fm.underlinepos;
557 }
558 
560 {
561  return d->fm.underlinewidth;
562 }
563 
564 #endif //QT_NO_QWS_QPF
565 
virtual QFixed leading() const
double d
Definition: qnumeric_p.h:62
virtual QFixed underlinePosition() const
QPFGlyph * get(glyph_t g)
QPFGlyphTree * less
#define Q_PACKED
Definition: qglobal.h:815
QPFGlyphTree(uchar *&data)
qreal dy() const
Returns the vertical translation factor.
Definition: qtransform.h:277
QFixed * advances_y
void setColor(int i, QRgb c)
Sets the color at the given index in the color table, to the given to colorValue. ...
Definition: qimage.cpp:1850
double qreal
Definition: qglobal.h:1193
virtual bool canRender(const QChar *string, int len)
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QFixed * advances_x
int weight() const
void read(uchar *&data)
ushort unicode() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qchar.h:251
The QPainterPath class provides a container for painting operations, enabling graphical shapes to be ...
Definition: qpainterpath.h:67
HB_Glyph * glyphs
QPaintEngineState * state
Definition: qpaintengine.h:239
virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const
RenderFlags flags
QTransform transform() const
Returns the matrix in the current paint engine state.
Definition: qpainter.cpp:9377
#define O_RDONLY
void readMetrics(uchar *&data)
virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs)
virtual qreal minLeftBearing() const
virtual void draw(QPaintEngine *p, qreal x, qreal y, const QTextItemInt &si)
unsigned char quint8
Definition: qglobal.h:934
QTransform & translate(qreal dx, qreal dy)
Moves the coordinate system dx along the x axis and dy along the y axis, and returns a reference to t...
Definition: qtransform.cpp:417
The QString class provides a Unicode character string.
Definition: qstring.h:83
static QFixed fromReal(qreal r)
Definition: qfixed_p.h:70
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
virtual QFixed descent() const
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
#define QT_READ
Definition: qcore_unix_p.h:280
Q_CORE_EXPORT void qDebug(const char *,...)
QGlyphLayout glyphs
signed char qint8
Definition: qglobal.h:933
unsigned char uchar
Definition: qglobal.h:994
void readData(uchar *&data)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
#define MAP_FAILED
Q_GUI_EXPORT_INLINE QRgb qRgba(int r, int g, int b, int a)
Definition: qrgb.h:72
bool inFont(glyph_t g) const
virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
int totalChars() const
static const QCssKnownValue positions[NumKnownPositionModes - 1]
Definition: qcssparser.cpp:329
virtual QFixed ascent() const
QChar mirroredChar() const
Returns the mirrored character if this character is a mirrored character; otherwise returns the chara...
Definition: qchar.cpp:1016
QPFGlyph * glyph
QFontEngineQPF1(const QFontDef &, const QString &fn)
void dump(int indent=0)
Internal QTextItem.
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
static const char * data(const QByteArray &arr)
QPFGlyph(QPFGlyphMetrics *m, uchar *d)
unsigned int uint
Definition: qglobal.h:996
static unsigned int getChar(const QChar *str, int &i, const int len)
__int64 qint64
Definition: qglobal.h:942
virtual Type type() const
The QPaintEngine class provides an abstract definition of how QPainter draws to a given device on a g...
Definition: qpaintengine.h:90
virtual void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
void readNode(uchar *&data)
Q_CORE_EXPORT void qFatal(const char *,...)
#define FM_SMOOTH
QPFGlyphTree * more
#define QT_OPEN
Definition: qcore_unix_p.h:186
void alphaPenBlt(const void *src, int bpl, int depth, int rx, int ry, int w, int h)
#define st(var, type, card)
QPFGlyphMetrics * metrics
int height() const
Returns the height.
Definition: qsize.h:129
if(void) toggleToolbarShown
static uint surrogateToUcs4(ushort high, ushort low)
Converts a UTF16 surrogate pair with the given high and low values to its UCS-4 code point...
Definition: qchar.h:297
qreal dx() const
Returns the horizontal translation factor.
Definition: qtransform.h:273
QFixed effectiveAdvance(int item) const
The QPaintEngineState class provides information about the active paint engine&#39;s current state...
Definition: qpaintengine.h:289
static QByteArray encodeName(const QString &fileName)
By default, this function converts fileName to the local 8-bit encoding determined by the user&#39;s loca...
Definition: qfile.cpp:528
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
#define MAP_FILE
The QRasterPaintEngine class enables hardware acceleration of painting operations in Qt for Embedded ...
virtual qreal minRightBearing() const
unsigned int glyph_t
Q_DECL_CONSTEXPR int qRound(qreal d)
Definition: qglobal.h:1203
virtual qreal maxCharWidth() const
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
Definition: qimage.cpp:1886
int size() const
virtual QImage alphaMapForGlyph(glyph_t)
The QTransform class specifies 2D transformations of a coordinate system.
Definition: qtransform.h:65
virtual QFixed lineThickness() const
#define QT_CLOSE
Definition: qcore_unix_p.h:304