1
/****************************************************************************
2
**
3
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
6
**
7
** This file is part of the QtGui module of the Qt Toolkit.
8
**
9
** $QT_BEGIN_LICENSE:LGPL$
10
** GNU Lesser General Public License Usage
11
** This file may be used under the terms of the GNU Lesser General Public
12
** License version 2.1 as published by the Free Software Foundation and
13
** appearing in the file LICENSE.LGPL included in the packaging of this
14
** file. Please review the following information to ensure the GNU Lesser
15
** General Public License version 2.1 requirements will be met:
16
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17
**
18
** In addition, as a special exception, Nokia gives you certain additional
19
** rights. These rights are described in the Nokia Qt LGPL Exception
20
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21
**
22
** GNU General Public License Usage
23
** Alternatively, this file may be used under the terms of the GNU General
24
** Public License version 3.0 as published by the Free Software Foundation
25
** and appearing in the file LICENSE.GPL included in the packaging of this
26
** file. Please review the following information to ensure the GNU General
27
** Public License version 3.0 requirements will be met:
28
** http://www.gnu.org/copyleft/gpl.html.
29
**
30
** Other Usage
31
** Alternatively, this file may be used in accordance with the terms and
32
** conditions contained in a signed written agreement between you and Nokia.
33
**
34
**
35
**
36
**
37
**
38
** $QT_END_LICENSE$
39
**
40
****************************************************************************/
41
42
#include "qglobal.h"
43
44
#if !defined(QT_NO_RAWFONT)
45
46
#include "qrawfont.h"
47
#include "qrawfont_p.h"
48
49
#include <QtCore/qendian.h>
50
51
QT_BEGIN_NAMESPACE
52
53
/*!
54
   \class QRawFont
55
   \brief The QRawFont class provides access to a single physical instance of a font.
56
   \since 4.8
57
58
   \ingroup text
59
   \mainclass
60
61
   \note QRawFont is a low level class. For most purposes QFont is a more appropriate class.
62
63
   Most commonly, when presenting text in a user interface, the exact fonts used
64
   to render the characters is to some extent unknown. This can be the case for several
65
   reasons: For instance, the actual, physical fonts present on the target system could be
66
   unexpected to the developers, or the text could contain user selected styles, sizes or
67
   writing systems that are not supported by font chosen in the code.
68
69
   Therefore, Qt's QFont class really represents a query for fonts. When text is interpreted,
70
   Qt will do its best to match the text to the query, but depending on the support, different
71
   fonts can be used behind the scenes.
72
73
   For most use cases, this is both expected and necessary, as it minimizes the possibility of
74
   text in the user interface being undisplayable. In some cases, however, more direct control
75
   over the process might be useful. It is for these use cases the QRawFont class exists.
76
77
   A QRawFont object represents a single, physical instance of a given font in a given pixel size.
78
   I.e. in the typical case it represents a set of TrueType or OpenType font tables and uses a
79
   user specified pixel size to convert metrics into logical pixel units. It can be used in
80
   combination with the QGlyphRun class to draw specific glyph indexes at specific positions, and
81
   also have accessors to some relevant data in the physical font.
82
83
   QRawFont only provides support for the main font technologies: GDI and DirectWrite on Windows
84
   platforms, FreeType on Symbian and Linux platforms and CoreText on Mac OS X. For other
85
   font back-ends, the APIs will be disabled.
86
87
   QRawFont can be constructed in a number of ways:
88
   \list
89
   \o It can be constructed by calling QTextLayout::glyphs() or QTextFragment::glyphs(). The
90
      returned QGlyphs objects will contain QRawFont objects which represent the actual fonts
91
      used to render each portion of the text.
92
   \o It can be constructed by passing a QFont object to QRawFont::fromFont(). The function
93
      will return a QRawFont object representing the font that will be selected as response to
94
      the QFont query and the selected writing system.
95
   \o It can be constructed by passing a file name or QByteArray directly to the QRawFont
96
      constructor, or by calling loadFromFile() or loadFromData(). In this case, the
97
      font will not be registered in QFontDatabase, and it will not be available as part of
98
      regular font selection.
99
   \endlist
100
101
   QRawFont is considered local to the thread in which it is constructed (either using a
102
   constructor, or by calling loadFromData() or loadFromFile()). The QRawFont cannot be moved to a
103
   different thread, but will have to be recreated in the thread in question.
104
105
   \note For the requirement of caching glyph indexes and font selections for static text to avoid
106
   reshaping and relayouting in the inner loop of an application, a better choice is the QStaticText
107
   class, since it optimizes the memory cost of the cache and also provides the possibility of paint
108
   engine specific caches for an additional speed-up.
109
*/
110
111
/*!
112
    \enum QRawFont::AntialiasingType
113
114
    This enum represents the different ways a glyph can be rasterized in the function
115
    alphaMapForGlyph().
116
117
    \value PixelAntialiasing Will rasterize by measuring the coverage of the shape on whole pixels.
118
           The returned image contains the alpha values of each pixel based on the coverage of
119
           the glyph shape.
120
    \value SubPixelAntialiasing Will rasterize by measuring the coverage of each subpixel,
121
           returning a separate alpha value for each of the red, green and blue components of
122
           each pixel.
123
*/
124
125
/*!
126
   Constructs an invalid QRawFont.
127
*/
128
QRawFont::QRawFont()
129
    : d(new QRawFontPrivate)
130
{
131
}
132
133
/*!
134
   Constructs a QRawFont representing the font contained in the file referenced
135
   by \a fileName for the size (in pixels) given by \a pixelSize, and using the
136
   hinting preference specified by \a hintingPreference.
137
138
   \note The referenced file must contain a TrueType or OpenType font.
139
*/
140
QRawFont::QRawFont(const QString &fileName,
141
                   qreal pixelSize,
142
                   QFont::HintingPreference hintingPreference)
143
    : d(new QRawFontPrivate)
144
{
145
    loadFromFile(fileName, pixelSize, hintingPreference);
146
}
147
148
/*!
149
   Constructs a QRawFont representing the font contained in the supplied
150
   \a fontData for the size (in pixels) given by \a pixelSize, and using the
151
   hinting preference specified by \a hintingPreference.
152
153
   \note The data must contain a TrueType or OpenType font.
154
*/
155
QRawFont::QRawFont(const QByteArray &fontData,
156
                   qreal pixelSize,
157
                   QFont::HintingPreference hintingPreference)
158
    : d(new QRawFontPrivate)
159
{
160
    loadFromData(fontData, pixelSize, hintingPreference);
161
}
162
163
/*!
164
   Creates a QRawFont which is a copy of \a other.
165
*/
166
QRawFont::QRawFont(const QRawFont &other)
167
{
168
    d = other.d;
169
}
170
171
/*!
172
   Destroys the QRawFont
173
*/
174
QRawFont::~QRawFont()
175
{
176
}
177
178
/*!
179
  Assigns \a other to this QRawFont.
180
*/
181
QRawFont &QRawFont::operator=(const QRawFont &other)
182
{
183
    d = other.d;
184
    return *this;
185
}
186
187
/*!
188
   Returns true if the QRawFont is valid and false otherwise.
189
*/
190
bool QRawFont::isValid() const
191
{
192
    return d->isValid();
193
}
194
195
/*!
196
   Replaces the current QRawFont with the contents of the file referenced
197
   by \a fileName for the size (in pixels) given by \a pixelSize, and using the
198
   hinting preference specified by \a hintingPreference.
199
200
   The file must reference a TrueType or OpenType font.
201
202
   \sa loadFromData()
203
*/
204
void QRawFont::loadFromFile(const QString &fileName,
205
                            qreal pixelSize,
206
                            QFont::HintingPreference hintingPreference)
207
{
208
    QFile file(fileName);
209
    if (file.open(QIODevice::ReadOnly))
210
        loadFromData(file.readAll(), pixelSize, hintingPreference);
211
}
212
213
/*!
214
   Replaces the current QRawFont with the font contained in the supplied
215
   \a fontData for the size (in pixels) given by \a pixelSize, and using the
216
   hinting preference specified by \a hintingPreference.
217
218
   The \a fontData must contain a TrueType or OpenType font.
219
220
   \sa loadFromFile()
221
*/
222
void QRawFont::loadFromData(const QByteArray &fontData,
223
                            qreal pixelSize,
224
                            QFont::HintingPreference hintingPreference)
225
{
226
    d.detach();
227
    d->cleanUp();
228
    d->hintingPreference = hintingPreference;
229
    d->thread = QThread::currentThread();
230
    d->platformLoadFromData(fontData, pixelSize, hintingPreference);
231
}
232
233
/*!
234
   This function returns a rasterized image of the glyph at the given
235
   \a glyphIndex in the underlying font, using the \a transform specified.
236
   If the QRawFont is not valid, this function will return an invalid QImage.
237
238
   If \a antialiasingType is set to QRawFont::SubPixelAntialiasing, then the resulting image will be
239
   in QImage::Format_RGB32 and the RGB values of each pixel will represent the subpixel opacities of
240
   the pixel in the rasterization of the glyph. Otherwise, the image will be in the format of
241
   QImage::Format_Indexed8 and each pixel will contain the opacity of the pixel in the
242
   rasterization.
243
244
   \sa pathForGlyph(), QPainter::drawGlyphRun()
245
*/
246
QImage QRawFont::alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialiasingType,
247
                                  const QTransform &transform) const
248
{
249
    if (!d->isValid())
250
        return QImage();
251
252
    if (antialiasingType == SubPixelAntialiasing)
253
        return d->fontEngine->alphaRGBMapForGlyph(glyphIndex, QFixed(), 0, transform);
254
255
    return d->fontEngine->alphaMapForGlyph(glyphIndex, QFixed(), transform);
256
}
257
258
/*!
259
   This function returns the shape of the glyph at a given \a glyphIndex in the underlying font
260
   if the QRawFont is valid. Otherwise, it returns an empty QPainterPath.
261
262
   The returned glyph will always be unhinted.
263
264
   \sa alphaMapForGlyph(), QPainterPath::addText()
265
*/
266
QPainterPath QRawFont::pathForGlyph(quint32 glyphIndex) const
267
{
268
    if (!d->isValid())
269
        return QPainterPath();
270
271
    QFixedPoint position;
272
    QPainterPath path;
273
    d->fontEngine->addGlyphsToPath(&glyphIndex, &position, 1, &path, 0);
274
    return path;
275
}
276
277
/*!
278
   Returns true if this QRawFont is equal to \a other. Otherwise, returns false.
279
*/
280
bool QRawFont::operator==(const QRawFont &other) const
281
{
282
    return d->fontEngine == other.d->fontEngine;
283
}
284
285
/*!
286
    \fn bool QRawFont::operator!=(const QRawFont &other) const
287
288
    Returns true if this QRawFont is not equal to \a other. Otherwise, returns false.
289
*/
290
291
/*!
292
   Returns the ascent of this QRawFont in pixel units.
293
294
   \sa QFontMetricsF::ascent()
295
*/
296
qreal QRawFont::ascent() const
297
{
298
    return d->isValid() ? d->fontEngine->ascent().toReal() : 0.0;
299
}
300
301
/*!
302
   Returns the descent of this QRawFont in pixel units.
303
304
   \sa QFontMetricsF::descent()
305
*/
306
qreal QRawFont::descent() const
307
{
308
    return d->isValid() ? d->fontEngine->descent().toReal() : 0.0;
309
}
310
311
/*!
312
   Returns the xHeight of this QRawFont in pixel units.
313
314
   \sa QFontMetricsF::xHeight()
315
*/
316
qreal QRawFont::xHeight() const
317
{
318
    return d->isValid() ? d->fontEngine->xHeight().toReal() : 0.0;
319
}
320
321
/*!
322
   Returns the leading of this QRawFont in pixel units.
323
324
   \sa QFontMetricsF::leading()
325
*/
326
qreal QRawFont::leading() const
327
{
328
    return d->isValid() ? d->fontEngine->leading().toReal() : 0.0;
329
}
330
331
/*!
332
   Returns the average character width of this QRawFont in pixel units.
333
334
   \sa QFontMetricsF::averageCharWidth()
335
*/
336
qreal QRawFont::averageCharWidth() const
337
{
338
    return d->isValid() ? d->fontEngine->averageCharWidth().toReal() : 0.0;
339
}
340
341
/*!
342
   Returns the width of the widest character in the font.
343
344
   \sa QFontMetricsF::maxWidth()
345
*/
346
qreal QRawFont::maxCharWidth() const
347
{
348
    return d->isValid() ? d->fontEngine->maxCharWidth() : 0.0;
349
}
350
351
/*!
352
   Returns the pixel size set for this QRawFont. The pixel size affects how glyphs are
353
   rasterized, the size of glyphs returned by pathForGlyph(), and is used to convert
354
   internal metrics from design units to logical pixel units.
355
356
   \sa setPixelSize()
357
*/
358
qreal QRawFont::pixelSize() const
359
{
360
    return d->isValid() ? d->fontEngine->fontDef.pixelSize : 0.0;
361
}
362
363
/*!
364
   Returns the number of design units define the width and height of the em square
365
   for this QRawFont. This value is used together with the pixel size when converting design metrics
366
   to pixel units, as the internal metrics are specified in design units and the pixel size gives
367
   the size of 1 em in pixels.
368
369
   \sa pixelSize(), setPixelSize()
370
*/
371
qreal QRawFont::unitsPerEm() const
372
{
373
    return d->isValid() ? d->fontEngine->emSquareSize().toReal() : 0.0;
374
}
375
376
/*!
377
   Returns the family name of this QRawFont.
378
*/
379
QString QRawFont::familyName() const
380
{
381
    return d->isValid() ? d->fontEngine->fontDef.family : QString();
382
}
383
384
/*!
385
   Returns the style name of this QRawFont.
386
387
   \sa QFont::styleName()
388
*/
389
QString QRawFont::styleName() const
390
{
391
    return d->isValid() ? d->fontEngine->fontDef.styleName : QString();
392
}
393
394
/*!
395
   Returns the style of this QRawFont.
396
397
   \sa QFont::style()
398
*/
399
QFont::Style QRawFont::style() const
400
{
401
    return d->isValid() ? QFont::Style(d->fontEngine->fontDef.style) : QFont::StyleNormal;
402
}
403
404
/*!
405
   Returns the weight of this QRawFont.
406
407
   \sa QFont::weight()
408
*/
409
int QRawFont::weight() const
410
{
411
    return d->isValid() ? int(d->fontEngine->fontDef.weight) : -1;
412
}
413
414
/*!
415
   Converts the string of unicode points given by \a text to glyph indexes
416
   using the CMAP table in the underlying font, and returns a vector containing
417
   the result.
418
419
   Note that, in cases where there are other tables in the font that affect the
420
   shaping of the text, the returned glyph indexes will not correctly represent
421
   the rendering of the text. To get the correctly shaped text, you can use
422
   QTextLayout to lay out and shape the text, then call QTextLayout::glyphs()
423
   to get the set of glyph index list and QRawFont pairs.
424
425
   \sa advancesForGlyphIndexes(), glyphIndexesForChars(), QGlyphRun, QTextLayout::glyphRuns(), QTextFragment::glyphRuns()
426
*/
427
QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const
428
{
429
    if (!d->isValid())
430
        return QVector<quint32>();
431
432
    int nglyphs = text.size();
433
    QVarLengthGlyphLayoutArray glyphs(nglyphs);
434
    if (!glyphIndexesForChars(text.data(), text.size(), glyphs.glyphs, &nglyphs)) {
435
        glyphs.resize(nglyphs);
436
        if (!glyphIndexesForChars(text.data(), text.size(), glyphs.glyphs, &nglyphs)) {
437
            Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice");
438
            return QVector<quint32>();
439
        }
440
    }
441
442
    QVector<quint32> glyphIndexes;
443
    for (int i=0; i<nglyphs; ++i)
444
        glyphIndexes.append(glyphs.glyphs[i]);
445
446
    return glyphIndexes;
447
}
448
449
/*!
450
   Converts a string of unicode points to glyph indexes using the CMAP table in the
451
   underlying font. The function works like glyphIndexesForString() except it take
452
   an array (\a chars), the results will be returned though \a glyphIndexes array
453
   and number of glyphs will be set in \a numGlyphs. The size of \a glyphIndexes array
454
   must be at least \a numChars, if that's still not enough, this function will return
455
   false, then you can resize \a glyphIndexes from the size returned in \a numGlyphs.
456
457
   \sa glyphIndexesForString(), advancesForGlyphIndexes(), QGlyphRun,
458
       QTextLayout::glyphRuns(), QTextFragment::glyphRuns()
459
*/
460
bool QRawFont::glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const
461
{
462
    if (!d->isValid())
463
        return false;
464
465
    QGlyphLayout glyphs;
466
    glyphs.glyphs = glyphIndexes;
467
    return d->fontEngine->stringToCMap(chars, numChars, &glyphs, numGlyphs, QTextEngine::GlyphIndicesOnly);
468
}
469
470
/*!
471
   Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances
472
   give the distance from the position of a given glyph to where the next glyph should be drawn
473
   to make it appear as if the two glyphs are unspaced.
474
475
   \sa QTextLine::horizontalAdvance(), QFontMetricsF::width()
476
*/
477
QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const
478
{
479
    if (!d->isValid())
480
        return QVector<QPointF>();
481
482
    int numGlyphs = glyphIndexes.size();
483
    QVarLengthGlyphLayoutArray glyphs(numGlyphs);
484
    qMemCopy(glyphs.glyphs, glyphIndexes.data(), numGlyphs * sizeof(quint32));
485
486
    d->fontEngine->recalcAdvances(&glyphs, 0);
487
488
    QVector<QPointF> advances;
489
    for (int i=0; i<numGlyphs; ++i)
490
        advances.append(QPointF(glyphs.advances_x[i].toReal(), glyphs.advances_y[i].toReal()));
491
492
    return advances;
493
}
494
495
/*!
496
   Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances
497
   give the distance from the position of a given glyph to where the next glyph should be drawn
498
   to make it appear as if the two glyphs are unspaced. The glyph indexes are given with the
499
   array \a glyphIndexes while the results are returned through \a advances, both of them must
500
   have \a numGlyphs elements.
501
502
   \sa QTextLine::horizontalAdvance(), QFontMetricsF::width()
503
*/
504
bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const
505
{
506
    if (!d->isValid())
507
        return false;
508
509
    QGlyphLayout glyphs;
510
    glyphs.glyphs = const_cast<HB_Glyph *>(glyphIndexes);
511
    glyphs.numGlyphs = numGlyphs;
512
    QVarLengthArray<QFixed> advances_x(numGlyphs);
513
    QVarLengthArray<QFixed> advances_y(numGlyphs);
514
    glyphs.advances_x = advances_x.data();
515
    glyphs.advances_y = advances_y.data();
516
517
    d->fontEngine->recalcAdvances(&glyphs, 0);
518
519
    for (int i=0; i<numGlyphs; ++i)
520
        advances[i] = QPointF(glyphs.advances_x[i].toReal(), glyphs.advances_y[i].toReal());
521
522
    return true;
523
}
524
525
/*!
526
   Returns the hinting preference used to construct this QRawFont.
527
528
   \sa QFont::hintingPreference()
529
*/
530
QFont::HintingPreference QRawFont::hintingPreference() const
531
{
532
    return d->isValid() ? d->hintingPreference : QFont::PreferDefaultHinting;
533
}
534
535
/*!
536
   Retrieves the sfnt table named \a tagName from the underlying physical font, or an empty
537
   byte array if no such table was found. The returned font table's byte order is Big Endian, like
538
   the sfnt format specifies. The \a tagName must be four characters long and should be formatted
539
   in the default endianness of the current platform.
540
*/
541
QByteArray QRawFont::fontTable(const char *tagName) const
542
{
543
    if (!d->isValid())
544
        return QByteArray();
545
546
    const quint32 *tagId = reinterpret_cast<const quint32 *>(tagName);
547
    return d->fontEngine->getSfntTable(qToBigEndian(*tagId));
548
}
549
550
// From qfontdatabase.cpp
551
extern QList<QFontDatabase::WritingSystem> qt_determine_writing_systems_from_truetype_bits(quint32 unicodeRange[4], quint32 codePageRange[2]);
552
553
/*!
554
   Returns a list of writing systems supported by the font according to designer supplied
555
   information in the font file. Please note that this does not guarantee support for a
556
   specific unicode point in the font. You can use the supportsCharacter() to check support
557
   for a single, specific character.
558
559
   \note The list is determined based on the unicode ranges and codepage ranges set in the font's
560
   OS/2 table and requires such a table to be present in the underlying font file.
561
562
   \sa supportsCharacter()
563
*/
564
QList<QFontDatabase::WritingSystem> QRawFont::supportedWritingSystems() const
565
{
566
    if (d->isValid()) {
567
        QByteArray os2Table = fontTable("OS/2");
568
        if (os2Table.size() > 86) {
569
            char *data = os2Table.data();
570
            quint32 *bigEndianUnicodeRanges = reinterpret_cast<quint32 *>(data + 42);
571
            quint32 *bigEndianCodepageRanges = reinterpret_cast<quint32 *>(data + 78);
572
573
            quint32 unicodeRanges[4];
574
            quint32 codepageRanges[2];
575
576
            for (int i=0; i<4; ++i) {
577
                if (i < 2)
578
                    codepageRanges[i] = qFromBigEndian(bigEndianCodepageRanges[i]);
579
                unicodeRanges[i] = qFromBigEndian(bigEndianUnicodeRanges[i]);
580
            }
581
582
            return qt_determine_writing_systems_from_truetype_bits(unicodeRanges, codepageRanges);
583
        }
584
    }
585
586
    return QList<QFontDatabase::WritingSystem>();
587
}
588
589
/*!
590
    Returns true if the font has a glyph that corresponds to the given \a character.
591
592
    \sa supportedWritingSystems()
593
*/
594
bool QRawFont::supportsCharacter(QChar character) const
595
{
596
    return d->isValid() && d->fontEngine->canRender(&character, 1);
597
}
598
599
/*!
600
    \overload
601
   Returns true if the font has a glyph that corresponds to the UCS-4 encoded character \a ucs4.
602
603
   \sa supportedWritingSystems()
604
*/
605
bool QRawFont::supportsCharacter(quint32 ucs4) const
606
{
607
    QChar str[2];
608
    int len;
609
    if (!QChar::requiresSurrogates(ucs4)) {
610
        str[0] = QChar(ucs4);
611
        len = 1;
612
    } else {
613
        str[0] = QChar(QChar::highSurrogate(ucs4));
614
        str[1] = QChar(QChar::lowSurrogate(ucs4));
615
        len = 2;
616
    }
617
618
    return d->isValid() && d->fontEngine->canRender(str, len);
619
}
620
621
// qfontdatabase.cpp
622
extern int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem);
623
624
/*!
625
   Fetches the physical representation based on a \a font query. The physical font returned is
626
   the font that will be preferred by Qt in order to display text in the selected \a writingSystem.
627
*/
628
QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writingSystem)
629
{
630
    QRawFont rawFont;
631
#if defined(Q_WS_MAC)
632
    QTextLayout layout(QFontDatabase::writingSystemSample(writingSystem), font);
633
    layout.beginLayout();
634
    QTextLine line = layout.createLine();
635
    layout.endLayout();
636
    QList<QGlyphRun> list = layout.glyphRuns();
637
    if (list.size()) {
638
        // Pick the one matches the family name we originally requested,
639
        // if none of them match, just pick the first one
640
        for (int i = 0; i < list.size(); i++) {
641
            rawFont = list.at(i).rawFont();
642
            if (rawFont.familyName() == font.family())
643
                return rawFont;
644
        }
645
        return list.at(0).rawFont();
646
    }
647
#else
648
    QFontPrivate *font_d = QFontPrivate::get(font);
649
    int script = qt_script_for_writing_system(writingSystem);
650
    QFontEngine *fe = font_d->engineForScript(script);
651
652
    if (fe != 0 && fe->type() == QFontEngine::Multi) {
653
        QFontEngineMulti *multiEngine = static_cast<QFontEngineMulti *>(fe);
654
        fe = multiEngine->engine(0);
655
        if (fe == 0) {
656
            multiEngine->loadEngine(0);
657
            fe = multiEngine->engine(0);
658
        }
659
    }
660
661
    if (fe != 0) {
662
        rawFont.d.data()->fontEngine = fe;
663
        rawFont.d.data()->fontEngine->ref.ref();
664
        rawFont.d.data()->hintingPreference = font.hintingPreference();
665
    }
666
#endif
667
    return rawFont;
668
}
669
670
/*!
671
   Sets the pixel size with which this font should be rendered to \a pixelSize.
672
*/
673
void QRawFont::setPixelSize(qreal pixelSize)
674
{
675
    if (d->fontEngine == 0)
676
        return;
677
678
    d.detach();
679
    QFontEngine *oldFontEngine = d->fontEngine;
680
681
    d->fontEngine = d->fontEngine->cloneWithSize(pixelSize);
682
    if (d->fontEngine != 0)
683
        d->fontEngine->ref.ref();
684
685
    oldFontEngine->ref.deref();
686
    if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
687
        delete oldFontEngine;
688
}
689
690
/*!
691
    \internal
692
*/
693
void QRawFontPrivate::cleanUp()
694
{
695
    platformCleanUp();
696
    if (fontEngine != 0) {
697
        fontEngine->ref.deref();
698
        if (fontEngine->cache_count == 0 && fontEngine->ref == 0)
699
            delete fontEngine;
700
        fontEngine = 0;
701
    }
702
    hintingPreference = QFont::PreferDefaultHinting;
703
}
704
705
#endif // QT_NO_RAWFONT
706
707
QT_END_NAMESPACE