Qt 4.8
qrawfont_win.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 test suite 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 "qrawfont_p.h"
43 
44 #if !defined(QT_NO_RAWFONT)
45 
46 #include <private/qsystemlibrary_p.h>
47 
48 #if !defined(QT_NO_DIRECTWRITE)
50 # include <dwrite.h>
51 #endif
52 
54 
55 namespace {
56 
57  template<typename T>
58  struct BigEndian
59  {
60  quint8 data[sizeof(T)];
61 
62  operator T() const
63  {
64  T littleEndian = 0;
65  for (int i = 0; i < int(sizeof(T)); ++i)
66  littleEndian |= data[i] << ((sizeof(T) - i - 1) * 8);
67 
68  return littleEndian;
69  }
70 
71  BigEndian<T> &operator=(const T &t)
72  {
73  for (int i = 0; i < int(sizeof(T)); ++i)
74  data[i] = ((t >> (sizeof(T) - i - 1) * 8) & 0xff);
75 
76  return *this;
77  }
78  };
79 
80 # pragma pack(1)
81 
82  // Common structure for all formats of the "name" table
83  struct NameTable
84  {
85  BigEndian<quint16> format;
86  BigEndian<quint16> count;
87  BigEndian<quint16> stringOffset;
88  };
89 
90  struct NameRecord
91  {
92  BigEndian<quint16> platformID;
93  BigEndian<quint16> encodingID;
94  BigEndian<quint16> languageID;
95  BigEndian<quint16> nameID;
96  BigEndian<quint16> length;
97  BigEndian<quint16> offset;
98  };
99 
100  struct OffsetSubTable
101  {
102  BigEndian<quint32> scalerType;
103  BigEndian<quint16> numTables;
104  BigEndian<quint16> searchRange;
105  BigEndian<quint16> entrySelector;
106  BigEndian<quint16> rangeShift;
107  };
108 
109  struct TableDirectory
110  {
111  BigEndian<quint32> identifier;
112  BigEndian<quint32> checkSum;
113  BigEndian<quint32> offset;
114  BigEndian<quint32> length;
115  };
116 
117  struct OS2Table
118  {
119  BigEndian<quint16> version;
120  BigEndian<qint16> avgCharWidth;
121  BigEndian<quint16> weightClass;
122  BigEndian<quint16> widthClass;
123  BigEndian<quint16> type;
124  BigEndian<qint16> subscriptXSize;
125  BigEndian<qint16> subscriptYSize;
126  BigEndian<qint16> subscriptXOffset;
127  BigEndian<qint16> subscriptYOffset;
128  BigEndian<qint16> superscriptXSize;
129  BigEndian<qint16> superscriptYSize;
130  BigEndian<qint16> superscriptXOffset;
131  BigEndian<qint16> superscriptYOffset;
132  BigEndian<qint16> strikeOutSize;
133  BigEndian<qint16> strikeOutPosition;
134  BigEndian<qint16> familyClass;
135  quint8 panose[10];
136  BigEndian<quint32> unicodeRanges[4];
137  quint8 vendorID[4];
138  BigEndian<quint16> selection;
139  BigEndian<quint16> firstCharIndex;
140  BigEndian<quint16> lastCharIndex;
141  BigEndian<qint16> typoAscender;
142  BigEndian<qint16> typoDescender;
143  BigEndian<qint16> typoLineGap;
144  BigEndian<quint16> winAscent;
145  BigEndian<quint16> winDescent;
146  BigEndian<quint32> codepageRanges[2];
147  BigEndian<qint16> height;
148  BigEndian<qint16> capHeight;
149  BigEndian<quint16> defaultChar;
150  BigEndian<quint16> breakChar;
151  BigEndian<quint16> maxContext;
152  };
153 
154 # pragma pack()
155 
156  class EmbeddedFont
157  {
158  public:
159  EmbeddedFont(const QByteArray &fontData) : m_fontData(fontData) {}
160 
161  QString changeFamilyName(const QString &newFamilyName);
162  QByteArray data() const { return m_fontData; }
163  TableDirectory *tableDirectoryEntry(const QByteArray &tagName);
164  QString familyName(TableDirectory *nameTableDirectory = 0);
165 
166  private:
167  QByteArray m_fontData;
168  };
169 
170  TableDirectory *EmbeddedFont::tableDirectoryEntry(const QByteArray &tagName)
171  {
172  Q_ASSERT(tagName.size() == 4);
173 
174  const BigEndian<quint32> *tagIdPtr =
175  reinterpret_cast<const BigEndian<quint32> *>(tagName.constData());
176  quint32 tagId = *tagIdPtr;
177 
178  OffsetSubTable *offsetSubTable = reinterpret_cast<OffsetSubTable *>(m_fontData.data());
179  TableDirectory *tableDirectory = reinterpret_cast<TableDirectory *>(offsetSubTable + 1);
180 
181  TableDirectory *nameTableDirectoryEntry = 0;
182  for (int i=0; i<offsetSubTable->numTables; ++i, ++tableDirectory) {
183  if (tableDirectory->identifier == tagId) {
184  nameTableDirectoryEntry = tableDirectory;
185  break;
186  }
187  }
188 
189  return nameTableDirectoryEntry;
190  }
191 
192  QString EmbeddedFont::familyName(TableDirectory *nameTableDirectoryEntry)
193  {
194  QString name;
195 
196  if (nameTableDirectoryEntry == 0)
197  nameTableDirectoryEntry = tableDirectoryEntry("name");
198 
199  if (nameTableDirectoryEntry != 0) {
200  NameTable *nameTable = reinterpret_cast<NameTable *>(m_fontData.data()
201  + nameTableDirectoryEntry->offset);
202  NameRecord *nameRecord = reinterpret_cast<NameRecord *>(nameTable + 1);
203  for (int i=0; i<nameTable->count; ++i, ++nameRecord) {
204  if (nameRecord->nameID == 1
205  && nameRecord->platformID == 3 // Windows
206  && nameRecord->languageID == 0x0409) { // US English
207  const void *ptr = reinterpret_cast<const quint8 *>(nameTable)
208  + nameTable->stringOffset
209  + nameRecord->offset;
210 
211  const BigEndian<quint16> *s = reinterpret_cast<const BigEndian<quint16> *>(ptr);
212  const BigEndian<quint16> *e = s + nameRecord->length / sizeof(quint16);
213  while (s != e)
214  name += QChar(*s++);
215  break;
216  }
217  }
218  }
219 
220  return name;
221  }
222 
223  QString EmbeddedFont::changeFamilyName(const QString &newFamilyName)
224  {
225  TableDirectory *nameTableDirectoryEntry = tableDirectoryEntry("name");
226  if (nameTableDirectoryEntry == 0)
227  return QString();
228 
229  QString oldFamilyName = familyName(nameTableDirectoryEntry);
230 
231  // Reserve size for name table header, five required name records and string
232  const int requiredRecordCount = 5;
233  quint16 nameIds[requiredRecordCount] = { 1, 2, 3, 4, 6 };
234 
235  int sizeOfHeader = sizeof(NameTable) + sizeof(NameRecord) * requiredRecordCount;
236  int newFamilyNameSize = newFamilyName.size() * sizeof(quint16);
237 
238  const QString regularString = QString::fromLatin1("Regular");
239  int regularStringSize = regularString.size() * sizeof(quint16);
240 
241  // Align table size of table to 32 bits (pad with 0)
242  int fullSize = ((sizeOfHeader + newFamilyNameSize + regularStringSize) & ~3) + 4;
243 
244  QByteArray newNameTable(fullSize, char(0));
245 
246  {
247  NameTable *nameTable = reinterpret_cast<NameTable *>(newNameTable.data());
248  nameTable->count = requiredRecordCount;
249  nameTable->stringOffset = sizeOfHeader;
250 
251  NameRecord *nameRecord = reinterpret_cast<NameRecord *>(nameTable + 1);
252  for (int i=0; i<requiredRecordCount; ++i, nameRecord++) {
253  nameRecord->nameID = nameIds[i];
254  nameRecord->encodingID = 1;
255  nameRecord->languageID = 0x0409;
256  nameRecord->platformID = 3;
257  nameRecord->length = newFamilyNameSize;
258 
259  // Special case for sub-family
260  if (nameIds[i] == 4) {
261  nameRecord->offset = newFamilyNameSize;
262  nameRecord->length = regularStringSize;
263  }
264  }
265 
266  // nameRecord now points to string data
267  BigEndian<quint16> *stringStorage = reinterpret_cast<BigEndian<quint16> *>(nameRecord);
268  const quint16 *sourceString = newFamilyName.utf16();
269  for (int i=0; i<newFamilyName.size(); ++i)
270  stringStorage[i] = sourceString[i];
271  stringStorage += newFamilyName.size();
272 
273  sourceString = regularString.utf16();
274  for (int i=0; i<regularString.size(); ++i)
275  stringStorage[i] = sourceString[i];
276  }
277 
278  quint32 *p = reinterpret_cast<quint32 *>(newNameTable.data());
279  quint32 *tableEnd = reinterpret_cast<quint32 *>(newNameTable.data() + fullSize);
280 
281  quint32 checkSum = 0;
282  while (p < tableEnd)
283  checkSum += *(p++);
284 
285  nameTableDirectoryEntry->checkSum = checkSum;
286  nameTableDirectoryEntry->offset = m_fontData.size();
287  nameTableDirectoryEntry->length = fullSize;
288 
289  m_fontData.append(newNameTable);
290 
291  return oldFamilyName;
292  }
293 
294 #if !defined(QT_NO_DIRECTWRITE)
295 
296  class DirectWriteFontFileStream: public IDWriteFontFileStream
297  {
298  public:
299  DirectWriteFontFileStream(const QByteArray &fontData)
300  : m_fontData(fontData)
301  , m_referenceCount(0)
302  {
303  }
304 
305  ~DirectWriteFontFileStream()
306  {
307  }
308 
309  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object);
310  ULONG STDMETHODCALLTYPE AddRef();
311  ULONG STDMETHODCALLTYPE Release();
312 
313  HRESULT STDMETHODCALLTYPE ReadFileFragment(const void **fragmentStart, UINT64 fileOffset,
314  UINT64 fragmentSize, OUT void **fragmentContext);
315  void STDMETHODCALLTYPE ReleaseFileFragment(void *fragmentContext);
316  HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64 *fileSize);
317  HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64 *lastWriteTime);
318 
319  private:
320  QByteArray m_fontData;
321  ULONG m_referenceCount;
322  };
323 
324  HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::QueryInterface(REFIID iid, void **object)
325  {
326  if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) {
327  *object = this;
328  AddRef();
329  return S_OK;
330  } else {
331  *object = NULL;
332  return E_NOINTERFACE;
333  }
334  }
335 
336  ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::AddRef()
337  {
338  return InterlockedIncrement(&m_referenceCount);
339  }
340 
341  ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::Release()
342  {
343  ULONG newCount = InterlockedDecrement(&m_referenceCount);
344  if (newCount == 0)
345  delete this;
346  return newCount;
347  }
348 
349  HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::ReadFileFragment(
350  const void **fragmentStart,
351  UINT64 fileOffset,
352  UINT64 fragmentSize,
353  OUT void **fragmentContext)
354  {
355  *fragmentContext = NULL;
356  if (fragmentSize + fileOffset <= m_fontData.size()) {
357  *fragmentStart = m_fontData.data() + fileOffset;
358  return S_OK;
359  } else {
360  *fragmentStart = NULL;
361  return E_FAIL;
362  }
363  }
364 
365  void STDMETHODCALLTYPE DirectWriteFontFileStream::ReleaseFileFragment(void *)
366  {
367  }
368 
369  HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetFileSize(UINT64 *fileSize)
370  {
371  *fileSize = m_fontData.size();
372  return S_OK;
373  }
374 
375  HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetLastWriteTime(UINT64 *lastWriteTime)
376  {
377  *lastWriteTime = 0;
378  return E_NOTIMPL;
379  }
380 
381  class DirectWriteFontFileLoader: public IDWriteFontFileLoader
382  {
383  public:
384  DirectWriteFontFileLoader() : m_referenceCount(0) {}
385 
386  ~DirectWriteFontFileLoader()
387  {
388  }
389 
390  inline void addKey(const void *key, const QByteArray &fontData)
391  {
392  Q_ASSERT(!m_fontDatas.contains(key));
393  m_fontDatas.insert(key, fontData);
394  }
395 
396  inline void removeKey(const void *key)
397  {
398  m_fontDatas.remove(key);
399  }
400 
401  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object);
402  ULONG STDMETHODCALLTYPE AddRef();
403  ULONG STDMETHODCALLTYPE Release();
404 
405  HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const *fontFileReferenceKey,
406  UINT32 fontFileReferenceKeySize,
407  OUT IDWriteFontFileStream **fontFileStream);
408 
409  private:
410  ULONG m_referenceCount;
412  };
413 
414  HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::QueryInterface(const IID &iid,
415  void **object)
416  {
417  if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) {
418  *object = this;
419  AddRef();
420  return S_OK;
421  } else {
422  *object = NULL;
423  return E_NOINTERFACE;
424  }
425  }
426 
427  ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::AddRef()
428  {
429  return InterlockedIncrement(&m_referenceCount);
430  }
431 
432  ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::Release()
433  {
434  ULONG newCount = InterlockedDecrement(&m_referenceCount);
435  if (newCount == 0)
436  delete this;
437  return newCount;
438  }
439 
440  HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::CreateStreamFromKey(
441  void const *fontFileReferenceKey,
442  UINT32 fontFileReferenceKeySize,
443  IDWriteFontFileStream **fontFileStream)
444  {
445  Q_UNUSED(fontFileReferenceKeySize);
446 
447  if (fontFileReferenceKeySize != sizeof(const void *)) {
448  qWarning("DirectWriteFontFileLoader::CreateStreamFromKey: Wrong key size");
449  return E_FAIL;
450  }
451 
452  const void *key = *reinterpret_cast<void * const *>(fontFileReferenceKey);
453  *fontFileStream = NULL;
454  if (!m_fontDatas.contains(key))
455  return E_FAIL;
456 
457  QByteArray fontData = m_fontDatas.value(key);
458  DirectWriteFontFileStream *stream = new DirectWriteFontFileStream(fontData);
459  stream->AddRef();
460  *fontFileStream = stream;
461 
462  return S_OK;
463  }
464 
465  class CustomFontFileLoader
466  {
467  public:
468  CustomFontFileLoader() : m_directWriteFactory(0), m_directWriteFontFileLoader(0)
469  {
470  HRESULT hres = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
471  __uuidof(IDWriteFactory),
472  reinterpret_cast<IUnknown **>(&m_directWriteFactory));
473  if (FAILED(hres)) {
474  qErrnoWarning(hres, "CustomFontFileLoader::CustomFontFileLoader: "
475  "DWriteCreateFactory failed.");
476  } else {
477  m_directWriteFontFileLoader = new DirectWriteFontFileLoader();
478  m_directWriteFactory->RegisterFontFileLoader(m_directWriteFontFileLoader);
479  }
480  }
481 
482  ~CustomFontFileLoader()
483  {
484  if (m_directWriteFactory != 0 && m_directWriteFontFileLoader != 0)
485  m_directWriteFactory->UnregisterFontFileLoader(m_directWriteFontFileLoader);
486 
487  if (m_directWriteFactory != 0)
488  m_directWriteFactory->Release();
489  }
490 
491  void addKey(const void *key, const QByteArray &fontData)
492  {
493  if (m_directWriteFontFileLoader != 0)
494  m_directWriteFontFileLoader->addKey(key, fontData);
495  }
496 
497  void removeKey(const void *key)
498  {
499  if (m_directWriteFontFileLoader != 0)
500  m_directWriteFontFileLoader->removeKey(key);
501  }
502 
503  IDWriteFontFileLoader *loader() const
504  {
505  return m_directWriteFontFileLoader;
506  }
507 
508  private:
509  IDWriteFactory *m_directWriteFactory;
510  DirectWriteFontFileLoader *m_directWriteFontFileLoader;
511  };
512 
513 #endif
514 
515 } // Anonymous namespace
516 
517 
518 // From qfontdatabase_win.cpp
519 extern QFontEngine *qt_load_font_engine_win(const QFontDef &request);
520 // From qfontdatabase.cpp
521 extern QFont::Weight weightFromInteger(int weight);
522 
523 typedef HANDLE (WINAPI *PtrAddFontMemResourceEx)(PVOID, DWORD, PVOID, DWORD *);
525 typedef BOOL (WINAPI *PtrRemoveFontMemResourceEx)(HANDLE);
527 
528 static void resolveGdi32()
529 {
530  static bool triedResolve = false;
531  if (!triedResolve) {
532  QSystemLibrary gdi32(QLatin1String("gdi32"));
533  if (gdi32.load()) {
534  ptrAddFontMemResourceEx = (PtrAddFontMemResourceEx)gdi32.resolve("AddFontMemResourceEx");
535  ptrRemoveFontMemResourceEx = (PtrRemoveFontMemResourceEx)gdi32.resolve("RemoveFontMemResourceEx");
536  }
537 
538  triedResolve = true;
539  }
540 }
541 
543 {
544  if (fontHandle != NULL) {
545  if (ptrRemoveFontMemResourceEx)
546  ptrRemoveFontMemResourceEx(fontHandle);
547  fontHandle = NULL;
548  }
549 }
550 
553  QFont::HintingPreference hintingPreference)
554 {
555  EmbeddedFont font(fontData);
556 
557 #if !defined(QT_NO_DIRECTWRITE)
558  if (hintingPreference == QFont::PreferDefaultHinting
559  || hintingPreference == QFont::PreferFullHinting)
560 #endif
561  {
562  GUID guid;
563  CoCreateGuid(&guid);
564 
565  QString uniqueFamilyName = QLatin1Char('f')
566  + QString::number(guid.Data1, 36) + QLatin1Char('-')
567  + QString::number(guid.Data2, 36) + QLatin1Char('-')
568  + QString::number(guid.Data3, 36) + QLatin1Char('-')
569  + QString::number(*reinterpret_cast<quint64 *>(guid.Data4), 36);
570 
571  QString actualFontName = font.changeFamilyName(uniqueFamilyName);
572  if (actualFontName.isEmpty()) {
573  qWarning("QRawFont::platformLoadFromData: Can't change family name of font");
574  return;
575  }
576 
577  Q_ASSERT(fontHandle == NULL);
578  resolveGdi32();
579  if (ptrAddFontMemResourceEx && ptrRemoveFontMemResourceEx) {
580  DWORD count = 0;
581  QByteArray newFontData = font.data();
582  fontHandle = ptrAddFontMemResourceEx((void *)newFontData.constData(), newFontData.size(),
583  0, &count);
584  if (count == 0 && fontHandle != NULL) {
585  ptrRemoveFontMemResourceEx(fontHandle);
586  fontHandle = NULL;
587  }
588  }
589 
590  if (fontHandle == NULL) {
591  qWarning("QRawFont::platformLoadFromData: AddFontMemResourceEx failed");
592  } else {
593  QFontDef request;
594  request.family = uniqueFamilyName;
595  request.pixelSize = pixelSize;
597  request.hintingPreference = hintingPreference;
598 
599  fontEngine = qt_load_font_engine_win(request);
600  if (request.family != fontEngine->fontDef.family) {
601  qWarning("QRawFont::platformLoadFromData: Failed to load font. "
602  "Got fallback instead: %s", qPrintable(fontEngine->fontDef.family));
603  if (fontEngine->cache_count == 0 && fontEngine->ref == 0)
604  delete fontEngine;
605  fontEngine = 0;
606  } else {
607  Q_ASSERT(fontEngine->cache_count == 0 && fontEngine->ref == 0);
608 
609  // Override the generated font name
610  static_cast<QFontEngineWin *>(fontEngine)->uniqueFamilyName = uniqueFamilyName;
611  fontEngine->fontDef.family = actualFontName;
612  fontEngine->ref.ref();
613  }
614  }
615  }
616 #if !defined(QT_NO_DIRECTWRITE)
617  else {
618  CustomFontFileLoader fontFileLoader;
619  fontFileLoader.addKey(this, fontData);
620 
621  IDWriteFactory *factory = NULL;
622  HRESULT hres = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
623  __uuidof(IDWriteFactory),
624  reinterpret_cast<IUnknown **>(&factory));
625  if (FAILED(hres)) {
626  qErrnoWarning(hres, "QRawFont::platformLoadFromData: DWriteCreateFactory failed");
627  return;
628  }
629 
630  IDWriteFontFile *fontFile = NULL;
631  void *key = this;
632 
633  hres = factory->CreateCustomFontFileReference(&key, sizeof(void *),
634  fontFileLoader.loader(), &fontFile);
635  if (FAILED(hres)) {
636  qErrnoWarning(hres, "QRawFont::platformLoadFromData: "
637  "CreateCustomFontFileReference failed");
638  factory->Release();
639  return;
640  }
641 
642  BOOL isSupportedFontType;
643  DWRITE_FONT_FILE_TYPE fontFileType;
644  DWRITE_FONT_FACE_TYPE fontFaceType;
645  UINT32 numberOfFaces;
646  fontFile->Analyze(&isSupportedFontType, &fontFileType, &fontFaceType, &numberOfFaces);
647  if (!isSupportedFontType) {
648  fontFile->Release();
649  factory->Release();
650  return;
651  }
652 
653  IDWriteFontFace *directWriteFontFace = NULL;
654  hres = factory->CreateFontFace(fontFaceType, 1, &fontFile, 0, DWRITE_FONT_SIMULATIONS_NONE,
655  &directWriteFontFace);
656  if (FAILED(hres)) {
657  qErrnoWarning(hres, "QRawFont::platformLoadFromData: CreateFontFace failed");
658  fontFile->Release();
659  factory->Release();
660  return;
661  }
662 
663  fontFile->Release();
664 
665  fontEngine = new QFontEngineDirectWrite(factory, directWriteFontFace, pixelSize);
666 
667  // Get font family from font data
668  fontEngine->fontDef.family = font.familyName();
669  fontEngine->ref.ref();
670 
671  directWriteFontFace->Release();
672  factory->Release();
673  }
674 #endif
675 
676  // Get style and weight info
677  if (fontEngine != 0) {
678  TableDirectory *os2TableEntry = font.tableDirectoryEntry("OS/2");
679  if (os2TableEntry != 0) {
680  const OS2Table *os2Table =
681  reinterpret_cast<const OS2Table *>(fontData.constData()
682  + os2TableEntry->offset);
683 
684  bool italic = os2Table->selection & 1;
685  bool oblique = os2Table->selection & 128;
686 
687  if (italic)
688  fontEngine->fontDef.style = QFont::StyleItalic;
689  else if (oblique)
690  fontEngine->fontDef.style = QFont::StyleOblique;
691  else
692  fontEngine->fontDef.style = QFont::StyleNormal;
693 
694  fontEngine->fontDef.weight = weightFromInteger(os2Table->weightClass);
695  }
696  }
697 }
698 
700 
701 #endif // QT_NO_RAWFONT
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
HintingPreference
This enum describes the different levels of hinting that can be applied to glyphs to improve legibili...
Definition: qfont.h:96
int type
Definition: qmetatype.cpp:239
double qreal
Definition: qglobal.h:1193
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
Definition: quuid.h:52
static void resolveGdi32()
static PtrAddFontMemResourceEx ptrAddFontMemResourceEx
ulong Data1
Definition: quuid.h:54
QFontEngine * qt_load_font_engine_win(const QFontDef &request)
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
Weight
Qt uses a weighting scale from 0 to 99 similar to, but not the same as, the scales used in Windows or...
Definition: qfont.h:103
unsigned char quint8
Definition: qglobal.h:934
The QString class provides a Unicode character string.
Definition: qstring.h:83
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
bool load(bool onlySystemDirectory=true)
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
static void addKey(QString &str, const QString &theKey, QKeySequence::SequenceFormat format)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
static FILE * stream
QFont::Weight weightFromInteger(int weight)
static float pixelSize(const QFontDef &request, int dpi)
Definition: qfont_win.cpp:80
static QFontEngine::FaceId fontFile(const QByteArray &_xname, QFreetypeFace **freetype, int *synth)
int size() const
Returns the number of characters in this string.
Definition: qstring.h:102
void platformLoadFromData(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
const char * name
#define CoCreateGuid
unsigned short quint16
Definition: qglobal.h:936
Q_CORE_EXPORT void qWarning(const char *,...)
static const char * data(const QByteArray &arr)
const T * ptr(const T &t)
BOOL(WINAPI * PtrRemoveFontMemResourceEx)(HANDLE)
void * HANDLE
Definition: qnamespace.h:1671
qreal pixelSize
Definition: qfont_p.h:90
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
long HRESULT
void * resolve(const char *symbol)
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
uchar Data4[8]
Definition: quuid.h:57
int key
unsigned int quint32
Definition: qglobal.h:938
void platformCleanUp()
Definition: qrawfont_ft.cpp:98
ushort Data3
Definition: quuid.h:56
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
QString family
Definition: qfont_p.h:82
uint hintingPreference
Definition: qfont_p.h:101
#define qPrintable(string)
Definition: qglobal.h:1750
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
ushort Data2
Definition: quuid.h:55
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
HANDLE(WINAPI * PtrAddFontMemResourceEx)(PVOID, DWORD, PVOID, DWORD *)
static PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx
const ushort * utf16() const
Returns the QString as a &#39;\0\&#39;-terminated array of unsigned shorts.
Definition: qstring.cpp:5290
void qErrnoWarning(const char *msg,...)
Definition: qglobal.cpp:2954