Qt 4.8
qfontengine_qpf.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_qpf_p.h"
43 
44 #include "private/qpaintengine_raster_p.h"
45 #include <QtCore/qlibraryinfo.h>
46 #include <QtCore/qfileinfo.h>
47 
48 #include <QtCore/qfile.h>
49 #include <QtCore/qdir.h>
50 #include <QtCore/qbuffer.h>
51 #if !defined(QT_NO_FREETYPE)
52 #include "private/qfontengine_ft_p.h"
53 #endif
54 #include "private/qcore_unix_p.h" // overrides QT_OPEN
55 
56 // for mmap
57 #include <stdlib.h>
58 #include <unistd.h>
59 #include <sys/types.h>
60 #include <sys/stat.h>
61 #include <sys/mman.h>
62 #include <fcntl.h>
63 #include <errno.h>
64 
66 
67 #ifndef QT_NO_QWS_QPF2
68 
69 #include "qpfutil.cpp"
70 
72 
73 #if defined(Q_WS_QWS)
74 # include "private/qwscommand_qws_p.h"
75 # include "qwsdisplay_qws.h"
76 # include "qabstractfontengine_p.h"
77 #endif
78 #include "qplatformdefs.h"
80 
81 //#define DEBUG_HEADER
82 //#define DEBUG_FONTENGINE
83 
84 #if defined(DEBUG_HEADER)
85 # define DEBUG_VERIFY qDebug
86 #else
87 # define DEBUG_VERIFY if (0) qDebug
88 #endif
89 
90 #define READ_VERIFY(type, variable) \
91  if (tagPtr + sizeof(type) > endPtr) { \
92  DEBUG_VERIFY() << "read verify failed in line" << __LINE__; \
93  return 0; \
94  } \
95  variable = qFromBigEndian<type>(tagPtr); \
96  DEBUG_VERIFY() << "read value" << variable << "of type " #type; \
97  tagPtr += sizeof(type)
98 
99 template <typename T>
100 T readValue(const uchar *&data)
101 {
102  T value = qFromBigEndian<T>(data);
103  data += sizeof(T);
104  return value;
105 }
106 
107 #define VERIFY(condition) \
108  if (!(condition)) { \
109  DEBUG_VERIFY() << "condition " #condition " failed in line" << __LINE__; \
110  return 0; \
111  }
112 
113 #define VERIFY_TAG(condition) \
114  if (!(condition)) { \
115  DEBUG_VERIFY() << "verifying tag condition " #condition " failed in line" << __LINE__ << "with tag" << tag; \
116  return 0; \
117  }
118 
119 static inline const uchar *verifyTag(const uchar *tagPtr, const uchar *endPtr)
120 {
121  quint16 tag, length;
122  READ_VERIFY(quint16, tag);
123  READ_VERIFY(quint16, length);
125  return endPtr;
126  if (tag < QFontEngineQPF::NumTags) {
127  switch (tagTypes[tag]) {
130  // can't do anything...
131  break;
133  VERIFY_TAG(length == sizeof(quint32));
134  break;
136  VERIFY_TAG(length == sizeof(quint32));
137  break;
139  VERIFY_TAG(length == sizeof(quint8));
140  break;
141  }
142 #if defined(DEBUG_HEADER)
143  if (length == 1)
144  qDebug() << "tag data" << hex << *tagPtr;
145  else if (length == 4)
146  qDebug() << "tag data" << hex << tagPtr[0] << tagPtr[1] << tagPtr[2] << tagPtr[3];
147 #endif
148  }
149  return tagPtr + length;
150 }
151 
153 {
154  if (!g || g >= glyphMapEntries)
155  return 0;
156  const quint32 *gmapPtr = reinterpret_cast<const quint32 *>(fontData + glyphMapOffset);
157  quint32 glyphPos = qFromBigEndian<quint32>(gmapPtr[g]);
158  if (glyphPos > glyphDataSize) {
159  if (glyphPos == 0xffffffff)
160  return 0;
161 #if defined(DEBUG_FONTENGINE)
162  qDebug() << "glyph" << g << "outside of glyphData, remapping font file";
163 #endif
164 #if !defined(QT_NO_FREETYPE) && !defined(QT_FONTS_ARE_RESOURCES)
165  const_cast<QFontEngineQPF *>(this)->remapFontData();
166 #endif
167  if (glyphPos > glyphDataSize)
168  return 0;
169  }
170  return reinterpret_cast<const Glyph *>(fontData + glyphDataOffset + glyphPos);
171 }
172 
174 {
175  VERIFY(size >= int(sizeof(Header)));
176  const Header *header = reinterpret_cast<const Header *>(data);
177  if (header->magic[0] != 'Q'
178  || header->magic[1] != 'P'
179  || header->magic[2] != 'F'
180  || header->magic[3] != '2')
181  return false;
182 
185  VERIFY(size >= int(sizeof(Header)) + dataSize);
186 
187  const uchar *tagPtr = data + sizeof(Header);
188  const uchar *tagEndPtr = tagPtr + dataSize;
189  while (tagPtr < tagEndPtr - 3) {
190  tagPtr = verifyTag(tagPtr, tagEndPtr);
191  VERIFY(tagPtr);
192  }
193 
194  VERIFY(tagPtr <= tagEndPtr);
195  return true;
196 }
197 
199 {
200  const Header *header = reinterpret_cast<const Header *>(data);
201  const uchar *tagPtr = data + sizeof(Header);
202  const uchar *endPtr = tagPtr + qFromBigEndian<quint16>(header->dataSize);
203  while (tagPtr < endPtr - 3) {
204  quint16 tag = readValue<quint16>(tagPtr);
205  quint16 length = readValue<quint16>(tagPtr);
206  if (tag == requestedTag) {
207  switch (tagTypes[requestedTag]) {
208  case StringType:
209  return QVariant(QString::fromUtf8(reinterpret_cast<const char *>(tagPtr), length));
210  case UInt32Type:
211  return QVariant(readValue<quint32>(tagPtr));
212  case UInt8Type:
213  return QVariant(uint(*tagPtr));
214  case FixedType:
215  return QVariant(QFixed::fromFixed(readValue<quint32>(tagPtr)).toReal());
216  case BitFieldType:
217  return QVariant(QByteArray(reinterpret_cast<const char *>(tagPtr), length));
218  }
219  return QVariant();
220  } else if (tag == Tag_EndOfHeader) {
221  break;
222  }
223  tagPtr += length;
224  }
225 
226  return QVariant();
227 }
228 
229 #endif // QT_NO_QWS_QPF2
230 
232 {
233  QString dir;
234 #if defined(Q_WS_QWS)
235  extern QString qws_dataDir();
236  dir = qws_dataDir();
237 #else
238  dir = QDir::tempPath();
239 #endif
240  dir.append(QLatin1String("/fonts/"));
241  QDir qd(dir);
242  if (!qd.exists() && !qd.mkpath(dir))
243  dir = QDir::tempPath();
244  return dir;
245 }
246 
247 #ifndef QT_NO_QWS_QPF2
248 
249 #ifndef QT_FONTS_ARE_RESOURCES
251 {
252  QList<QByteArray> removedFonts;
253  QDir dir(qws_fontCacheDir(), QLatin1String("*.qsf"));
254  foreach (const QFileInfo &fi, dir.entryInfoList()) {
256 
257  int fd = QT_OPEN(fileName.constData(), O_RDONLY, 0);
258  if (fd >= 0) {
259  void *header = ::mmap(0, sizeof(QFontEngineQPF::Header), PROT_READ, MAP_SHARED, fd, 0);
260  if (header && header != MAP_FAILED) {
261  quint32 lockValue = reinterpret_cast<QFontEngineQPF::Header *>(header)->lock;
262 
263  if (lockValue && crashedClientIds.contains(lockValue)) {
264  removedFonts.append(fileName);
265  QFile::remove(QFile::decodeName(fileName));
266  }
267 
268  ::munmap(header, sizeof(QFontEngineQPF::Header));
269  }
270  QT_CLOSE(fd);
271  }
272  }
273  if (!removedFonts.isEmpty())
274  qDebug() << "list of corrupted and removed fonts:" << removedFonts;
275  return removedFonts;
276 }
277 #endif
278 
279 static inline unsigned int getChar(const QChar *str, int &i, const int len)
280 {
281  uint ucs4 = str[i].unicode();
282  if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) {
283  ++i;
284  ucs4 = QChar::surrogateToUcs4(ucs4, str[i].unicode());
285  }
286  return ucs4;
287 }
288 #ifdef QT_FONTS_ARE_RESOURCES
289 QFontEngineQPF::QFontEngineQPF(const QFontDef &def, const uchar *bytes, int size)
290  : fd(-1), fontData(bytes), dataSize(size), renderingFontEngine(0)
291 #else
292 QFontEngineQPF::QFontEngineQPF(const QFontDef &def, int fileDescriptor, QFontEngine *fontEngine)
293  : fd(fileDescriptor), fontData(0), dataSize(0), renderingFontEngine(fontEngine)
294 #endif
295 {
296  fontDef = def;
297  cache_cost = 100;
298  freetype = 0;
299  externalCMap = 0;
300  cmapOffset = 0;
301  cmapSize = 0;
302  glyphMapOffset = 0;
303  glyphMapEntries = 0;
304  glyphDataOffset = 0;
305  glyphDataSize = 0;
308  kerning_pairs_loaded = false;
309  readOnly = true;
310 
311 #if defined(DEBUG_FONTENGINE)
312  qDebug() << "QFontEngineQPF::QFontEngineQPF( fd =" << fd << ", renderingFontEngine =" << renderingFontEngine << ')';
313 #endif
314 
315 #ifndef QT_FONTS_ARE_RESOURCES
316  if (fd < 0) {
317  if (!renderingFontEngine)
318  return;
319 
324  QLatin1String("_italic") : QLatin1String(""))
325  + QLatin1String(".qsf");
328 
330  if (::access(encodedFileName, F_OK) == 0) {
331 #if defined(DEBUG_FONTENGINE)
332  qDebug() << "found existing qpf:" << fileName;
333 #endif
334  if (::access(encodedFileName, W_OK | R_OK) == 0) {
336  }
337  // read-write access failed - try read-only access
338  if (fd == -1 && ::access(encodedFileName, R_OK) == 0) {
340  if (fd == -1) {
341 #if defined(DEBUG_FONTENGINE)
342  qErrnoWarning("QFontEngineQPF: unable to open %s", encodedFileName.constData());
343 #endif
344  return;
345  }
346  }
347  if (fd == -1) {
348 #if defined(DEBUG_FONTENGINE)
349  qWarning("QFontEngineQPF: insufficient access rights to %s", encodedFileName.constData());
350 #endif
351  return;
352  }
353  } else {
354 #if defined(DEBUG_FONTENGINE)
355  qDebug() << "creating qpf on the fly:" << fileName;
356 #endif
357  if (::access(QFile::encodeName(qws_fontCacheDir()), W_OK) == 0) {
359  if (fd == -1) {
360 #if defined(DEBUG_FONTENGINE)
361  qErrnoWarning(errno, "QFontEngineQPF: open() failed for %s", encodedFileName.constData());
362 #endif
363  return;
364  }
365 
366  QBuffer buffer;
367  buffer.open(QIODevice::ReadWrite);
368  QPFGenerator generator(&buffer, renderingFontEngine);
369  generator.generate();
370  buffer.close();
371  const QByteArray &data = buffer.data();
372  if (QT_WRITE(fd, data.constData(), data.size()) == -1) {
373 #if defined(DEBUG_FONTENGINE)
374  qErrnoWarning(errno, "QFontEngineQPF: write() failed for %s", encodedFileName.constData());
375 #endif
376  return;
377  }
378  } else {
379 #if defined(DEBUG_FONTENGINE)
380  qErrnoWarning(errno, "QFontEngineQPF: access() failed for %s", qPrintable(qws_fontCacheDir()));
381 #endif
382  return;
383  }
384  }
385  }
386 
387  QT_STATBUF st;
388  if (QT_FSTAT(fd, &st)) {
389 #if defined(DEBUG_FONTENGINE)
390  qErrnoWarning(errno, "QFontEngineQPF: fstat failed!");
391 #endif
392  return;
393  }
394  dataSize = st.st_size;
395 
396 
397  fontData = (const uchar *)::mmap(0, st.st_size, PROT_READ | (renderingFontEngine ? PROT_WRITE : 0), MAP_SHARED, fd, 0);
398  if (!fontData || fontData == (const uchar *)MAP_FAILED) {
399 #if defined(DEBUG_FONTENGINE)
400  perror("mmap failed");
401 #endif
402  fontData = 0;
403  return;
404  }
405 #endif //QT_FONTS_ARE_RESOURCES
406 
407  if (!verifyHeader(fontData, dataSize)) {
408 #if defined(DEBUG_FONTENGINE)
409  qDebug() << "verifyHeader failed!";
410 #endif
411  return;
412  }
413 
414  const Header *header = reinterpret_cast<const Header *>(fontData);
415 
416  readOnly = (header->lock == 0xffffffff);
417 
418  const uchar *data = fontData + sizeof(Header) + qFromBigEndian<quint16>(header->dataSize);
419  const uchar *endPtr = fontData + dataSize;
420  while (data <= endPtr - 8) {
421  quint16 blockTag = readValue<quint16>(data);
422  data += 2; // skip padding
423  quint32 blockSize = readValue<quint32>(data);
424 
425  if (blockTag == CMapBlock) {
426  cmapOffset = data - fontData;
428  } else if (blockTag == GMapBlock) {
429  glyphMapOffset = data - fontData;
430  glyphMapEntries = blockSize / 4;
431  } else if (blockTag == GlyphBlock) {
432  glyphDataOffset = data - fontData;
434  }
435 
436  data += blockSize;
437  }
438 
441 #if !defined(QT_NO_FREETYPE) && !defined(QT_FONTS_ARE_RESOURCES)
443  if (!freetype) {
444  QString newPath =
445 #ifndef QT_NO_SETTINGS
447 #endif
448  QLatin1String("/fonts/") +
452  }
453  if (freetype) {
454  const quint32 qpfTtfRevision = extractHeaderField(fontData, Tag_FontRevision).toUInt();
455  uchar data[4];
456  uint length = 4;
457  bool ok = freetype->getSfntTable(MAKE_TAG('h', 'e', 'a', 'd'), data, &length);
458  if (!ok || length != 4
459  || qFromBigEndian<quint32>(data) != qpfTtfRevision) {
461  freetype = 0;
462  }
463  }
464  if (!cmapOffset && freetype) {
465  freetypeCMapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p'));
466  externalCMap = reinterpret_cast<const uchar *>(freetypeCMapTable.constData());
468  }
469 #endif
470 
471  // get the real cmap
472  if (cmapOffset) {
473  int tableSize = cmapSize;
474  const uchar *cmapPtr = getCMap(fontData + cmapOffset, tableSize, &symbol, &cmapSize);
475  if (cmapPtr)
476  cmapOffset = cmapPtr - fontData;
477  else
478  cmapOffset = 0;
479  } else if (externalCMap) {
480  int tableSize = cmapSize;
481  externalCMap = getCMap(externalCMap, tableSize, &symbol, &cmapSize);
482  }
483 
484  // verify all the positions in the glyphMap
485  if (glyphMapOffset) {
486  const quint32 *gmapPtr = reinterpret_cast<const quint32 *>(fontData + glyphMapOffset);
487  for (uint i = 0; i < glyphMapEntries; ++i) {
488  quint32 glyphDataPos = qFromBigEndian<quint32>(gmapPtr[i]);
489  if (glyphDataPos == 0xffffffff)
490  continue;
491  if (glyphDataPos >= glyphDataSize) {
492  // error
493  glyphMapOffset = 0;
494  glyphMapEntries = 0;
495  break;
496  }
497  }
498  }
499 
500 #if defined(DEBUG_FONTENGINE)
501  if (!isValid())
502  qDebug() << "fontData" << fontData << "dataSize" << dataSize
503  << "externalCMap" << externalCMap << "cmapOffset" << cmapOffset
504  << "glyphMapOffset" << glyphMapOffset << "glyphDataOffset" << glyphDataOffset
505  << "fd" << fd << "glyphDataSize" << glyphDataSize;
506 #endif
507 #if defined(Q_WS_QWS)
508  if (isValid() && renderingFontEngine)
510 #endif
511 }
512 
514 {
515 #if defined(Q_WS_QWS)
516  if (isValid() && renderingFontEngine) {
517  QT_TRY {
519  } QT_CATCH(...) {
520  qDebug("QFontEngineQPF::~QFontEngineQPF: Out of memory");
521  // ignore.
522  }
523  }
524 #endif
525  delete renderingFontEngine;
526  if (fontData) {
527  if (munmap((void *)fontData, dataSize) == -1) {
528 #if defined(DEBUG_FONTENGINE)
529  qErrnoWarning(errno, "~QFontEngineQPF: Unable to munmap");
530 #endif
531  }
532  }
533  if (fd != -1)
534  ::close(fd);
535 #if !defined(QT_NO_FREETYPE)
536  if (freetype)
538 #endif
539 }
540 
541 bool QFontEngineQPF::getSfntTableData(uint tag, uchar *buffer, uint *length) const
542 {
543 #if !defined(QT_NO_FREETYPE)
544  if (freetype)
545  return freetype->getSfntTable(tag, buffer, length);
546 #endif
547  Q_UNUSED(tag);
548  Q_UNUSED(buffer);
549  *length = 0;
550  return false;
551 }
552 
553 bool QFontEngineQPF::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
554 {
556  if (!renderingFontEngine->stringToCMap(str, len, glyphs, nglyphs, flags))
557  return false;
558 #ifndef QT_NO_FREETYPE
559  const_cast<QFontEngineQPF *>(this)->ensureGlyphsLoaded(*glyphs);
560 #endif
561  return true;
562  }
563 
564  if (*nglyphs < len) {
565  *nglyphs = len;
566  return false;
567  }
568 
569 #if defined(DEBUG_FONTENGINE)
570  QSet<QChar> seenGlyphs;
571 #endif
572 
574 
575  bool mirrored = flags & QTextEngine::RightToLeft;
576  int glyph_pos = 0;
577  if (symbol) {
578  for (int i = 0; i < len; ++i) {
579  unsigned int uc = getChar(str, i, len);
580  glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
581  if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
582  glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
583  ++glyph_pos;
584  }
585  } else {
586  for (int i = 0; i < len; ++i) {
587  unsigned int uc = getChar(str, i, len);
588  if (mirrored)
589  uc = QChar::mirroredChar(uc);
590  glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
591 #if 0 && defined(DEBUG_FONTENGINE)
592  QChar c(uc);
593  if (!findGlyph(glyphs[glyph_pos].glyph) && !seenGlyphs.contains(c))
594  qDebug() << "glyph for character" << c << '/' << hex << uc << "is" << dec << glyphs[glyph_pos].glyph;
595 
596  seenGlyphs.insert(c);
597 #endif
598  ++glyph_pos;
599  }
600  }
601 
602  *nglyphs = glyph_pos;
603  glyphs->numGlyphs = glyph_pos;
604  recalcAdvances(glyphs, flags);
605  return true;
606 }
607 
608 void QFontEngineQPF::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags) const
609 {
610 #ifndef QT_NO_FREETYPE
611  const_cast<QFontEngineQPF *>(this)->ensureGlyphsLoaded(*glyphs);
612 #endif
613  for (int i = 0; i < glyphs->numGlyphs; ++i) {
614  const Glyph *g = findGlyph(glyphs->glyphs[i]);
615  if (!g) {
616  glyphs->glyphs[i] = 0;
617  continue;
618  }
619  glyphs->advances_x[i] = g->advance;
620  glyphs->advances_y[i] = 0;
621  }
622 }
623 
625 {
626  const Glyph *glyph = findGlyph(g);
627  if (!glyph)
628  return QImage();
629 
630  const uchar *bits = ((const uchar *) glyph) + sizeof(Glyph);
631 
632  QImage image(glyph->width, glyph->height, QImage::Format_Indexed8);
633  for (int j=0; j<256; ++j)
634  image.setColor(j, qRgba(0, 0, 0, j));
635 
636  for (int i=0; i<glyph->height; ++i) {
637  memcpy(image.scanLine(i), bits, glyph->bytesPerLine);
638  bits += glyph->bytesPerLine;
639  }
640  return image;
641 }
642 
644 {
645  QPaintEngineState *pState = p->state;
646  QRasterPaintEngine *paintEngine = static_cast<QRasterPaintEngine*>(p);
647 
648  QTransform matrix = pState->transform();
649  matrix.translate(_x, _y);
650  QFixed x = QFixed::fromReal(matrix.dx());
651  QFixed y = QFixed::fromReal(matrix.dy());
652 
655  getGlyphPositions(si.glyphs, matrix, si.flags, glyphs, positions);
656  if (glyphs.size() == 0)
657  return;
658 
659  for(int i = 0; i < glyphs.size(); i++) {
660  const Glyph *glyph = findGlyph(glyphs[i]);
661  if (!glyph)
662  continue;
663 
664  const int depth = 8; //###
665 
666  paintEngine->alphaPenBlt(reinterpret_cast<const uchar *>(glyph) + sizeof(Glyph), glyph->bytesPerLine, depth,
667  qRound(positions[i].x) + glyph->x,
668  qRound(positions[i].y) + glyph->y,
669  glyph->width, glyph->height);
670  }
671 }
672 
673 void QFontEngineQPF::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
674 {
675  if (renderingFontEngine &&
677  || static_cast<QProxyFontEngine *>(renderingFontEngine)->capabilities() & QAbstractFontEngine::CanOutlineGlyphs)) {
678  renderingFontEngine->addOutlineToPath(x, y, glyphs, path, flags);
679  return;
680  }
681  addBitmapFontToPath(x, y, glyphs, path, flags);
682 }
683 
685 {
686 #ifndef QT_NO_FREETYPE
687  const_cast<QFontEngineQPF *>(this)->ensureGlyphsLoaded(glyphs);
688 #endif
689 
690  glyph_metrics_t overall;
691  // initialize with line height, we get the same behaviour on all platforms
692  overall.y = -ascent();
693  overall.height = ascent() + descent() + 1;
694 
695  QFixed ymax = 0;
696  QFixed xmax = 0;
697  for (int i = 0; i < glyphs.numGlyphs; i++) {
698  const Glyph *g = findGlyph(glyphs.glyphs[i]);
699  if (!g)
700  continue;
701 
702  QFixed x = overall.xoff + glyphs.offsets[i].x + g->x;
703  QFixed y = overall.yoff + glyphs.offsets[i].y + g->y;
704  overall.x = qMin(overall.x, x);
705  overall.y = qMin(overall.y, y);
706  xmax = qMax(xmax, x + g->width);
707  ymax = qMax(ymax, y + g->height);
708  overall.xoff += g->advance;
709  }
710  overall.height = qMax(overall.height, ymax - overall.y);
711  overall.width = xmax - overall.x;
712 
713  return overall;
714 }
715 
717 {
718 #ifndef QT_NO_FREETYPE
719  {
721  tmp.glyphs[0] = glyph;
722  const_cast<QFontEngineQPF *>(this)->ensureGlyphsLoaded(tmp);
723  }
724 #endif
725  glyph_metrics_t overall;
726  const Glyph *g = findGlyph(glyph);
727  if (!g)
728  return overall;
729  overall.x = g->x;
730  overall.y = g->y;
731  overall.width = g->width;
732  overall.height = g->height;
733  overall.xoff = g->advance;
734  return overall;
735 }
736 
738 {
739  return QFixed::fromReal(extractHeaderField(fontData, Tag_Ascent).value<qreal>());
740 }
741 
743 {
744  return QFixed::fromReal(extractHeaderField(fontData, Tag_Descent).value<qreal>());
745 }
746 
748 {
749  return QFixed::fromReal(extractHeaderField(fontData, Tag_Leading).value<qreal>());
750 }
751 
753 {
755 }
756 
758 {
760 }
761 
763 {
765 }
766 
768 {
770 }
771 
773 {
775 }
776 
778 {
779  return QFontEngine::QPF2;
780 }
781 
782 bool QFontEngineQPF::canRender(const QChar *string, int len)
783 {
785 
786  if (symbol) {
787  for (int i = 0; i < len; ++i) {
788  unsigned int uc = getChar(string, i, len);
789  glyph_t g = getTrueTypeGlyphIndex(cmap, uc);
790  if(!g && uc < 0x100)
791  g = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
792  if (!g)
793  return false;
794  }
795  } else {
796  for (int i = 0; i < len; ++i) {
797  unsigned int uc = getChar(string, i, len);
798  if (!getTrueTypeGlyphIndex(cmap, uc))
799  return false;
800  }
801  }
802  return true;
803 }
804 
806 {
808  && glyphMapOffset && glyphDataOffset && (fd >= 0 || glyphDataSize > 0);
809 }
810 
811 #if !defined(QT_NO_FREETYPE)
813 {
815  freetype->lock();
816  FT_Face face = freetype->face;
817 
818  // ### not perfect
819  const int ysize = qRound(fontDef.pixelSize * qreal(64));
820  const int xsize = ysize;
821 
822  if (freetype->xsize != xsize || freetype->ysize != ysize) {
823  FT_Set_Char_Size(face, xsize, ysize, 0, 0);
824  freetype->xsize = xsize;
825  freetype->ysize = ysize;
826  }
827  FT_Matrix identityMatrix;
828  identityMatrix.xx = 0x10000;
829  identityMatrix.yy = 0x10000;
830  identityMatrix.xy = 0;
831  identityMatrix.yx = 0;
832  if (freetype->matrix.xx != identityMatrix.xx ||
833  freetype->matrix.yy != identityMatrix.yy ||
834  freetype->matrix.xy != identityMatrix.xy ||
835  freetype->matrix.yx != identityMatrix.yx) {
836  freetype->matrix = identityMatrix;
837  FT_Set_Transform(face, &freetype->matrix, 0);
838  }
839  return face;
840 }
841 
843 {
844  freetype->unlock();
845 }
846 
847 void QFontEngineQPF::doKerning(QGlyphLayout *g, QTextEngine::ShaperFlags flags) const
848 {
849  if (!kerning_pairs_loaded) {
850  kerning_pairs_loaded = true;
851  if (freetype) {
852  lockFace();
853  if (freetype->face->size->metrics.x_ppem != 0) {
854  QFixed scalingFactor(freetype->face->units_per_EM/freetype->face->size->metrics.x_ppem);
855  unlockFace();
856  const_cast<QFontEngineQPF *>(this)->loadKerningPairs(scalingFactor);
857  } else {
858  unlockFace();
859  }
860  }
861  }
862  QFontEngine::doKerning(g, flags);
863 }
864 
865 HB_Error QFontEngineQPF::getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints)
866 {
867  if (!freetype)
868  return HB_Err_Not_Covered;
869  lockFace();
870  HB_Error result = freetype->getPointInOutline(glyph, flags, point, xpos, ypos, nPoints);
871  unlockFace();
872  return result;
873 }
874 
876 {
877  if (!freetype)
878  return QFontEngine::emSquareSize();
879  if (FT_IS_SCALABLE(freetype->face))
880  return freetype->face->units_per_EM;
881  else
882  return freetype->face->size->metrics.y_ppem;
883 }
884 
886 {
887  if (readOnly)
888  return;
889  bool locked = false;
890  for (int i = 0; i < glyphs.numGlyphs; ++i) {
891  if (!glyphs.glyphs[i])
892  continue;
893  const Glyph *g = findGlyph(glyphs.glyphs[i]);
894  if (g)
895  continue;
896  if (!locked) {
897  if (!lockFile())
898  return;
899  locked = true;
900  g = findGlyph(glyphs.glyphs[i]);
901  if (g)
902  continue;
903  }
904  loadGlyph(glyphs.glyphs[i]);
905  }
906  if (locked) {
907  unlockFile();
908 #if defined(DEBUG_FONTENGINE)
909  qDebug() << "Finished rendering glyphs\n";
910 #endif
911  }
912 }
913 
915 {
916  quint32 glyphPos = ~0;
917 
918  if (!renderingFontEngine)
919  return;
921  if (img.format() != QImage::Format_Indexed8) {
922  bool mono = img.depth() == 1;
924  if (mono) {
925  //### we know that 1 is opaque and 0 is transparent
926  uchar *byte = img.bits();
927  int count = img.byteCount();
928  while (count--)
929  *byte++ *= 0xff;
930  }
931  }
934 
935  off_t oldSize = ::lseek(fd, 0, SEEK_END);
936  if (oldSize == (off_t)-1)
937  return;
938 
939  Glyph g;
940  g.width = img.width();
941  g.height = img.height();
942  g.bytesPerLine = img.bytesPerLine();
943  g.x = qRound(metrics.x);
944  g.y = qRound(metrics.y);
945  g.advance = qRound(metrics.xoff);
946 
947  QT_WRITE(fd, &g, sizeof(g));
948  QT_WRITE(fd, img.bits(), img.byteCount());
949 
950  glyphPos = oldSize - glyphDataOffset;
951 #if 0 && defined(DEBUG_FONTENGINE)
952  qDebug() << "glyphPos for new glyph" << glyph << "is" << glyphPos << "oldSize" << oldSize << "glyphDataOffset" << glyphDataOffset;
953 #endif
954 
955  quint32 *gmap = (quint32 *)(fontData + glyphMapOffset);
956  gmap[glyph] = qToBigEndian(glyphPos);
957 
958  glyphDataSize = glyphPos + sizeof(g) + img.byteCount();
959  quint32 *blockSizePtr = (quint32 *)(fontData + glyphDataOffset - 4);
960  *blockSizePtr = qToBigEndian(glyphDataSize);
961 }
962 
964 {
965  // #### this does not handle the case when the process holding the
966  // lock hangs for some reason
967  struct flock lock;
968  lock.l_type = F_WRLCK;
969  lock.l_whence = SEEK_SET;
970  lock.l_start = 0;
971  lock.l_len = 0; // lock the whole file
972  while (fcntl(fd, F_SETLKW, &lock) != 0) {
973  if (errno == EINTR)
974  continue;
975  perror("locking qpf");
976  return false;
977  }
978  Header *header = (Header *)fontData;
979  if (header->lock) {
980  lock.l_type = F_UNLCK;
981  if (fcntl(fd, F_SETLK, &lock) != 0)
982  perror("unlocking possibly corrupt qpf");
983  return false;
984  }
985 #if defined(Q_WS_QWS)
986  extern int qws_client_id;
987  // qws_client_id == 0 means we're the server. in this case we just
988  // set the id to 1
989  header->lock = qws_client_id ? qws_client_id : 1;
990 #else
991  header->lock = 1;
992 #endif
993  return true;
994 }
995 
997 {
998  ((Header *)fontData)->lock = 0;
999 
1000  struct flock lock;
1001  lock.l_type = F_UNLCK;
1002  lock.l_whence = SEEK_SET;
1003  lock.l_start = 0;
1004  lock.l_len = 0; // lock the whole file
1005  if (fcntl(fd, F_SETLK, &lock) != 0) {
1006  perror("unlocking qpf");
1007  }
1008 
1009  remapFontData();
1010 }
1011 
1013 {
1014  off_t newFileSize = ::lseek(fd, 0, SEEK_END);
1015  if (newFileSize == (off_t)-1) {
1016 #ifdef DEBUG_FONTENGINE
1017  perror("QFontEngineQPF::remapFontData: lseek failed");
1018 #endif
1019  fontData = 0;
1020  return;
1021  }
1022 
1023 #ifndef QT_NO_MREMAP
1024  fontData = static_cast<uchar *>(::mremap(const_cast<uchar *>(fontData), dataSize, newFileSize, MREMAP_MAYMOVE));
1025  if (!fontData || fontData == (const uchar *)MAP_FAILED) {
1026 # if defined(DEBUG_FONTENGINE)
1027  perror("QFontEngineQPF::remapFontData(): mremap failed");
1028 # endif
1029  fontData = 0;
1030  }
1031 
1032  if (!fontData)
1033 #endif // QT_NO_MREMAP
1034  {
1035  int status = ::munmap((void *)fontData, dataSize);
1036  if (status != 0)
1037  qErrnoWarning(status, "QFontEngineQPF::remapFomrData: munmap failed!");
1038 
1039  fontData = (const uchar *)::mmap(0, newFileSize, PROT_READ | (renderingFontEngine ? PROT_WRITE : 0),
1040  MAP_SHARED, fd, 0);
1041  if (!fontData || fontData == (const uchar *)MAP_FAILED) {
1042 # if defined(DEBUG_FONTENGINE)
1043  perror("mmap failed");
1044 # endif
1045  fontData = 0;
1046  return;
1047  }
1048  }
1049 
1050  dataSize = newFileSize;
1051  glyphDataSize = newFileSize - glyphDataOffset;
1052 #if defined(DEBUG_FONTENGINE)
1053  qDebug() << "remapped the font file to" << newFileSize << "bytes";
1054 #endif
1055 }
1056 
1057 #endif // QT_NO_FREETYPE
1058 
1060 {
1061  writeHeader();
1062  writeGMap();
1063  writeBlock(QFontEngineQPF::GlyphBlock, QByteArray());
1064 
1065  dev->seek(4); // position of header.lock
1066  writeUInt32(0);
1067 }
1068 
1070 {
1071  QFontEngineQPF::Header header;
1072 
1073  header.magic[0] = 'Q';
1074  header.magic[1] = 'P';
1075  header.magic[2] = 'F';
1076  header.magic[3] = '2';
1077  header.lock = 1;
1080  header.dataSize = 0;
1081  dev->write((const char *)&header, sizeof(header));
1082 
1083  writeTaggedString(QFontEngineQPF::Tag_FontName, fe->fontDef.family.toUtf8());
1084 
1085  QFontEngine::FaceId face = fe->faceId();
1086  writeTaggedString(QFontEngineQPF::Tag_FileName, face.filename);
1087  writeTaggedUInt32(QFontEngineQPF::Tag_FileIndex, face.index);
1088 
1089  {
1090  uchar data[4];
1091  uint len = 4;
1092  bool ok = fe->getSfntTableData(MAKE_TAG('h', 'e', 'a', 'd'), data, &len);
1093  if (ok) {
1094  const quint32 revision = qFromBigEndian<quint32>(data);
1095  writeTaggedUInt32(QFontEngineQPF::Tag_FontRevision, revision);
1096  }
1097  }
1098 
1099  writeTaggedQFixed(QFontEngineQPF::Tag_Ascent, fe->ascent());
1100  writeTaggedQFixed(QFontEngineQPF::Tag_Descent, fe->descent());
1101  writeTaggedQFixed(QFontEngineQPF::Tag_Leading, fe->leading());
1102  writeTaggedQFixed(QFontEngineQPF::Tag_XHeight, fe->xHeight());
1103  writeTaggedQFixed(QFontEngineQPF::Tag_AverageCharWidth, fe->averageCharWidth());
1104  writeTaggedQFixed(QFontEngineQPF::Tag_MaxCharWidth, QFixed::fromReal(fe->maxCharWidth()));
1105  writeTaggedQFixed(QFontEngineQPF::Tag_LineThickness, fe->lineThickness());
1106  writeTaggedQFixed(QFontEngineQPF::Tag_MinLeftBearing, QFixed::fromReal(fe->minLeftBearing()));
1107  writeTaggedQFixed(QFontEngineQPF::Tag_MinRightBearing, QFixed::fromReal(fe->minRightBearing()));
1108  writeTaggedQFixed(QFontEngineQPF::Tag_UnderlinePosition, fe->underlinePosition());
1109  writeTaggedUInt8(QFontEngineQPF::Tag_PixelSize, fe->fontDef.pixelSize);
1110  writeTaggedUInt8(QFontEngineQPF::Tag_Weight, fe->fontDef.weight);
1111  writeTaggedUInt8(QFontEngineQPF::Tag_Style, fe->fontDef.style);
1112 
1114 
1115  writeTaggedString(QFontEngineQPF::Tag_EndOfHeader, QByteArray());
1116  align4();
1117 
1118  const quint64 size = dev->pos();
1119  header.dataSize = qToBigEndian<quint16>(size - sizeof(header));
1120  dev->seek(0);
1121  dev->write((const char *)&header, sizeof(header));
1122  dev->seek(size);
1123 }
1124 
1126 {
1127  const quint16 glyphCount = fe->glyphCount();
1128 
1129  writeUInt16(QFontEngineQPF::GMapBlock);
1130  writeUInt16(0); // padding
1131  writeUInt32(glyphCount * 4);
1132 
1133  QByteArray &buffer = dev->buffer();
1134  const int numBytes = glyphCount * sizeof(quint32);
1135  qint64 pos = buffer.size();
1136  buffer.resize(pos + numBytes);
1137  qMemSet(buffer.data() + pos, 0xff, numBytes);
1138  dev->seek(pos + numBytes);
1139 }
1140 
1142 {
1143  writeUInt16(tag);
1144  writeUInt16(0); // padding
1145  const int padSize = ((data.size() + 3) / 4) * 4 - data.size();
1146  writeUInt32(data.size() + padSize);
1147  dev->write(data);
1148  for (int i = 0; i < padSize; ++i)
1149  writeUInt8(0);
1150 }
1151 
1153 {
1154  writeUInt16(tag);
1155  writeUInt16(string.length());
1156  dev->write(string);
1157 }
1158 
1160 {
1161  writeUInt16(tag);
1162  writeUInt16(sizeof(value));
1163  writeUInt32(value);
1164 }
1165 
1167 {
1168  writeUInt16(tag);
1169  writeUInt16(sizeof(value));
1170  writeUInt8(value);
1171 }
1172 
1174 {
1175  writeUInt16(tag);
1176  writeUInt16(sizeof(quint32));
1177  writeUInt32(value.value());
1178 }
1179 
1180 #endif // QT_NO_QWS_QPF2
1181 
1182 /*
1183  Creates a new multi qws engine.
1184 
1185  This function takes ownership of the QFontEngine, increasing it's refcount.
1186 */
1188  : QFontEngineMulti(fallbacks.size() + 1),
1189  fallbackFamilies(fallbacks), script(_script)
1190 {
1191  engines[0] = fe;
1192  fe->ref.ref();
1193  fontDef = engines[0]->fontDef;
1194 }
1195 
1197 {
1198  Q_ASSERT(at < engines.size());
1199  Q_ASSERT(engines.at(at) == 0);
1200 
1201  QFontDef request = fontDef;
1203  request.family = fallbackFamilies.at(at-1);
1205  /*fontprivate*/0,
1206  request);
1207  Q_ASSERT(engines[at]);
1208  engines[at]->ref.ref();
1209  engines[at]->fontDef = request;
1210 }
1211 
1212 void QFontEngineMultiQWS::draw(QPaintEngine */*p*/, qreal /*x*/, qreal /*y*/, const QTextItemInt &/*si*/)
1213 {
1214  qFatal("QFontEngineMultiQWS::draw should never be called!");
1215 }
1216 
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qstring.cpp:6448
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
void ensureGlyphsLoaded(const QGlyphLayout &glyphs)
The QDir class provides access to directory structures and their contents.
Definition: qdir.h:58
QAtomicInt ref
static QFreetypeFace * getFace(const QFontEngine::FaceId &face_id, const QByteArray &fontData=QByteArray())
HB_Error getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints)
QFixed ascent() const
bool mkpath(const QString &dirPath) const
Creates the directory path dirPath.
Definition: qdir.cpp:1477
const int blockSize
void sendFontCommand(int type, const QByteArray &fontName)
QFreetypeFace * freetype
qreal dy() const
Returns the vertical translation factor.
Definition: qtransform.h:277
QFixed * advances_y
static QFixed fromFixed(int fixed)
Definition: qfixed_p.h:71
#define MAP_FAILED
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 QImage alphaMapForGlyph(glyph_t)
unsigned char c[8]
Definition: qnumeric_p.h:62
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
void draw(QPaintEngine *p, qreal x, qreal y, const QTextItemInt &si)
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
int value() const
Definition: qfixed_p.h:73
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
QFixed * advances_x
const QByteArray & data() const
Returns the data contained in the buffer.
Definition: qbuffer.cpp:301
glyph_metrics_t boundingBox(const QGlyphLayout &glyphs)
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
Q_GUI_EXPORT QWSDisplay * qt_fbdpy
HB_Glyph * glyphs
QPaintEngineState * state
Definition: qpaintengine.h:239
virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const
T readValue(const uchar *&data)
bool open(OpenMode openMode)
Reimplemented Function
Definition: qbuffer.cpp:338
QString & replace(int i, int len, QChar after)
Definition: qstring.cpp:2005
#define at(className, varName)
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
RenderFlags flags
QTransform transform() const
Returns the matrix in the current paint engine state.
Definition: qpainter.cpp:9377
virtual void addOutlineToPath(qreal, qreal, const QGlyphLayout &, QPainterPath *, QTextItem::RenderFlags flags)
void close()
Reimplemented Function
Definition: qbuffer.cpp:359
QString & prepend(QChar c)
Definition: qstring.h:261
#define O_RDONLY
bool canRender(const QChar *string, int len)
virtual int glyphCount() const
QString fileName() const
Returns the name of the file, excluding the path.
Definition: qfileinfo.cpp:726
static const uchar * getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize)
static QColor cmap[256]
Definition: qgl_mac.mm:760
int byteCount() const
Returns the number of bytes occupied by the image data.
Definition: qimage.cpp:1800
static LibLoadStatus status
Definition: qlocale_icu.cpp:69
QString absoluteFilePath() const
Returns an absolute path including the file name.
Definition: qfileinfo.cpp:534
#define QT_END_INCLUDE_NAMESPACE
This macro is equivalent to QT_BEGIN_NAMESPACE.
Definition: qglobal.h:92
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
int bytesPerLine() const
Returns the number of bytes per image scanline.
Definition: qimage.cpp:1812
#define READ_VERIFY(type, variable)
qreal minRightBearing() const
unsigned char quint8
Definition: qglobal.h:934
bool ref()
Atomically increments the value of this QAtomicInt.
quint32 qFromBigEndian< quint32 >(const uchar *src)
Definition: qendian.h:239
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 QBuffer class provides a QIODevice interface for a QByteArray.
Definition: qbuffer.h:57
bool getSfntTable(uint tag, uchar *buffer, uint *length) const
The QString class provides a Unicode character string.
Definition: qstring.h:83
static QFixed fromReal(qreal r)
Definition: qfixed_p.h:70
QImage alphaMapForGlyph(glyph_t t)
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QFixed lineThickness() const
virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const =0
#define O_CREAT
virtual Type type() const =0
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
static const uchar * verifyTag(const uchar *tagPtr, const uchar *endPtr)
Format format() const
Returns the format of the image.
Definition: qimage.cpp:2305
Q_CORE_EXPORT QTextStream & hex(QTextStream &s)
bool exists() const
Returns true if the directory exists; otherwise returns false.
Definition: qdir.cpp:1560
Q_CORE_EXPORT QTextStream & dec(QTextStream &s)
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
int qws_client_id
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
void writeTaggedUInt32(QFontEngineQPF::HeaderTag tag, quint32 value)
static quint32 getTrueTypeGlyphIndex(const uchar *cmap, uint unicode)
int toInt(bool *ok=0) const
Returns the variant as an int if the variant has type() Int , Bool , ByteArray , Char ...
Definition: qvariant.cpp:2625
static QString decodeName(const QByteArray &localFileName)
This does the reverse of QFile::encodeName() using localFileName.
Definition: qfile.cpp:552
#define MAKE_TAG(ch1, ch2, ch3, ch4)
QFontEngineQPF(const QFontDef &def, int fd, QFontEngine *renderingFontEngine=0)
Q_CORE_EXPORT void qDebug(const char *,...)
QGlyphLayout glyphs
unsigned char uchar
Definition: qglobal.h:994
static QString toString(Register *reg, int type, bool *ok=0)
void writeTaggedString(QFontEngineQPF::HeaderTag tag, const QByteArray &string)
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
Q_GUI_EXPORT_INLINE QRgb qRgba(int r, int g, int b, int a)
Definition: qrgb.h:72
QFixed y
Definition: qfixed_p.h:191
QBool contains(const T &t) const
Returns true if the list contains an occurrence of value; otherwise returns false.
Definition: qlist.h:880
struct FT_FaceRec_ * FT_Face
Definition: qfont.h:50
bool isValid() const
void writeTaggedQFixed(QFontEngineQPF::HeaderTag tag, QFixed value)
unsigned __int64 quint64
Definition: qglobal.h:943
void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const
int access(const char *, int)
bool contains(const T &value) const
Definition: qset.h:91
static const QCssKnownValue positions[NumKnownPositionModes - 1]
Definition: qcssparser.cpp:329
void doKerning(QGlyphLayout *g, QTextEngine::ShaperFlags flags) const
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
QChar mirroredChar() const
Returns the mirrored character if this character is a mirrored character; otherwise returns the chara...
Definition: qchar.cpp:1016
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
T qToBigEndian(T source)
Definition: qendian.h:337
static QString fromUtf8(const char *, int size=-1)
Returns a QString initialized with the first size bytes of the UTF-8 string str.
Definition: qstring.cpp:4302
void getGlyphPositions(const QGlyphLayout &glyphs, const QTransform &matrix, QTextItem::RenderFlags flags, QVarLengthArray< glyph_t > &glyphs_out, QVarLengthArray< QFixedPoint > &positions)
QByteArray encodedFileName
unsigned short quint16
Definition: qglobal.h:936
QFixed underlinePosition() const
Q_CORE_EXPORT void qWarning(const char *,...)
Internal QTextItem.
const_iterator insert(const T &value)
Definition: qset.h:179
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
static QList< QByteArray > cleanUpAfterClientCrash(const QList< int > &crashedClientIds)
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
uint weight
Definition: qfont_p.h:95
void unlockFace() const
QFileInfoList entryInfoList(Filters filters=NoFilter, SortFlags sort=NoSort) const
Returns a list of QFileInfo objects for all the files and directories in the directory, ordered according to the name and attribute filters previously set with setNameFilters() and setFilter(), and sorted according to the flags set with setSorting().
Definition: qdir.cpp:1316
int depth() const
Returns the depth of the image.
Definition: qimage.cpp:1620
virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs)=0
__int64 qint64
Definition: qglobal.h:942
QFontEngine * renderingFontEngine
virtual void removeGlyphFromCache(glyph_t)
The QPaintEngine class provides an abstract definition of how QPainter draws to a given device on a g...
Definition: qpaintengine.h:90
#define QT_CATCH(A)
Definition: qglobal.h:1537
Q_CORE_EXPORT int QT_FASTCALL script(uint ucs4)
qreal pixelSize
Definition: qfont_p.h:90
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
QVector< QFontEngine * > engines
static QFontEngineQPA::TagType tagTypes[QFontEngineQPA::NumTags]
quint16 qFromBigEndian< quint16 >(const uchar *src)
Definition: qendian.h:249
static QString tempPath()
Returns the absolute path of the system&#39;s temporary directory.
Definition: qdir.cpp:1987
QFontEngineMultiQWS(QFontEngine *fe, int script, const QStringList &fallbacks)
qreal maxCharWidth() const
const Glyph * findGlyph(glyph_t g) const
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
const uchar * fontData
QFixed x
Definition: qfixed_p.h:190
virtual HB_Error getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints)
uchar * bits()
Returns a pointer to the first pixel data.
Definition: qimage.cpp:1946
Q_CORE_EXPORT void qFatal(const char *,...)
int fcntl(int, int,...)
int width() const
Returns the width of the image.
Definition: qimage.cpp:1557
void * qMemSet(void *dest, int c, size_t n)
Definition: qglobal.cpp:2509
QImage convertToFormat(Format f, Qt::ImageConversionFlags flags=Qt::AutoColor) const Q_REQUIRED_RESULT
Returns a copy of the image in the given format.
Definition: qimage.cpp:3966
#define QT_OPEN
Definition: qcore_unix_p.h:186
void writeTaggedUInt8(QFontEngineQPF::HeaderTag tag, quint8 value)
virtual QFixed emSquareSize() const
QString & append(QChar c)
Definition: qstring.cpp:1777
const uchar * externalCMap
FT_Face lockFace() const
void writeBlock(QFontEngineQPF::BlockTag tag, const QByteArray &data)
void release(const QFontEngine::FaceId &face_id)
uint style
Definition: qfont_p.h:97
QFixed descent() const
void alphaPenBlt(const void *src, int bpl, int depth, int rx, int ry, int w, int h)
static QString location(LibraryLocation)
Returns the location specified by loc.
QString qws_fontCacheDir()
QString qws_dataDir()
#define st(var, type, card)
QString toLower() const Q_REQUIRED_RESULT
Returns a lowercase copy of the string.
Definition: qstring.cpp:5389
void resize(int size)
Sets the size of the byte array to size bytes.
uint toUInt(bool *ok=0) const
Returns the variant as an unsigned int if the variant has type() UInt , Bool , ByteArray ...
Definition: qvariant.cpp:2644
unsigned int quint32
Definition: qglobal.h:938
QByteArray freetypeCMapTable
QFixed leading() const
static bool verifyHeader(const uchar *data, int size)
static QReadWriteLock lock
Definition: proxyconf.cpp:399
virtual QFixed emSquareSize() const
int height() const
Returns the height of the image.
Definition: qimage.cpp:1572
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 minLeftBearing() const
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
qreal dx() const
Returns the horizontal translation factor.
Definition: qtransform.h:273
static unsigned int getChar(const QChar *str, int &i, const int len)
bool remove()
Removes the file specified by fileName().
Definition: qfile.cpp:715
void draw(QPaintEngine *p, qreal x, qreal y, const QTextItemInt &si)
#define QT_BEGIN_INCLUDE_NAMESPACE
This macro is equivalent to QT_END_NAMESPACE.
Definition: qglobal.h:91
QTextStream & hex(QTextStream &stream)
Calls QTextStream::setIntegerBase(16) on stream and returns stream.
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
void loadKerningPairs(QFixed scalingFactor)
The QRasterPaintEngine class enables hardware acceleration of painting operations in Qt for Embedded ...
QFontDef fontDef
#define VERIFY_TAG(condition)
QString family
Definition: qfont_p.h:82
T value() const
Returns the stored value converted to the template type T.
Definition: qvariant.h:332
#define VERIFY(condition)
The QFileInfo class provides system-independent file information.
Definition: qfileinfo.h:60
QFixedPoint * offsets
#define QT_WRITE
Definition: qcore_unix_p.h:289
#define qPrintable(string)
Definition: qglobal.h:1750
Type type() const
uint styleStrategy
Definition: qfont_p.h:92
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
#define O_RDWR
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
bool getSfntTableData(uint tag, uchar *buffer, uint *length) const
#define O_EXCL
QStringList fallbackFamilies
#define QT_TRY
Definition: qglobal.h:1536
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
void addBitmapFontToPath(qreal x, qreal y, const QGlyphLayout &, QPainterPath *, QTextItem::RenderFlags)
unsigned int glyph_t
Q_DECL_CONSTEXPR int qRound(qreal d)
Definition: qglobal.h:1203
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
Definition: qimage.cpp:1886
int size() const
static qreal toReal(Register *reg, int type, bool *ok=0)
int errno
The QTransform class specifies 2D transformations of a coordinate system.
Definition: qtransform.h:65
void qErrnoWarning(const char *msg,...)
Definition: qglobal.cpp:2954
void loadGlyph(glyph_t glyph)
static QStringList fallbackFamilies(const QString &family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script)
QByteArray getSfntTable(uint) const
#define QT_CLOSE
Definition: qcore_unix_p.h:304
static QVariant extractHeaderField(const uchar *data, HeaderTag tag)
static QFontEngine * findFont(int script, const QFontPrivate *fp, const QFontDef &request)