Qt 4.8
qfontengine_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 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 #if _WIN32_WINNT < 0x0500
43 #undef _WIN32_WINNT
44 #define _WIN32_WINNT 0x0500
45 #endif
46 
47 #include "qfontengine_p.h"
48 #include "qtextengine_p.h"
49 #include <qglobal.h>
50 #include "qt_windows.h"
51 #include <private/qapplication_p.h>
52 
53 #include <private/qsystemlibrary_p.h>
54 #include <qpaintdevice.h>
55 #include <qpainter.h>
56 #include <limits.h>
57 
58 #include <qendian.h>
59 #include <qmath.h>
60 #include <qthreadstorage.h>
61 
62 #include <private/qunicodetables_p.h>
63 #include <qbitmap.h>
64 
65 #include <private/qpainter_p.h>
66 #include "qpaintengine.h"
67 #include "qvarlengtharray.h"
68 #include <private/qpaintengine_raster_p.h>
69 #include <private/qnativeimage_p.h>
70 
71 #if defined(Q_WS_WINCE)
72 #include "qguifunctions_wince.h"
73 #endif
74 
75 //### mingw needed define
76 #ifndef TT_PRIM_CSPLINE
77 #define TT_PRIM_CSPLINE 3
78 #endif
79 
80 #ifdef MAKE_TAG
81 #undef MAKE_TAG
82 #endif
83 // GetFontData expects the tags in little endian ;(
84 #define MAKE_TAG(ch1, ch2, ch3, ch4) (\
85  (((quint32)(ch4)) << 24) | \
86  (((quint32)(ch3)) << 16) | \
87  (((quint32)(ch2)) << 8) | \
88  ((quint32)(ch1)) \
89  )
90 
91 // common DC for all fonts
92 
94 
95 class QtHDC
96 {
97  HDC _hdc;
98 public:
100  {
101  HDC displayDC = GetDC(0);
102  _hdc = CreateCompatibleDC(displayDC);
103  ReleaseDC(0, displayDC);
104  }
106  {
107  if (_hdc)
108  DeleteDC(_hdc);
109  }
110  HDC hdc() const
111  {
112  return _hdc;
113  }
114 };
115 
116 #ifndef QT_NO_THREAD
119 {
120  QtHDC *&hdc = local_shared_dc()->localData();
121  if (!hdc)
122  hdc = new QtHDC;
123  return hdc->hdc();
124 }
125 #else
126 HDC shared_dc()
127 {
128  return 0;
129 }
130 #endif
131 
132 #ifndef Q_WS_WINCE
133 typedef BOOL (WINAPI *PtrGetCharWidthI)(HDC, UINT, UINT, LPWORD, LPINT);
134 static PtrGetCharWidthI ptrGetCharWidthI = 0;
135 static bool resolvedGetCharWidthI = false;
136 
137 static void resolveGetCharWidthI()
138 {
139  if (resolvedGetCharWidthI)
140  return;
141 
142  QSystemLibrary gdi32(QLatin1String("gdi32"));
143  ptrGetCharWidthI = (PtrGetCharWidthI)gdi32.resolve("GetCharWidthI");
144 
145  resolvedGetCharWidthI = true;
146 }
147 #endif // !defined(Q_WS_WINCE)
148 
149 // defined in qtextengine_win.cpp
150 typedef void *SCRIPT_CACHE;
151 typedef HRESULT (WINAPI *fScriptFreeCache)(SCRIPT_CACHE *);
153 
154 static inline quint32 getUInt(unsigned char *p)
155 {
156  quint32 val;
157  val = *p++ << 24;
158  val |= *p++ << 16;
159  val |= *p++ << 8;
160  val |= *p;
161 
162  return val;
163 }
164 
165 static inline quint16 getUShort(unsigned char *p)
166 {
167  quint16 val;
168  val = *p++ << 8;
169  val |= *p;
170 
171  return val;
172 }
173 
174 // general font engine
175 
177 {
178  if(lineWidth > 0)
179  return lineWidth;
180 
182 }
183 
184 static OUTLINETEXTMETRIC *getOutlineTextMetric(HDC hdc)
185 {
186  int size;
187  size = GetOutlineTextMetrics(hdc, 0, 0);
188  OUTLINETEXTMETRIC *otm = (OUTLINETEXTMETRIC *)malloc(size);
189  GetOutlineTextMetrics(hdc, size, otm);
190  return otm;
191 }
192 
194 {
195  ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE);
196  HDC hdc = shared_dc();
197  SelectObject(hdc, hfont);
198  bool symb = false;
199  if (ttf) {
200  cmapTable = getSfntTable(qbswap<quint32>(MAKE_TAG('c', 'm', 'a', 'p')));
201  int size = 0;
202  cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()),
203  cmapTable.size(), &symb, &size);
204  }
205  if (!cmap) {
206  ttf = false;
207  symb = false;
208  }
209  symbol = symb;
210  designToDevice = 1;
211  _faceId.index = 0;
212  if(cmap) {
213  OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc);
214  designToDevice = QFixed((int)otm->otmEMSquare)/int(otm->otmTextMetrics.tmHeight);
215  unitsPerEm = otm->otmEMSquare;
216  x_height = (int)otm->otmsXHeight;
217  loadKerningPairs(designToDevice);
218  _faceId.filename = QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpFullName)).toLatin1();
219  lineWidth = otm->otmsUnderscoreSize;
220  fsType = otm->otmfsType;
221  free(otm);
222  } else {
223  unitsPerEm = tm.tmHeight;
224  }
225 }
226 
227 
228 inline unsigned int getChar(const QChar *str, int &i, const int len)
229 {
230  uint ucs4 = str[i].unicode();
231  if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) {
232  ++i;
233  ucs4 = QChar::surrogateToUcs4(ucs4, str[i].unicode());
234  }
235  return ucs4;
236 }
237 
238 int QFontEngineWin::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout *glyphs, bool mirrored) const
239 {
240  int i = 0;
241  int glyph_pos = 0;
242  if (mirrored) {
243 #if defined(Q_WS_WINCE)
244  {
245 #else
246  if (symbol) {
247  for (; i < numChars; ++i, ++glyph_pos) {
248  unsigned int uc = getChar(str, i, numChars);
249  glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
250  if (!glyphs->glyphs[glyph_pos] && uc < 0x100)
251  glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
252  }
253  } else if (ttf) {
254  for (; i < numChars; ++i, ++glyph_pos) {
255  unsigned int uc = getChar(str, i, numChars);
256  glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, QChar::mirroredChar(uc));
257  }
258  } else {
259 #endif
260  wchar_t first = tm.tmFirstChar;
261  wchar_t last = tm.tmLastChar;
262 
263  for (; i < numChars; ++i, ++glyph_pos) {
264  uint ucs = QChar::mirroredChar(getChar(str, i, numChars));
265  if (
266 #ifdef Q_WS_WINCE
267  tm.tmFirstChar > 60000 || // see line 375
268 #endif
269  ucs >= first && ucs <= last)
270  glyphs->glyphs[glyph_pos] = ucs;
271  else
272  glyphs->glyphs[glyph_pos] = 0;
273  }
274  }
275  } else {
276 #if defined(Q_WS_WINCE)
277  {
278 #else
279  if (symbol) {
280  for (; i < numChars; ++i, ++glyph_pos) {
281  unsigned int uc = getChar(str, i, numChars);
282  glyphs->glyphs[i] = getTrueTypeGlyphIndex(cmap, uc);
283  if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
284  glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
285  }
286  } else if (ttf) {
287  for (; i < numChars; ++i, ++glyph_pos) {
288  unsigned int uc = getChar(str, i, numChars);
289  glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
290  }
291  } else {
292 #endif
293  wchar_t first = tm.tmFirstChar;
294  wchar_t last = tm.tmLastChar;
295 
296  for (; i < numChars; ++i, ++glyph_pos) {
297  uint uc = getChar(str, i, numChars);
298  if (
299 #ifdef Q_WS_WINCE
300  tm.tmFirstChar > 60000 || // see comment in QFontEngineWin
301 #endif
302  uc >= first && uc <= last)
303  glyphs->glyphs[glyph_pos] = uc;
304  else
305  glyphs->glyphs[glyph_pos] = 0;
306  }
307  }
308  }
309  glyphs->numGlyphs = glyph_pos;
310  return glyph_pos;
311 }
312 
313 
314 QFontEngineWin::QFontEngineWin(const QString &name, HFONT _hfont, bool stockFont, LOGFONT lf)
315 {
316  //qDebug("regular windows font engine created: font='%s', size=%d", name, lf.lfHeight);
317 
318  _name = name;
319 
320  cmap = 0;
321  hfont = _hfont;
322  logfont = lf;
323  HDC hdc = shared_dc();
324  SelectObject(hdc, hfont);
325  this->stockFont = stockFont;
326  fontDef.pixelSize = -lf.lfHeight;
327 
328  lbearing = SHRT_MIN;
329  rbearing = SHRT_MIN;
330  synthesized_flags = -1;
331  lineWidth = -1;
332  x_height = -1;
333 
334  BOOL res = GetTextMetrics(hdc, &tm);
335  fontDef.fixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH);
336  if (!res) {
337  qErrnoWarning("QFontEngineWin: GetTextMetrics failed");
338  ZeroMemory(&tm, sizeof(TEXTMETRIC));
339  }
340 
341  cache_cost = tm.tmHeight * tm.tmAveCharWidth * 2000;
342  getCMap();
343 
344  widthCache = 0;
345  widthCacheSize = 0;
346  designAdvances = 0;
347  designAdvancesSize = 0;
348 
349 #ifndef Q_WS_WINCE
350  if (!resolvedGetCharWidthI)
351  resolveGetCharWidthI();
352 #endif
353 }
354 
356 {
357  if (designAdvances)
358  free(designAdvances);
359 
360  if (widthCache)
361  free(widthCache);
362 
363  // make sure we aren't by accident still selected
364  SelectObject(shared_dc(), (HFONT)GetStockObject(SYSTEM_FONT));
365 
366  if (!stockFont) {
367  if (!DeleteObject(hfont))
368  qErrnoWarning("QFontEngineWin: failed to delete non-stock font...");
369  }
370 }
371 
373 {
374  LOGFONT f = logfont;
375  f.lfHeight = unitsPerEm;
376  HFONT designFont = CreateFontIndirect(&f);
377  return SelectObject(shared_dc(), designFont);
378 }
379 
380 bool QFontEngineWin::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
381 {
382  if (*nglyphs < len) {
383  *nglyphs = len;
384  return false;
385  }
386 
387  *nglyphs = getGlyphIndexes(str, len, glyphs, flags & QTextEngine::RightToLeft);
388 
389  if (flags & QTextEngine::GlyphIndicesOnly)
390  return true;
391 
392  recalcAdvances(glyphs, flags);
393  return true;
394 }
395 
396 inline void calculateTTFGlyphWidth(HDC hdc, UINT glyph, int &width)
397 {
398 #if defined(Q_WS_WINCE)
399  GetCharWidth32(hdc, glyph, glyph, &width);
400 #else
401  if (ptrGetCharWidthI)
402  ptrGetCharWidthI(hdc, glyph, 1, 0, &width);
403 #endif
404 }
405 
406 void QFontEngineWin::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
407 {
408  HGDIOBJ oldFont = 0;
409  HDC hdc = shared_dc();
410  if (ttf && (flags & QTextEngine::DesignMetrics)) {
411  for(int i = 0; i < glyphs->numGlyphs; i++) {
412  unsigned int glyph = glyphs->glyphs[i];
413  if(int(glyph) >= designAdvancesSize) {
414  int newSize = (glyph + 256) >> 8 << 8;
415  designAdvances = q_check_ptr((QFixed *)realloc(designAdvances,
416  newSize*sizeof(QFixed)));
417  for(int i = designAdvancesSize; i < newSize; ++i)
418  designAdvances[i] = -1000000;
419  designAdvancesSize = newSize;
420  }
421  if (designAdvances[glyph] < -999999) {
422  if (!oldFont)
423  oldFont = selectDesignFont();
424 
425  int width = 0;
426  calculateTTFGlyphWidth(hdc, glyph, width);
427  designAdvances[glyph] = QFixed(width) / designToDevice;
428  }
429  glyphs->advances_x[i] = designAdvances[glyph];
430  glyphs->advances_y[i] = 0;
431  }
432  if(oldFont)
433  DeleteObject(SelectObject(hdc, oldFont));
434  } else {
435  for(int i = 0; i < glyphs->numGlyphs; i++) {
436  unsigned int glyph = glyphs->glyphs[i];
437 
438  glyphs->advances_y[i] = 0;
439 
440  if (glyph >= widthCacheSize) {
441  int newSize = (glyph + 256) >> 8 << 8;
442  widthCache = q_check_ptr((unsigned char *)realloc(widthCache,
443  newSize*sizeof(QFixed)));
444  memset(widthCache + widthCacheSize, 0, newSize - widthCacheSize);
445  widthCacheSize = newSize;
446  }
447  glyphs->advances_x[i] = widthCache[glyph];
448  // font-width cache failed
449  if (glyphs->advances_x[i] == 0) {
450  int width = 0;
451  if (!oldFont)
452  oldFont = SelectObject(hdc, hfont);
453 
454  if (!ttf) {
455  QChar ch[2] = { ushort(glyph), 0 };
456  int chrLen = 1;
457  if (glyph > 0xffff) {
458  ch[0] = QChar::highSurrogate(glyph);
459  ch[1] = QChar::lowSurrogate(glyph);
460  ++chrLen;
461  }
462  SIZE size = {0, 0};
463  GetTextExtentPoint32(hdc, (wchar_t *)ch, chrLen, &size);
464  width = size.cx;
465  } else {
466  calculateTTFGlyphWidth(hdc, glyph, width);
467  }
468  glyphs->advances_x[i] = width;
469  // if glyph's within cache range, store it for later
470  if (width > 0 && width < 0x100)
471  widthCache[glyph] = width;
472  }
473  }
474 
475  if (oldFont)
476  SelectObject(hdc, oldFont);
477  }
478 }
479 
481 {
482  if (glyphs.numGlyphs == 0)
483  return glyph_metrics_t();
484 
485  QFixed w = 0;
486  for (int i = 0; i < glyphs.numGlyphs; ++i)
487  w += glyphs.effectiveAdvance(i);
488 
489  return glyph_metrics_t(0, -tm.tmAscent, w - lastRightBearing(glyphs), tm.tmHeight, w, 0);
490 }
491 
492 #ifndef Q_WS_WINCE
493 bool QFontEngineWin::getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const
494 {
495  Q_ASSERT(metrics != 0);
496 
497  HDC hdc = shared_dc();
498 
499  GLYPHMETRICS gm;
500  DWORD res = 0;
501  MAT2 mat;
502  mat.eM11.value = mat.eM22.value = 1;
503  mat.eM11.fract = mat.eM22.fract = 0;
504  mat.eM21.value = mat.eM12.value = 0;
505  mat.eM21.fract = mat.eM12.fract = 0;
506 
507  if (t.type() > QTransform::TxTranslate) {
508  // We need to set the transform using the HDC's world
509  // matrix rather than using the MAT2 above, because the
510  // results provided when transforming via MAT2 does not
511  // match the glyphs that are drawn using a WorldTransform
512  XFORM xform;
513  xform.eM11 = t.m11();
514  xform.eM12 = t.m12();
515  xform.eM21 = t.m21();
516  xform.eM22 = t.m22();
517  xform.eDx = 0;
518  xform.eDy = 0;
519  SetGraphicsMode(hdc, GM_ADVANCED);
520  SetWorldTransform(hdc, &xform);
521  }
522 
523  uint format = GGO_METRICS;
524  if (ttf)
525  format |= GGO_GLYPH_INDEX;
526  res = GetGlyphOutline(hdc, glyph, format, &gm, 0, 0, &mat);
527 
528  if (t.type() > QTransform::TxTranslate) {
529  XFORM xform;
530  xform.eM11 = xform.eM22 = 1;
531  xform.eM12 = xform.eM21 = xform.eDx = xform.eDy = 0;
532  SetWorldTransform(hdc, &xform);
533  SetGraphicsMode(hdc, GM_COMPATIBLE);
534  }
535 
536  if (res != GDI_ERROR) {
537  *metrics = glyph_metrics_t(gm.gmptGlyphOrigin.x, -gm.gmptGlyphOrigin.y,
538  (int)gm.gmBlackBoxX, (int)gm.gmBlackBoxY, gm.gmCellIncX, gm.gmCellIncY);
539  return true;
540  } else {
541  return false;
542  }
543 }
544 #endif
545 
547 {
548 #ifndef Q_WS_WINCE
549  HDC hdc = shared_dc();
550  SelectObject(hdc, hfont);
551 
552  glyph_metrics_t glyphMetrics;
553  bool success = getOutlineMetrics(glyph, t, &glyphMetrics);
554 
555  if (!ttf && !success) {
556  // Bitmap fonts
557  wchar_t ch = glyph;
558  ABCFLOAT abc;
559  GetCharABCWidthsFloat(hdc, ch, ch, &abc);
560  int width = qRound(abc.abcfB);
561 
562  return glyph_metrics_t(QFixed::fromReal(abc.abcfA), -tm.tmAscent, width, tm.tmHeight, width, 0).transformed(t);
563  }
564 
565  return glyphMetrics;
566 #else
567  HDC hdc = shared_dc();
568  HGDIOBJ oldFont = SelectObject(hdc, hfont);
569 
570  ABC abc;
571  int width;
572  int advance;
573 #ifdef GWES_MGTT // true type fonts
574  if (GetCharABCWidths(hdc, glyph, glyph, &abc)) {
575  width = qAbs(abc.abcA) + abc.abcB + qAbs(abc.abcC);
576  advance = abc.abcA + abc.abcB + abc.abcC;
577  }
578  else
579 #endif
580 #if defined(GWES_MGRAST) || defined(GWES_MGRAST2) // raster fonts
581  if (GetCharWidth32(hdc, glyph, glyph, &width)) {
582  advance = width;
583  }
584  else
585 #endif
586  { // fallback
587  width = tm.tmMaxCharWidth;
588  advance = width;
589  }
590 
591  SelectObject(hdc, oldFont);
592  return glyph_metrics_t(0, -tm.tmAscent, width, tm.tmHeight, advance, 0).transformed(t);
593 #endif
594 }
595 
597 {
598  return tm.tmAscent;
599 }
600 
602 {
603  // ### we substract 1 to even out the historical +1 in QFontMetrics's
604  // ### height=asc+desc+1 equation. Fix in Qt5.
605  return tm.tmDescent - 1;
606 }
607 
609 {
610  return tm.tmExternalLeading;
611 }
612 
613 
615 {
616  if(x_height >= 0)
617  return x_height;
618  return QFontEngine::xHeight();
619 }
620 
622 {
623  return tm.tmAveCharWidth;
624 }
625 
627 {
628  return tm.tmMaxCharWidth;
629 }
630 
631 enum { max_font_count = 256 };
632 static const ushort char_table[] = {
633  40,
634  67,
635  70,
636  75,
637  86,
638  88,
639  89,
640  91,
641  102,
642  114,
643  124,
644  127,
645  205,
646  645,
647  884,
648  922,
649  1070,
650  12386,
651  0
652 };
653 
654 static const int char_table_entries = sizeof(char_table)/sizeof(ushort);
655 
656 #ifndef Q_CC_MINGW
657 void QFontEngineWin::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rightBearing)
658 {
659  HDC hdc = shared_dc();
660  SelectObject(hdc, hfont);
661 
662 #ifndef Q_WS_WINCE
663  if (ttf)
664 #endif
665 
666  {
667  ABC abcWidths;
668  GetCharABCWidthsI(hdc, glyph, 1, 0, &abcWidths);
669  if (leftBearing)
670  *leftBearing = abcWidths.abcA;
671  if (rightBearing)
672  *rightBearing = abcWidths.abcC;
673  }
674 
675 #ifndef Q_WS_WINCE
676  else {
677  QFontEngine::getGlyphBearings(glyph, leftBearing, rightBearing);
678  }
679 #endif
680 }
681 #endif // Q_CC_MINGW
682 
684 {
685  if (lbearing == SHRT_MIN)
686  minRightBearing(); // calculates both
687 
688  return lbearing;
689 }
690 
692 {
693 #ifdef Q_WS_WINCE
694  if (rbearing == SHRT_MIN) {
695  int ml = 0;
696  int mr = 0;
697  HDC hdc = shared_dc();
698  SelectObject(hdc, hfont);
699  if (ttf) {
700  ABC *abc = 0;
701  int n = tm.tmLastChar - tm.tmFirstChar;
702  if (n <= max_font_count) {
703  abc = new ABC[n+1];
704  GetCharABCWidths(hdc, tm.tmFirstChar, tm.tmLastChar, abc);
705  } else {
706  abc = new ABC[char_table_entries+1];
707  for(int i = 0; i < char_table_entries; i++)
708  GetCharABCWidths(hdc, char_table[i], char_table[i], abc+i);
709  n = char_table_entries;
710  }
711  ml = abc[0].abcA;
712  mr = abc[0].abcC;
713  for (int i = 1; i < n; i++) {
714  if (abc[i].abcA + abc[i].abcB + abc[i].abcC != 0) {
715  ml = qMin(ml,abc[i].abcA);
716  mr = qMin(mr,abc[i].abcC);
717  }
718  }
719  delete [] abc;
720  }
721  lbearing = ml;
722  rbearing = mr;
723  }
724 
725  return rbearing;
726 #else
727  if (rbearing == SHRT_MIN) {
728  int ml = 0;
729  int mr = 0;
730  HDC hdc = shared_dc();
731  SelectObject(hdc, hfont);
732  if (ttf) {
733  ABC *abc = 0;
734  int n = tm.tmLastChar - tm.tmFirstChar;
735  if (n <= max_font_count) {
736  abc = new ABC[n+1];
737  GetCharABCWidths(hdc, tm.tmFirstChar, tm.tmLastChar, abc);
738  } else {
739  abc = new ABC[char_table_entries+1];
740  for(int i = 0; i < char_table_entries; i++)
741  GetCharABCWidths(hdc, char_table[i], char_table[i], abc + i);
742  n = char_table_entries;
743  }
744  ml = abc[0].abcA;
745  mr = abc[0].abcC;
746  for (int i = 1; i < n; i++) {
747  if (abc[i].abcA + abc[i].abcB + abc[i].abcC != 0) {
748  ml = qMin(ml,abc[i].abcA);
749  mr = qMin(mr,abc[i].abcC);
750  }
751  }
752  delete [] abc;
753  } else {
754  ABCFLOAT *abc = 0;
755  int n = tm.tmLastChar - tm.tmFirstChar+1;
756  if (n <= max_font_count) {
757  abc = new ABCFLOAT[n];
758  GetCharABCWidthsFloat(hdc, tm.tmFirstChar, tm.tmLastChar, abc);
759  } else {
760  abc = new ABCFLOAT[char_table_entries];
761  for(int i = 0; i < char_table_entries; i++)
762  GetCharABCWidthsFloat(hdc, char_table[i], char_table[i], abc+i);
763  n = char_table_entries;
764  }
765  float fml = abc[0].abcfA;
766  float fmr = abc[0].abcfC;
767  for (int i=1; i<n; i++) {
768  if (abc[i].abcfA + abc[i].abcfB + abc[i].abcfC != 0) {
769  fml = qMin(fml,abc[i].abcfA);
770  fmr = qMin(fmr,abc[i].abcfC);
771  }
772  }
773  ml = int(fml - 0.9999);
774  mr = int(fmr - 0.9999);
775  delete [] abc;
776  }
777  lbearing = ml;
778  rbearing = mr;
779  }
780 
781  return rbearing;
782 #endif
783 }
784 
785 
786 const char *QFontEngineWin::name() const
787 {
788  return 0;
789 }
790 
791 bool QFontEngineWin::canRender(const QChar *string, int len)
792 {
793  if (symbol) {
794  for (int i = 0; i < len; ++i) {
795  unsigned int uc = getChar(string, i, len);
796  if (getTrueTypeGlyphIndex(cmap, uc) == 0) {
797  if (uc < 0x100) {
798  if (getTrueTypeGlyphIndex(cmap, uc + 0xf000) == 0)
799  return false;
800  } else {
801  return false;
802  }
803  }
804  }
805  } else if (ttf) {
806  for (int i = 0; i < len; ++i) {
807  unsigned int uc = getChar(string, i, len);
808  if (getTrueTypeGlyphIndex(cmap, uc) == 0)
809  return false;
810  }
811  } else {
812  while(len--) {
813  if (tm.tmFirstChar > string->unicode() || tm.tmLastChar < string->unicode())
814  return false;
815  }
816  }
817  return true;
818 }
819 
821 {
822  return QFontEngine::Win;
823 }
824 
825 static inline double qt_fixed_to_double(const FIXED &p) {
826  return ((p.value << 16) + p.fract) / 65536.0;
827 }
828 
829 static inline QPointF qt_to_qpointf(const POINTFX &pt, qreal scale) {
830  return QPointF(qt_fixed_to_double(pt.x) * scale, -qt_fixed_to_double(pt.y) * scale);
831 }
832 
833 #ifndef GGO_UNHINTED
834 #define GGO_UNHINTED 0x0100
835 #endif
836 
837 static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc,
838  QPainterPath *path, bool ttf, glyph_metrics_t *metric = 0, qreal scale = 1)
839 {
840 #if defined(Q_WS_WINCE)
841  Q_UNUSED(glyph);
842  Q_UNUSED(hdc);
843 #endif
844  MAT2 mat;
845  mat.eM11.value = mat.eM22.value = 1;
846  mat.eM11.fract = mat.eM22.fract = 0;
847  mat.eM21.value = mat.eM12.value = 0;
848  mat.eM21.fract = mat.eM12.fract = 0;
849  uint glyphFormat = GGO_NATIVE;
850 
851  if (ttf)
852  glyphFormat |= GGO_GLYPH_INDEX;
853 
854  GLYPHMETRICS gMetric;
855  memset(&gMetric, 0, sizeof(GLYPHMETRICS));
856  int bufferSize = GDI_ERROR;
857 #if !defined(Q_WS_WINCE)
858  bufferSize = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat);
859 #endif
860  if ((DWORD)bufferSize == GDI_ERROR) {
861  return false;
862  }
863 
864  void *dataBuffer = new char[bufferSize];
865  DWORD ret = GDI_ERROR;
866 #if !defined(Q_WS_WINCE)
867  ret = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, bufferSize, dataBuffer, &mat);
868 #endif
869  if (ret == GDI_ERROR) {
870  delete [](char *)dataBuffer;
871  return false;
872  }
873 
874  if(metric) {
875  // #### obey scale
876  *metric = glyph_metrics_t(gMetric.gmptGlyphOrigin.x, -gMetric.gmptGlyphOrigin.y,
877  (int)gMetric.gmBlackBoxX, (int)gMetric.gmBlackBoxY,
878  gMetric.gmCellIncX, gMetric.gmCellIncY);
879  }
880 
881  int offset = 0;
882  int headerOffset = 0;
883  TTPOLYGONHEADER *ttph = 0;
884 
885  QPointF oset = position.toPointF();
886  while (headerOffset < bufferSize) {
887  ttph = (TTPOLYGONHEADER*)((char *)dataBuffer + headerOffset);
888 
889  QPointF lastPoint(qt_to_qpointf(ttph->pfxStart, scale));
890  path->moveTo(lastPoint + oset);
891  offset += sizeof(TTPOLYGONHEADER);
892  TTPOLYCURVE *curve;
893  while (offset<int(headerOffset + ttph->cb)) {
894  curve = (TTPOLYCURVE*)((char*)(dataBuffer) + offset);
895  switch (curve->wType) {
896  case TT_PRIM_LINE: {
897  for (int i=0; i<curve->cpfx; ++i) {
898  QPointF p = qt_to_qpointf(curve->apfx[i], scale) + oset;
899  path->lineTo(p);
900  }
901  break;
902  }
903  case TT_PRIM_QSPLINE: {
904  const QPainterPath::Element &elm = path->elementAt(path->elementCount()-1);
905  QPointF prev(elm.x, elm.y);
906  QPointF endPoint;
907  for (int i=0; i<curve->cpfx - 1; ++i) {
908  QPointF p1 = qt_to_qpointf(curve->apfx[i], scale) + oset;
909  QPointF p2 = qt_to_qpointf(curve->apfx[i+1], scale) + oset;
910  if (i < curve->cpfx - 2) {
911  endPoint = QPointF((p1.x() + p2.x()) / 2, (p1.y() + p2.y()) / 2);
912  } else {
913  endPoint = p2;
914  }
915 
916  path->quadTo(p1, endPoint);
917  prev = endPoint;
918  }
919 
920  break;
921  }
922  case TT_PRIM_CSPLINE: {
923  for (int i=0; i<curve->cpfx; ) {
924  QPointF p2 = qt_to_qpointf(curve->apfx[i++], scale) + oset;
925  QPointF p3 = qt_to_qpointf(curve->apfx[i++], scale) + oset;
926  QPointF p4 = qt_to_qpointf(curve->apfx[i++], scale) + oset;
927  path->cubicTo(p2, p3, p4);
928  }
929  break;
930  }
931  default:
932  qWarning("QFontEngineWin::addOutlineToPath, unhandled switch case");
933  }
934  offset += sizeof(TTPOLYCURVE) + (curve->cpfx-1) * sizeof(POINTFX);
935  }
936  path->closeSubpath();
937  headerOffset += ttph->cb;
938  }
939  delete [] (char*)dataBuffer;
940 
941  return true;
942 }
943 
945  QPainterPath *path, QTextItem::RenderFlags)
946 {
947  LOGFONT lf = logfont;
948  // The sign must be negative here to make sure we match against character height instead of
949  // hinted cell height. This ensures that we get linear matching, and we need this for
950  // paths since we later on apply a scaling transform to the glyph outline to get the
951  // font at the correct pixel size.
952  lf.lfHeight = -unitsPerEm;
953  lf.lfWidth = 0;
954  HFONT hf = CreateFontIndirect(&lf);
955  HDC hdc = shared_dc();
956  HGDIOBJ oldfont = SelectObject(hdc, hf);
957 
958  for(int i = 0; i < nglyphs; ++i) {
959  if (!addGlyphToPath(glyphs[i], positions[i], hdc, path, ttf, /*metric*/0,
960  qreal(fontDef.pixelSize) / unitsPerEm)) {
961  // Some windows fonts, like "Modern", are vector stroke
962  // fonts, which are reported as TMPF_VECTOR but do not
963  // support GetGlyphOutline, and thus we set this bit so
964  // that addOutLineToPath can check it and return safely...
965  hasOutline = false;
966  break;
967  }
968  }
969  DeleteObject(SelectObject(hdc, oldfont));
970 }
971 
973  QPainterPath *path, QTextItem::RenderFlags flags)
974 {
975 #if !defined(Q_WS_WINCE)
976  if(tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) {
977  hasOutline = true;
978  QFontEngine::addOutlineToPath(x, y, glyphs, path, flags);
979  if (hasOutline) {
980  // has_outline is set to false if addGlyphToPath gets
981  // false from GetGlyphOutline, meaning its not an outline
982  // font.
983  return;
984  }
985  }
986 #endif
987  QFontEngine::addBitmapFontToPath(x, y, glyphs, path, flags);
988 }
989 
991 {
992  return _faceId;
993 }
994 
996 #include <qdebug.h>
998 
1000 {
1001  if(synthesized_flags == -1) {
1002  synthesized_flags = 0;
1003  if(ttf) {
1004  const DWORD HEAD = MAKE_TAG('h', 'e', 'a', 'd');
1005  HDC hdc = shared_dc();
1006  SelectObject(hdc, hfont);
1007  uchar data[4];
1008  GetFontData(hdc, HEAD, 44, &data, 4);
1009  USHORT macStyle = getUShort(data);
1010  if (tm.tmItalic && !(macStyle & 2))
1011  synthesized_flags = SynthesizedItalic;
1012  if (fontDef.stretch != 100 && ttf)
1013  synthesized_flags |= SynthesizedStretch;
1014  if (tm.tmWeight >= 500 && !(macStyle & 1))
1015  synthesized_flags |= SynthesizedBold;
1016  //qDebug() << "font is" << _name <<
1017  // "it=" << (macStyle & 2) << fontDef.style << "flags=" << synthesized_flags;
1018  }
1019  }
1020  return synthesized_flags;
1021 }
1022 
1024 {
1025  return unitsPerEm;
1026 }
1027 
1029 {
1030  LOGFONT lf = logfont;
1031  lf.lfHeight = unitsPerEm;
1032  HFONT hf = CreateFontIndirect(&lf);
1033  HDC hdc = shared_dc();
1034  HGDIOBJ oldfont = SelectObject(hdc, hf);
1035  OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc);
1036  Properties p;
1037  p.emSquare = unitsPerEm;
1038  p.italicAngle = otm->otmItalicAngle;
1039  p.postscriptName = QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpFamilyName)).toLatin1();
1040  p.postscriptName += QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpStyleName)).toLatin1();
1042  p.boundingBox = QRectF(otm->otmrcFontBox.left, -otm->otmrcFontBox.top,
1043  otm->otmrcFontBox.right - otm->otmrcFontBox.left,
1044  otm->otmrcFontBox.top - otm->otmrcFontBox.bottom);
1045  p.ascent = otm->otmAscent;
1046  p.descent = -otm->otmDescent;
1047  p.leading = (int)otm->otmLineGap;
1048  p.capHeight = 0;
1049  p.lineWidth = otm->otmsUnderscoreSize;
1050  free(otm);
1051  DeleteObject(SelectObject(hdc, oldfont));
1052  return p;
1053 }
1054 
1056 {
1057  LOGFONT lf = logfont;
1058  lf.lfHeight = unitsPerEm;
1059  int flags = synthesized();
1060  if(flags & SynthesizedItalic)
1061  lf.lfItalic = false;
1062  lf.lfWidth = 0;
1063  HFONT hf = CreateFontIndirect(&lf);
1064  HDC hdc = shared_dc();
1065  HGDIOBJ oldfont = SelectObject(hdc, hf);
1066  QFixedPoint p;
1067  p.x = 0;
1068  p.y = 0;
1069  addGlyphToPath(glyph, p, hdc, path, ttf, metrics);
1070  DeleteObject(SelectObject(hdc, oldfont));
1071 }
1072 
1073 bool QFontEngineWin::getSfntTableData(uint tag, uchar *buffer, uint *length) const
1074 {
1075  if (!ttf)
1076  return false;
1077  HDC hdc = shared_dc();
1078  SelectObject(hdc, hfont);
1079  DWORD t = qbswap<quint32>(tag);
1080  *length = GetFontData(hdc, t, 0, buffer, *length);
1081  return *length != GDI_ERROR;
1082 }
1083 
1084 #if !defined(CLEARTYPE_QUALITY)
1085 # define CLEARTYPE_QUALITY 5
1086 #endif
1087 
1088 extern bool qt_cleartype_enabled;
1089 
1090 QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin,
1091  const QTransform &t, QImage::Format mask_format)
1092 {
1093  Q_UNUSED(mask_format)
1094  glyph_metrics_t gm = boundingBox(glyph);
1095 
1096 // printf(" -> for glyph %4x\n", glyph);
1097 
1098  int gx = gm.x.toInt();
1099  int gy = gm.y.toInt();
1100  int iw = gm.width.toInt();
1101  int ih = gm.height.toInt();
1102 
1103  if (iw <= 0 || iw <= 0)
1104  return 0;
1105 
1106  bool has_transformation = t.type() > QTransform::TxTranslate;
1107 
1108 #ifndef Q_WS_WINCE
1109  unsigned int options = ttf ? ETO_GLYPH_INDEX : 0;
1110  XFORM xform;
1111 
1112  if (has_transformation) {
1113  xform.eM11 = t.m11();
1114  xform.eM12 = t.m12();
1115  xform.eM21 = t.m21();
1116  xform.eM22 = t.m22();
1117  xform.eDx = margin;
1118  xform.eDy = margin;
1119 
1120  QtHDC qthdc;
1121  HDC hdc = qthdc.hdc();
1122 
1123  SetGraphicsMode(hdc, GM_ADVANCED);
1124  SetWorldTransform(hdc, &xform);
1125  HGDIOBJ old_font = SelectObject(hdc, font);
1126 
1127  int ggo_options = GGO_METRICS | (ttf ? GGO_GLYPH_INDEX : 0);
1128  GLYPHMETRICS tgm;
1129  MAT2 mat;
1130  memset(&mat, 0, sizeof(mat));
1131  mat.eM11.value = mat.eM22.value = 1;
1132 
1133  if (GetGlyphOutline(hdc, glyph, ggo_options, &tgm, 0, 0, &mat) == GDI_ERROR) {
1134  qWarning("QWinFontEngine: unable to query transformed glyph metrics...");
1135  return 0;
1136  }
1137 
1138  iw = tgm.gmBlackBoxX;
1139  ih = tgm.gmBlackBoxY;
1140 
1141  xform.eDx -= tgm.gmptGlyphOrigin.x;
1142  xform.eDy += tgm.gmptGlyphOrigin.y;
1143 
1144  SetGraphicsMode(hdc, GM_COMPATIBLE);
1145  SelectObject(hdc, old_font);
1146  }
1147 #else // else winc
1148  unsigned int options = 0;
1149 #ifdef DEBUG
1150  Q_ASSERT(!has_transformation);
1151 #else
1152  Q_UNUSED(has_transformation);
1153 #endif
1154 #endif
1155 
1156  QNativeImage *ni = new QNativeImage(iw + 2 * margin + 4,
1157  ih + 2 * margin + 4,
1158  QNativeImage::systemFormat(), !qt_cleartype_enabled);
1159 
1160  /*If cleartype is enabled we use the standard system format even on Windows CE
1161  and not the special textbuffer format we have to use if cleartype is disabled*/
1162 
1163  ni->image.fill(0xffffffff);
1164 
1165  HDC hdc = ni->hdc;
1166 
1167  SelectObject(hdc, GetStockObject(NULL_BRUSH));
1168  SelectObject(hdc, GetStockObject(BLACK_PEN));
1169  SetTextColor(hdc, RGB(0,0,0));
1170  SetBkMode(hdc, TRANSPARENT);
1171  SetTextAlign(hdc, TA_BASELINE);
1172 
1173  HGDIOBJ old_font = SelectObject(hdc, font);
1174 
1175 #ifndef Q_OS_WINCE
1176  if (has_transformation) {
1177  SetGraphicsMode(hdc, GM_ADVANCED);
1178  SetWorldTransform(hdc, &xform);
1179  ExtTextOut(hdc, 0, 0, options, 0, (LPCWSTR) &glyph, 1, 0);
1180  } else
1181 #endif
1182  {
1183  ExtTextOut(hdc, -gx + margin, -gy + margin, options, 0, (LPCWSTR) &glyph, 1, 0);
1184  }
1185 
1186  SelectObject(hdc, old_font);
1187  return ni;
1188 }
1189 
1190 
1191 extern uint qt_pow_gamma[256];
1192 
1194 {
1195  HFONT font = hfont;
1196  if (qt_cleartype_enabled) {
1197  LOGFONT lf = logfont;
1198  lf.lfQuality = ANTIALIASED_QUALITY;
1199  font = CreateFontIndirect(&lf);
1200  }
1202 #ifndef Q_OS_WINCE
1203  mask_format = QImage::Format_RGB32;
1204 #endif
1205 
1206  QNativeImage *mask = drawGDIGlyph(font, glyph, 0, xform, mask_format);
1207  if (mask == 0)
1208  return QImage();
1209 
1210  QImage indexed(mask->width(), mask->height(), QImage::Format_Indexed8);
1211 
1212  // ### This part is kinda pointless, but we'll crash later if we don't because some
1213  // code paths expects there to be colortables for index8-bit...
1214  QVector<QRgb> colors(256);
1215  for (int i=0; i<256; ++i)
1216  colors[i] = qRgba(0, 0, 0, i);
1217  indexed.setColorTable(colors);
1218 
1219  // Copy data... Cannot use QPainter here as GDI has messed up the
1220  // Alpha channel of the ni.image pixels...
1221  for (int y=0; y<mask->height(); ++y) {
1222  uchar *dest = indexed.scanLine(y);
1223  if (mask->image.format() == QImage::Format_RGB16) {
1224  const qint16 *src = (qint16 *) ((const QImage &) mask->image).scanLine(y);
1225  for (int x=0; x<mask->width(); ++x)
1226  dest[x] = 255 - qGray(src[x]);
1227  } else {
1228  const uint *src = (uint *) ((const QImage &) mask->image).scanLine(y);
1229  for (int x=0; x<mask->width(); ++x) {
1230 #ifdef Q_OS_WINCE
1231  dest[x] = 255 - qGray(src[x]);
1232 #else
1234  dest[x] = 255 - qGray(src[x]);
1235  else
1236  dest[x] = 255 - (qt_pow_gamma[qGray(src[x])] * 255. / 2047.);
1237 #endif
1238  }
1239  }
1240  }
1241 
1242  // Cleanup...
1243  delete mask;
1244  if (qt_cleartype_enabled) {
1245  DeleteObject(font);
1246  }
1247 
1248  return indexed;
1249 }
1250 
1251 #define SPI_GETFONTSMOOTHINGCONTRAST 0x200C
1252 #define SPI_SETFONTSMOOTHINGCONTRAST 0x200D
1253 
1255 {
1256  HFONT font = hfont;
1257 
1258  int contrast;
1259  SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &contrast, 0);
1260  SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, (void *) 1000, 0);
1261 
1262  QNativeImage *mask = drawGDIGlyph(font, glyph, margin, t, QImage::Format_RGB32);
1263  SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, (void *) contrast, 0);
1264 
1265  if (mask == 0)
1266  return QImage();
1267 
1268  // Gracefully handle the odd case when the display is 16-bit
1269  const QImage source = mask->image.depth() == 32
1270  ? mask->image
1272 
1273  QImage rgbMask(mask->width(), mask->height(), QImage::Format_RGB32);
1274  for (int y=0; y<mask->height(); ++y) {
1275  uint *dest = (uint *) rgbMask.scanLine(y);
1276  const uint *src = (uint *) source.scanLine(y);
1277  for (int x=0; x<mask->width(); ++x) {
1278  dest[x] = 0xffffffff - (0x00ffffff & src[x]);
1279  }
1280  }
1281 
1282  delete mask;
1283 
1284  return rgbMask;
1285 }
1286 
1287 // From qfontdatabase_win.cpp
1288 extern QFontEngine *qt_load_font_engine_win(const QFontDef &request);
1290 {
1291  QFontDef request = fontDef;
1292  QString actualFontName = request.family;
1293  if (!uniqueFamilyName.isEmpty())
1294  request.family = uniqueFamilyName;
1295  request.pixelSize = pixelSize;
1296 
1297  QFontEngine *fontEngine = qt_load_font_engine_win(request);
1298  if (fontEngine != NULL)
1299  fontEngine->fontDef.family = actualFontName;
1300 
1301  return fontEngine;
1302 }
1303 
1304 // -------------------------------------- Multi font engine
1305 
1307  : QFontEngineMulti(fallbacks.size()+1),
1308  fallbacks(fallbacks)
1309 {
1310  engines[0] = first;
1311  first->ref.ref();
1312  fontDef = engines[0]->fontDef;
1313  cache_cost = first->cache_cost;
1314 }
1315 
1317 {
1318  Q_ASSERT(at < engines.size());
1319  Q_ASSERT(engines.at(at) == 0);
1320 
1321  QString fam = fallbacks.at(at-1);
1322 
1323  LOGFONT lf = static_cast<QFontEngineWin *>(engines.at(0))->logfont;
1324  memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded
1325  HFONT hfont = CreateFontIndirect(&lf);
1326 
1327  bool stockFont = false;
1328  if (hfont == 0) {
1329  hfont = (HFONT)GetStockObject(ANSI_VAR_FONT);
1330  stockFont = true;
1331  }
1332  engines[at] = new QFontEngineWin(fam, hfont, stockFont, lf);
1333  engines[at]->ref.ref();
1334  engines[at]->fontDef = fontDef;
1335 
1336  // TODO: increase cost in QFontCache for the font engine loaded here
1337 }
1338 
static QString fromWCharArray(const wchar_t *, int size=-1)
Returns a copy of the string, where the encoding of string depends on the size of wchar...
Definition: qstring.cpp:1019
QAtomicInt ref
virtual QFixed lineThickness() const
T * q_check_ptr(T *p)
Definition: qglobal.h:1857
The QPainterPath::Element class specifies the position and type of a subpath.
Definition: qpainterpath.h:77
virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing=0, qreal *rightBearing=0)
virtual qreal minRightBearing() const
Format
The following image formats are available in Qt.
Definition: qimage.h:91
static double qt_fixed_to_double(const FIXED &p)
static QPointF qt_to_qpointf(const POINTFX &pt, qreal scale)
QFixed * advances_y
double qreal
Definition: qglobal.h:1193
static const ushort char_table[]
QIntegerForSizeof< void * >::Unsigned quintptr
Definition: qglobal.h:986
virtual QFixed lineThickness() const
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QFixed * advances_x
virtual QFixed ascent() const
virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
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
bool canRender(const QChar *string, int len)
qreal m21() const
Returns the horizontal shearing factor.
Definition: qtransform.h:249
#define at(className, varName)
void fill(uint pixel)
Fills the entire image with the given pixelValue.
Definition: qimage.cpp:2032
virtual QImage alphaMapForGlyph(glyph_t t)
virtual void addOutlineToPath(qreal, qreal, const QGlyphLayout &, QPainterPath *, QTextItem::RenderFlags flags)
virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs, QPainterPath *path, QTextItem::RenderFlags flags)
#define ETO_GLYPH_INDEX
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
void closeSubpath()
Closes the current subpath by drawing a line to the beginning of the subpath, automatically starting ...
virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs)
static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
static const uchar * getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize)
qreal m22() const
Returns the vertical scaling factor.
Definition: qtransform.h:253
static QColor cmap[256]
Definition: qgl_mac.mm:760
#define QT_END_INCLUDE_NAMESPACE
This macro is equivalent to QT_BEGIN_NAMESPACE.
Definition: qglobal.h:92
virtual QFixed descent() const
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
static QImage::Format systemFormat()
static quint16 getUShort(unsigned char *p)
bool ref()
Atomically increments the value of this QAtomicInt.
virtual qreal minLeftBearing() const
qreal y
the y coordinate of the element&#39;s position.
Definition: qpainterpath.h:80
The QString class provides a Unicode character string.
Definition: qstring.h:83
static QFixed fromReal(qreal r)
Definition: qfixed_p.h:70
Q_DECL_CONSTEXPR T qAbs(const T &t)
Definition: qglobal.h:1201
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
TransformationType type() const
Returns the transformation type of this matrix.
#define ANSI_VAR_FONT
QFontEngineMultiWin(QFontEngine *first, const QStringList &fallbacks)
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
#define SIZE(large, small, mini)
void moveTo(const QPointF &p)
Moves the current point to the given point, implicitly starting a new subpath and closing the previou...
void * SCRIPT_CACHE
const QPainterPath::Element & elementAt(int i) const
Returns the element at the given index in the painter path.
Definition: qpainterpath.h:402
static HDC displayDC
Format format() const
Returns the format of the image.
Definition: qimage.cpp:2305
HGDIOBJ selectDesignFont() const
virtual QFixed xHeight() const
qreal x() const
Returns the x-coordinate of this point.
Definition: qpoint.h:282
static ushort highSurrogate(uint ucs4)
Returns the high surrogate value of a ucs4 code point.
Definition: qchar.h:303
virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing=0, qreal *rightBearing=0)
static ushort lowSurrogate(uint ucs4)
Returns the low surrogate value of a ucs4 code point.
Definition: qchar.h:306
void lineTo(const QPointF &p)
Adds a straight line from the current position to the given endPoint.
qreal m12() const
Returns the vertical shearing factor.
Definition: qtransform.h:241
HDC hdc() const
virtual void recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags) const
unsigned char uchar
Definition: qglobal.h:994
struct tagTTPOLYCURVE TTPOLYCURVE
#define MAKE_TAG(ch1, ch2, ch3, ch4)
#define SPI_SETFONTSMOOTHINGCONTRAST
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
glyph_metrics_t transformed(const QTransform &xform) const
Q_GUI_EXPORT_INLINE QRgb qRgba(int r, int g, int b, int a)
Definition: qrgb.h:72
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
virtual QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform)
QFixed y
Definition: qfixed_p.h:191
virtual QFixed leading() const
int width() const
static const int char_table_entries
static float pixelSize(const QFontDef &request, int dpi)
Definition: qfont_win.cpp:80
QNativeImage * drawGDIGlyph(HFONT font, glyph_t, int margin, const QTransform &xform, QImage::Format mask_format)
static const QCssKnownValue positions[NumKnownPositionModes - 1]
Definition: qcssparser.cpp:329
const char * name
#define GGO_NATIVE
#define Q_GLOBAL_STATIC(TYPE, NAME)
Declares a global static variable with the given type and name.
Definition: qglobal.h:1968
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
short qint16
Definition: qglobal.h:935
unsigned short quint16
Definition: qglobal.h:936
Q_CORE_EXPORT void qWarning(const char *,...)
int toInt() const
Definition: qfixed_p.h:76
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
virtual const char * name() const
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
int depth() const
Returns the depth of the image.
Definition: qimage.cpp:1620
virtual QFixed averageCharWidth() const
static quint32 getUInt(unsigned char *p)
Type type() const
void calculateTTFGlyphWidth(HDC hdc, UINT glyph, int &width)
uint qt_pow_gamma[256]
qreal pixelSize
Definition: qfont_p.h:90
HDC shared_dc()
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
virtual QFixed xHeight() const
QVector< QFontEngine * > engines
unsigned int getChar(const QChar *str, int &i, const int len)
QFontEngineWin(const QString &name, HFONT, bool, LOGFONT)
QFixed x
Definition: qfixed_p.h:190
Q_GUI_EXPORT_INLINE int qGray(int r, int g, int b)
Definition: qrgb.h:75
virtual void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
long HRESULT
HRESULT(WINAPI * fScriptFreeCache)(SCRIPT_CACHE *)
void * resolve(const char *symbol)
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
struct tagTTPOLYGONHEADER TTPOLYGONHEADER
fScriptFreeCache ScriptFreeCache
QPointF toPointF() const
Definition: qfixed_p.h:194
int height() const
#define SPI_GETFONTSMOOTHINGCONTRAST
virtual qreal maxCharWidth() const
unsigned short ushort
Definition: qglobal.h:995
static QByteArray convertToPostscriptFontFamilyName(const QByteArray &fontFamily)
#define TT_PRIM_CSPLINE
#define TT_PRIM_QSPLINE
#define TT_PRIM_LINE
unsigned int quint32
Definition: qglobal.h:938
static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc, QPainterPath *path, bool ttf, glyph_metrics_t *metric=0, qreal scale=1)
int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs, bool mirrored) const
virtual QFixed emSquareSize() const
virtual bool getSfntTableData(uint tag, uchar *buffer, uint *length) const
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
void quadTo(const QPointF &ctrlPt, const QPointF &endPt)
Adds a quadratic Bezier curve between the current position and the given endPoint with the control po...
qreal x
the x coordinate of the element&#39;s position.
Definition: qpainterpath.h:79
qreal y() const
Returns the y-coordinate of this point.
Definition: qpoint.h:287
void cubicTo(const QPointF &ctrlPt1, const QPointF &ctrlPt2, const QPointF &endPt)
Adds a cubic Bezier curve between the current position and the given endPoint using the control point...
#define QT_BEGIN_INCLUDE_NAMESPACE
This macro is equivalent to QT_END_NAMESPACE.
Definition: qglobal.h:91
QFixed effectiveAdvance(int item) const
virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics)
static OUTLINETEXTMETRIC * getOutlineTextMetric(HDC hdc)
int elementCount() const
Returns the number of path elements in the painter path.
Definition: qpainterpath.h:397
#define Q_WS_WINCE
Definition: qglobal.h:895
QFontEngine * qt_load_font_engine_win(const QFontDef &request)
quint32 qbswap< quint32 >(quint32 source)
Definition: qendian.h:302
QFontDef fontDef
virtual QFontEngine * cloneWithSize(qreal pixelSize) const
virtual Properties properties() const
QString family
Definition: qfont_p.h:82
virtual int synthesized() const
The QThreadStorage class provides per-thread data storage.
#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
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
#define GGO_GLYPH_INDEX
struct tagPOINTFX POINTFX
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
virtual FaceId faceId() const
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
Definition: qimage.cpp:1886
qreal m11() const
Returns the horizontal scaling factor.
Definition: qtransform.h:237
The QTransform class specifies 2D transformations of a coordinate system.
Definition: qtransform.h:65
bool qt_cleartype_enabled
void qErrnoWarning(const char *msg,...)
Definition: qglobal.cpp:2954