source: trunk/src/gui/text/qfontengine_mac.mm@ 5

Last change on this file since 5 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 60.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <private/qapplication_p.h>
43#include <private/qfontengine_p.h>
44#include <private/qpainter_p.h>
45#include <private/qtextengine_p.h>
46#include <qbitmap.h>
47#include <private/qpaintengine_mac_p.h>
48#include <private/qprintengine_mac_p.h>
49#include <private/qpdf_p.h>
50#include <qglobal.h>
51#include <qpixmap.h>
52#include <qpixmapcache.h>
53#include <qvarlengtharray.h>
54#include <qdebug.h>
55#include <qendian.h>
56
57#include <ApplicationServices/ApplicationServices.h>
58#include <AppKit/AppKit.h>
59
60QT_BEGIN_NAMESPACE
61
62/*****************************************************************************
63 QFontEngine debug facilities
64 *****************************************************************************/
65//#define DEBUG_ADVANCES
66
67extern int qt_antialiasing_threshold; // QApplication.cpp
68
69#ifndef FixedToQFixed
70#define FixedToQFixed(a) QFixed::fromFixed((a) >> 10)
71#define QFixedToFixed(x) ((x).value() << 10)
72#endif
73
74class QMacFontPath
75{
76 float x, y;
77 QPainterPath *path;
78public:
79 inline QMacFontPath(float _x, float _y, QPainterPath *_path) : x(_x), y(_y), path(_path) { }
80 inline void setPosition(float _x, float _y) { x = _x; y = _y; }
81 inline void advance(float _x) { x += _x; }
82 static OSStatus lineTo(const Float32Point *, void *);
83 static OSStatus cubicTo(const Float32Point *, const Float32Point *,
84 const Float32Point *, void *);
85 static OSStatus moveTo(const Float32Point *, void *);
86 static OSStatus closePath(void *);
87};
88
89OSStatus QMacFontPath::lineTo(const Float32Point *pt, void *data)
90
91{
92 QMacFontPath *p = static_cast<QMacFontPath*>(data);
93 p->path->lineTo(p->x + pt->x, p->y + pt->y);
94 return noErr;
95}
96
97OSStatus QMacFontPath::cubicTo(const Float32Point *cp1, const Float32Point *cp2,
98 const Float32Point *ep, void *data)
99
100{
101 QMacFontPath *p = static_cast<QMacFontPath*>(data);
102 p->path->cubicTo(p->x + cp1->x, p->y + cp1->y,
103 p->x + cp2->x, p->y + cp2->y,
104 p->x + ep->x, p->y + ep->y);
105 return noErr;
106}
107
108OSStatus QMacFontPath::moveTo(const Float32Point *pt, void *data)
109{
110 QMacFontPath *p = static_cast<QMacFontPath*>(data);
111 p->path->moveTo(p->x + pt->x, p->y + pt->y);
112 return noErr;
113}
114
115OSStatus QMacFontPath::closePath(void *data)
116{
117 static_cast<QMacFontPath*>(data)->path->closeSubpath();
118 return noErr;
119}
120
121
122#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
123QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool kerning)
124 : QFontEngineMulti(0)
125{
126 this->fontDef = fontDef;
127 CTFontSymbolicTraits symbolicTraits = 0;
128 if (fontDef.weight >= QFont::Bold)
129 symbolicTraits |= kCTFontBoldTrait;
130 switch (fontDef.style) {
131 case QFont::StyleNormal:
132 break;
133 case QFont::StyleItalic:
134 case QFont::StyleOblique:
135 symbolicTraits |= kCTFontItalicTrait;
136 break;
137 }
138
139 QCFString name;
140 ATSFontGetName(atsFontRef, kATSOptionFlagsDefault, &name);
141 QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pixelSize);
142 QCFType<CTFontRef> baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, 0);
143 ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, 0, symbolicTraits, symbolicTraits);
144
145 // CTFontCreateCopyWithSymbolicTraits returns NULL if we ask for a trait that does
146 // not exist for the given font. (for example italic)
147 if (ctfont == 0) {
148 ctfont = baseFont;
149 CFRetain(ctfont);
150 }
151
152 attributeDict = CFDictionaryCreateMutable(0, 2,
153 &kCFTypeDictionaryKeyCallBacks,
154 &kCFTypeDictionaryValueCallBacks);
155 CFDictionaryAddValue(attributeDict, NSFontAttributeName, ctfont);
156 if (!kerning) {
157 float zero = 0.0;
158 QCFType<CFNumberRef> noKern = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &zero);
159 CFDictionaryAddValue(attributeDict, kCTKernAttributeName, &noKern);
160 }
161
162 QCoreTextFontEngine *fe = new QCoreTextFontEngine(ctfont, fontDef, this);
163 fe->ref.ref();
164 engines.append(fe);
165
166}
167
168QCoreTextFontEngineMulti::~QCoreTextFontEngineMulti()
169{
170 CFRelease(ctfont);
171}
172
173uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef id) const
174{
175 for (int i = 0; i < engines.count(); ++i) {
176 if (CFEqual(engineAt(i)->ctfont, id))
177 return i;
178 }
179
180 QCoreTextFontEngineMulti *that = const_cast<QCoreTextFontEngineMulti *>(this);
181 QCoreTextFontEngine *fe = new QCoreTextFontEngine(id, fontDef, that);
182 fe->ref.ref();
183 that->engines.append(fe);
184 return engines.count() - 1;
185}
186
187bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags,
188 unsigned short *logClusters, const HB_CharAttributes *) const
189{
190 QCFType<CFStringRef> cfstring = CFStringCreateWithCharactersNoCopy(0,
191 reinterpret_cast<const UniChar *>(str),
192 len, kCFAllocatorNull);
193 QCFType<CFAttributedStringRef> attributedString = CFAttributedStringCreate(0, cfstring, attributeDict);
194 QCFType<CTTypesetterRef> typeSetter = CTTypesetterCreateWithAttributedString(attributedString);
195 CFRange range = {0, 0};
196 QCFType<CTLineRef> line = CTTypesetterCreateLine(typeSetter, range);
197 CFArrayRef array = CTLineGetGlyphRuns(line);
198 uint arraySize = CFArrayGetCount(array);
199 glyph_t *outGlyphs = glyphs->glyphs;
200 HB_GlyphAttributes *outAttributes = glyphs->attributes;
201 QFixed *outAdvances_x = glyphs->advances_x;
202 QFixed *outAdvances_y = glyphs->advances_y;
203 glyph_t *initialGlyph = outGlyphs;
204
205 if (arraySize == 0)
206 return false;
207
208 const bool rtl = (CTRunGetStatus(static_cast<CTRunRef>(CFArrayGetValueAtIndex(array, 0))) & kCTRunStatusRightToLeft);
209
210 bool outOBounds = false;
211 for (uint i = 0; i < arraySize; ++i) {
212 CTRunRef run = static_cast<CTRunRef>(CFArrayGetValueAtIndex(array, rtl ? (arraySize - 1 - i) : i));
213 CFIndex glyphCount = CTRunGetGlyphCount(run);
214 if (glyphCount == 0)
215 continue;
216
217 Q_ASSERT((CTRunGetStatus(run) & kCTRunStatusRightToLeft) == rtl);
218
219 if (!outOBounds && outGlyphs + glyphCount - initialGlyph > *nglyphs) {
220 outOBounds = true;
221 }
222 if (!outOBounds) {
223 CFDictionaryRef runAttribs = CTRunGetAttributes(run);
224 //NSLog(@"Dictionary %@", runAttribs);
225 if (!runAttribs)
226 runAttribs = attributeDict;
227 CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(runAttribs, NSFontAttributeName));
228 const uint fontIndex = (fontIndexForFont(runFont) << 24);
229 //NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont));
230 QVarLengthArray<CGGlyph, 512> cgglyphs(0);
231 const CGGlyph *tmpGlyphs = CTRunGetGlyphsPtr(run);
232 if (!tmpGlyphs) {
233 cgglyphs.resize(glyphCount);
234 CTRunGetGlyphs(run, range, cgglyphs.data());
235 tmpGlyphs = cgglyphs.constData();
236 }
237 QVarLengthArray<CGPoint, 512> cgpoints(0);
238 const CGPoint *tmpPoints = CTRunGetPositionsPtr(run);
239 if (!tmpPoints) {
240 cgpoints.resize(glyphCount);
241 CTRunGetPositions(run, range, cgpoints.data());
242 tmpPoints = cgpoints.constData();
243 }
244
245 const int rtlOffset = rtl ? (glyphCount - 1) : 0;
246 const int rtlSign = rtl ? -1 : 1;
247
248 if (logClusters) {
249 CFRange stringRange = CTRunGetStringRange(run);
250 QVarLengthArray<CFIndex, 512> stringIndices(0);
251 const CFIndex *tmpIndices = CTRunGetStringIndicesPtr(run);
252 if (!tmpIndices) {
253 stringIndices.resize(glyphCount);
254 CTRunGetStringIndices(run, range, stringIndices.data());
255 tmpIndices = stringIndices.constData();
256 }
257
258 const int firstGlyphIndex = outGlyphs - initialGlyph;
259 outAttributes[0].clusterStart = true;
260
261 CFIndex k = 0;
262 CFIndex i = 0;
263 for (i = stringRange.location;
264 (i < stringRange.location + stringRange.length) && (k < glyphCount); ++i) {
265 if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location) {
266 logClusters[i] = k + firstGlyphIndex;
267 outAttributes[k].clusterStart = true;
268 ++k;
269 } else {
270 logClusters[i] = k + firstGlyphIndex - 1;
271 }
272 }
273 // in case of a ligature at the end, fill the remaining logcluster entries
274 for (;i < stringRange.location + stringRange.length; i++) {
275 logClusters[i] = k + firstGlyphIndex - 1;
276 }
277 }
278 for (CFIndex i = 0; i < glyphCount - 1; ++i) {
279 int idx = rtlOffset + rtlSign * i;
280 outGlyphs[idx] = tmpGlyphs[i] | fontIndex;
281 outAdvances_x[idx] = QFixed::fromReal(tmpPoints[i + 1].x - tmpPoints[i].x);
282 outAdvances_y[idx] = QFixed::fromReal(tmpPoints[i + 1].y - tmpPoints[i].y);
283 }
284 CGSize lastGlyphAdvance;
285 CTFontGetAdvancesForGlyphs(runFont, kCTFontHorizontalOrientation, tmpGlyphs + glyphCount - 1, &lastGlyphAdvance, 1);
286
287 outGlyphs[rtl ? 0 : (glyphCount - 1)] = tmpGlyphs[glyphCount - 1] | fontIndex;
288 outAdvances_x[rtl ? 0 : (glyphCount - 1)] = QFixed::fromReal(lastGlyphAdvance.width).ceil();
289 }
290 outGlyphs += glyphCount;
291 outAttributes += glyphCount;
292 outAdvances_x += glyphCount;
293 outAdvances_y += glyphCount;
294 }
295 *nglyphs = (outGlyphs - initialGlyph);
296 return !outOBounds;
297}
298
299bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
300 int *nglyphs, QTextEngine::ShaperFlags flags) const
301{
302 return stringToCMap(str, len, glyphs, nglyphs, flags, 0, 0);
303}
304
305void QCoreTextFontEngineMulti::recalcAdvances(int , QGlyphLayout *, QTextEngine::ShaperFlags) const
306{
307}
308void QCoreTextFontEngineMulti::doKerning(int , QGlyphLayout *, QTextEngine::ShaperFlags) const
309{
310}
311
312void QCoreTextFontEngineMulti::loadEngine(int)
313{
314 // Do nothing
315 Q_ASSERT(false);
316}
317
318
319
320QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def,
321 QCoreTextFontEngineMulti *multiEngine)
322{
323 fontDef = def;
324 parentEngine = multiEngine;
325 synthesisFlags = 0;
326 ctfont = font;
327 CFRetain(ctfont);
328 ATSFontRef atsfont = CTFontGetPlatformFont(ctfont, 0);
329 cgFont = CGFontCreateWithPlatformFont(&atsfont);
330 CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctfont);
331 if (fontDef.weight >= QFont::Bold && !(traits & kCTFontBoldTrait)) {
332 synthesisFlags |= SynthesizedBold;
333 }
334
335 if (fontDef.style != QFont::StyleNormal && !(traits & kCTFontItalicTrait)) {
336 synthesisFlags |= SynthesizedItalic;
337 }
338
339 QByteArray os2Table = getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
340 if (os2Table.size() >= 10)
341 fsType = qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(os2Table.constData() + 8));
342}
343
344QCoreTextFontEngine::~QCoreTextFontEngine()
345{
346 CFRelease(ctfont);
347 CFRelease(cgFont);
348}
349
350bool QCoreTextFontEngine::stringToCMap(const QChar *, int, QGlyphLayout *, int *, QTextEngine::ShaperFlags) const
351{
352 return false;
353}
354
355glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs)
356{
357 QFixed w;
358 for (int i = 0; i < glyphs.numGlyphs; ++i)
359 w += glyphs.effectiveAdvance(i);
360 return glyph_metrics_t(0, -(ascent()), w, ascent()+descent(), w, 0);
361}
362glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph)
363{
364 glyph_metrics_t ret;
365 CGGlyph g = glyph;
366 CGRect rect = CTFontGetBoundingRectsForGlyphs(ctfont, kCTFontHorizontalOrientation, &g, 0, 1);
367 ret.width = QFixed::fromReal(rect.size.width);
368 ret.height = QFixed::fromReal(rect.size.height);
369 ret.x = QFixed::fromReal(rect.origin.x);
370 ret.y = -QFixed::fromReal(rect.origin.y) - ret.height;
371 CGSize advances[1];
372 CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, &g, advances, 1);
373 ret.xoff = QFixed::fromReal(advances[0].width).ceil();
374 ret.yoff = QFixed::fromReal(advances[0].height).ceil();
375 return ret;
376}
377
378QFixed QCoreTextFontEngine::ascent() const
379{
380 return QFixed::fromReal(CTFontGetAscent(ctfont)).ceil();
381}
382QFixed QCoreTextFontEngine::descent() const
383{
384 return QFixed::fromReal(CTFontGetDescent(ctfont)).ceil();
385}
386QFixed QCoreTextFontEngine::leading() const
387{
388 return QFixed::fromReal(CTFontGetLeading(ctfont)).ceil();
389}
390QFixed QCoreTextFontEngine::xHeight() const
391{
392 return QFixed::fromReal(CTFontGetXHeight(ctfont)).ceil();
393}
394QFixed QCoreTextFontEngine::averageCharWidth() const
395{
396 // ### Need to implement properly and get the information from the OS/2 Table.
397 return QFontEngine::averageCharWidth();
398}
399
400qreal QCoreTextFontEngine::maxCharWidth() const
401{
402 // ### Max Help!
403 return 0;
404
405}
406qreal QCoreTextFontEngine::minLeftBearing() const
407{
408 // ### Min Help!
409 return 0;
410
411}
412qreal QCoreTextFontEngine::minRightBearing() const
413{
414 // ### Max Help! (even thought it's right)
415 return 0;
416
417}
418
419void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight)
420{
421 QVarLengthArray<QFixedPoint> positions;
422 QVarLengthArray<glyph_t> glyphs;
423 QTransform matrix;
424 matrix.translate(x, y);
425 getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
426 if (glyphs.size() == 0)
427 return;
428
429 CGContextSetFontSize(ctx, fontDef.pixelSize);
430
431 CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx);
432
433 CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, -1, 0, -paintDeviceHeight);
434
435 CGAffineTransformConcat(cgMatrix, oldTextMatrix);
436
437 if (synthesisFlags & QFontEngine::SynthesizedItalic)
438 cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0));
439
440// ### cgMatrix = CGAffineTransformConcat(cgMatrix, transform);
441
442 CGContextSetTextMatrix(ctx, cgMatrix);
443
444 CGContextSetTextDrawingMode(ctx, kCGTextFill);
445
446
447 QVarLengthArray<CGSize> advances(glyphs.size());
448 QVarLengthArray<CGGlyph> cgGlyphs(glyphs.size());
449
450 for (int i = 0; i < glyphs.size() - 1; ++i) {
451 advances[i].width = (positions[i + 1].x - positions[i].x).toReal();
452 advances[i].height = (positions[i + 1].y - positions[i].y).toReal();
453 cgGlyphs[i] = glyphs[i];
454 }
455 advances[glyphs.size() - 1].width = 0;
456 advances[glyphs.size() - 1].height = 0;
457 cgGlyphs[glyphs.size() - 1] = glyphs[glyphs.size() - 1];
458
459 CGContextSetFont(ctx, cgFont);
460 //NSLog(@"Font inDraw %@ ctfont %@", CGFontCopyFullName(cgFont), CTFontCopyFamilyName(ctfont));
461
462 CGContextSetTextPosition(ctx, positions[0].x.toReal(), positions[0].y.toReal());
463
464 CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size());
465
466 if (synthesisFlags & QFontEngine::SynthesizedBold) {
467 CGContextSetTextPosition(ctx, positions[0].x.toReal() + 0.5 * lineThickness().toReal(),
468 positions[0].y.toReal());
469
470 CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size());
471 }
472
473 CGContextSetTextMatrix(ctx, oldTextMatrix);
474}
475
476struct ConvertPathInfo
477{
478 ConvertPathInfo(QPainterPath *newPath, const QPointF &newPos) : path(newPath), pos(newPos) {}
479 QPainterPath *path;
480 QPointF pos;
481};
482
483static void convertCGPathToQPainterPath(void *info, const CGPathElement *element)
484{
485 ConvertPathInfo *myInfo = static_cast<ConvertPathInfo *>(info);
486 switch(element->type) {
487 case kCGPathElementMoveToPoint:
488 myInfo->path->moveTo(element->points[0].x + myInfo->pos.x(),
489 element->points[0].y + myInfo->pos.y());
490 break;
491 case kCGPathElementAddLineToPoint:
492 myInfo->path->lineTo(element->points[0].x + myInfo->pos.x(),
493 element->points[0].y + myInfo->pos.y());
494 break;
495 case kCGPathElementAddQuadCurveToPoint:
496 myInfo->path->quadTo(element->points[0].x + myInfo->pos.x(),
497 element->points[0].y + myInfo->pos.y(),
498 element->points[1].x + myInfo->pos.x(),
499 element->points[1].y + myInfo->pos.y());
500 break;
501 case kCGPathElementAddCurveToPoint:
502 myInfo->path->cubicTo(element->points[0].x + myInfo->pos.x(),
503 element->points[0].y + myInfo->pos.y(),
504 element->points[1].x + myInfo->pos.x(),
505 element->points[1].y + myInfo->pos.y(),
506 element->points[2].x + myInfo->pos.x(),
507 element->points[2].y + myInfo->pos.y());
508 break;
509 case kCGPathElementCloseSubpath:
510 myInfo->path->closeSubpath();
511 break;
512 default:
513 qDebug() << "Unhandled path transform type: " << element->type;
514 }
515
516}
517
518void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nGlyphs,
519 QPainterPath *path, QTextItem::RenderFlags)
520{
521
522 CGAffineTransform cgMatrix = CGAffineTransformIdentity;
523 cgMatrix = CGAffineTransformScale(cgMatrix, 1, -1);
524
525 if (synthesisFlags & QFontEngine::SynthesizedItalic)
526 cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, tanf(14 * acosf(0) / 90), 1, 0, 0));
527
528
529 for (int i = 0; i < nGlyphs; ++i) {
530 QCFType<CGPathRef> cgpath = CTFontCreatePathForGlyph(ctfont, glyphs[i], &cgMatrix);
531 ConvertPathInfo info(path, positions[i].toPointF());
532 CGPathApply(cgpath, &info, convertCGPathToQPainterPath);
533 }
534}
535
536QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph)
537{
538 const glyph_metrics_t br = boundingBox(glyph);
539 QImage im(qRound(br.width)+2, qRound(br.height)+2, QImage::Format_RGB32);
540 im.fill(0);
541
542 CGColorSpaceRef colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace();
543#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
544 uint cgflags = kCGImageAlphaNoneSkipFirst;
545#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
546 if(QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4)
547 cgflags |= kCGBitmapByteOrder32Host;
548#endif
549#else
550 CGImageAlphaInfo cgflags = kCGImageAlphaNoneSkipFirst;
551#endif
552 CGContextRef ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(),
553 8, im.bytesPerLine(), colorspace,
554 cgflags);
555 CGContextSetFontSize(ctx, fontDef.pixelSize);
556 CGContextSetShouldAntialias(ctx, fontDef.pointSize > qt_antialiasing_threshold && !(fontDef.styleStrategy & QFont::NoAntialias));
557 CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx);
558 CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0);
559
560 CGAffineTransformConcat(cgMatrix, oldTextMatrix);
561