Coverage Report

Created: 2025-09-27 07:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/text/qrawfont.cpp
Line
Count
Source
1
/****************************************************************************
2
**
3
** Copyright (C) 2016 The Qt Company Ltd.
4
** Contact: https://www.qt.io/licensing/
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 The Qt Company. For licensing terms
14
** and conditions see https://www.qt.io/terms-conditions. For further
15
** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL3 included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 3 requirements
23
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24
**
25
** GNU General Public License Usage
26
** Alternatively, this file may be used under the terms of the GNU
27
** General Public License version 2.0 or (at your option) the GNU General
28
** Public license version 3 or any later version approved by the KDE Free
29
** Qt Foundation. The licenses are as published by the Free Software
30
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31
** included in the packaging of this file. Please review the following
32
** information to ensure the GNU General Public License requirements will
33
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34
** https://www.gnu.org/licenses/gpl-3.0.html.
35
**
36
** $QT_END_LICENSE$
37
**
38
****************************************************************************/
39
40
#include "qglobal.h"
41
42
#if !defined(QT_NO_RAWFONT)
43
44
#include "qrawfont.h"
45
#include "qrawfont_p.h"
46
#include "qplatformfontdatabase.h"
47
48
#include <private/qguiapplication_p.h>
49
#include <qpa/qplatformintegration.h>
50
#include <qpa/qplatformfontdatabase.h>
51
52
#include <QtCore/qendian.h>
53
#include <QtCore/qfile.h>
54
#include <QtGui/qpainterpath.h>
55
56
QT_BEGIN_NAMESPACE
57
58
/*!
59
   \class QRawFont
60
   \brief The QRawFont class provides access to a single physical instance of a font.
61
   \since 4.8
62
   \inmodule QtGui
63
64
   \ingroup text
65
   \ingroup shared
66
67
   \note QRawFont is a low level class. For most purposes QFont is a more appropriate class.
68
69
   Most commonly, when presenting text in a user interface, the exact fonts used
70
   to render the characters is to some extent unknown. This can be the case for several
71
   reasons: For instance, the actual, physical fonts present on the target system could be
72
   unexpected to the developers, or the text could contain user selected styles, sizes or
73
   writing systems that are not supported by font chosen in the code.
74
75
   Therefore, Qt's QFont class really represents a query for fonts. When text is interpreted,
76
   Qt will do its best to match the text to the query, but depending on the support, different
77
   fonts can be used behind the scenes.
78
79
   For most use cases, this is both expected and necessary, as it minimizes the possibility of
80
   text in the user interface being undisplayable. In some cases, however, more direct control
81
   over the process might be useful. It is for these use cases the QRawFont class exists.
82
83
   A QRawFont object represents a single, physical instance of a given font in a given pixel size.
84
   I.e. in the typical case it represents a set of TrueType or OpenType font tables and uses a
85
   user specified pixel size to convert metrics into logical pixel units. It can be used in
86
   combination with the QGlyphRun class to draw specific glyph indexes at specific positions, and
87
   also have accessors to some relevant data in the physical font.
88
89
   QRawFont only provides support for the main font technologies: GDI and DirectWrite on Windows
90
   platforms, FreeType on Linux platforms and CoreText on \macos. For other
91
   font back-ends, the APIs will be disabled.
92
93
   QRawFont can be constructed in a number of ways:
94
   \list
95
   \li It can be constructed by calling QTextLayout::glyphs() or QTextFragment::glyphs(). The
96
      returned QGlyphs objects will contain QRawFont objects which represent the actual fonts
97
      used to render each portion of the text.
98
   \li It can be constructed by passing a QFont object to QRawFont::fromFont(). The function
99
      will return a QRawFont object representing the font that will be selected as response to
100
      the QFont query and the selected writing system.
101
   \li It can be constructed by passing a file name or QByteArray directly to the QRawFont
102
      constructor, or by calling loadFromFile() or loadFromData(). In this case, the
103
      font will not be registered in QFontDatabase, and it will not be available as part of
104
      regular font selection.
105
   \endlist
106
107
   QRawFont is considered local to the thread in which it is constructed (either using a
108
   constructor, or by calling loadFromData() or loadFromFile()). The QRawFont cannot be moved to a
109
   different thread, but will have to be recreated in the thread in question.
110
111
   \note For the requirement of caching glyph indexes and font selections for static text to avoid
112
   reshaping and relayouting in the inner loop of an application, a better choice is the QStaticText
113
   class, since it optimizes the memory cost of the cache and also provides the possibility of paint
114
   engine specific caches for an additional speed-up.
115
*/
116
117
/*!
118
    \enum QRawFont::AntialiasingType
119
120
    This enum represents the different ways a glyph can be rasterized in the function
121
    alphaMapForGlyph().
122
123
    \value PixelAntialiasing Will rasterize by measuring the coverage of the shape on whole pixels.
124
           The returned image contains the alpha values of each pixel based on the coverage of
125
           the glyph shape.
126
    \value SubPixelAntialiasing Will rasterize by measuring the coverage of each subpixel,
127
           returning a separate alpha value for each of the red, green and blue components of
128
           each pixel.
129
*/
130
131
/*!
132
    \enum QRawFont::LayoutFlag
133
    \since 5.1
134
135
    This enum tells the function advancesForGlyphIndexes() how to calculate the advances.
136
137
    \value SeparateAdvances Will calculate the advance for each glyph separately.
138
    \value KernedAdvances Will apply kerning between adjacent glyphs. Note that OpenType GPOS based
139
           kerning is currently not supported.
140
    \value UseDesignMetrics Use design metrics instead of hinted metrics adjusted to the resolution
141
           of the paint device.
142
           Can be OR-ed with any of the options above.
143
*/
144
145
/*!
146
   Constructs an invalid QRawFont.
147
*/
148
QRawFont::QRawFont()
149
0
    : d(new QRawFontPrivate)
150
0
{
151
0
}
152
153
/*!
154
   Constructs a QRawFont representing the font contained in the file referenced
155
   by \a fileName for the size (in pixels) given by \a pixelSize, and using the
156
   hinting preference specified by \a hintingPreference.
157
158
   \note The referenced file must contain a TrueType or OpenType font.
159
*/
160
QRawFont::QRawFont(const QString &fileName,
161
                   qreal pixelSize,
162
                   QFont::HintingPreference hintingPreference)
163
0
    : d(new QRawFontPrivate)
164
0
{
165
0
    loadFromFile(fileName, pixelSize, hintingPreference);
166
0
}
167
168
/*!
169
   Constructs a QRawFont representing the font contained in the supplied
170
   \a fontData for the size (in pixels) given by \a pixelSize, and using the
171
   hinting preference specified by \a hintingPreference.
172
173
   \note The data must contain a TrueType or OpenType font.
174
*/
175
QRawFont::QRawFont(const QByteArray &fontData,
176
                   qreal pixelSize,
177
                   QFont::HintingPreference hintingPreference)
178
0
    : d(new QRawFontPrivate)
179
0
{
180
0
    loadFromData(fontData, pixelSize, hintingPreference);
181
0
}
182
183
/*!
184
   Creates a QRawFont which is a copy of \a other.
185
*/
186
QRawFont::QRawFont(const QRawFont &other)
187
0
{
188
0
    d = other.d;
189
0
}
190
191
/*!
192
   Destroys the QRawFont
193
*/
194
QRawFont::~QRawFont()
195
0
{
196
0
}
197
198
/*!
199
  Assigns \a other to this QRawFont.
200
*/
201
QRawFont &QRawFont::operator=(const QRawFont &other)
202
0
{
203
0
    d = other.d;
204
0
    return *this;
205
0
}
206
207
/*!
208
  \fn void QRawFont::swap(QRawFont &other)
209
  \since 5.0
210
211
  Swaps this raw font with \a other. This function is very fast and
212
  never fails.
213
*/
214
215
/*!
216
   Returns \c true if the QRawFont is valid and false otherwise.
217
*/
218
bool QRawFont::isValid() const
219
0
{
220
0
    return d->isValid();
221
0
}
222
223
/*!
224
   Replaces the current QRawFont with the contents of the file referenced
225
   by \a fileName for the size (in pixels) given by \a pixelSize, and using the
226
   hinting preference specified by \a hintingPreference.
227
228
   The file must reference a TrueType or OpenType font.
229
230
   \sa loadFromData()
231
*/
232
void QRawFont::loadFromFile(const QString &fileName,
233
                            qreal pixelSize,
234
                            QFont::HintingPreference hintingPreference)
235
0
{
236
0
    QFile file(fileName);
237
0
    if (file.open(QIODevice::ReadOnly))
238
0
        loadFromData(file.readAll(), pixelSize, hintingPreference);
239
0
}
240
241
/*!
242
   Replaces the current QRawFont with the font contained in the supplied
243
   \a fontData for the size (in pixels) given by \a pixelSize, and using the
244
   hinting preference specified by \a hintingPreference.
245
246
   The \a fontData must contain a TrueType or OpenType font.
247
248
   \sa loadFromFile()
249
*/
250
void QRawFont::loadFromData(const QByteArray &fontData,
251
                            qreal pixelSize,
252
                            QFont::HintingPreference hintingPreference)
253
0
{
254
0
    d.detach();
255
0
    d->cleanUp();
256
0
    d->hintingPreference = hintingPreference;
257
0
    d->loadFromData(fontData, pixelSize, hintingPreference);
258
0
}
259
260
/*!
261
   This function returns a rasterized image of the glyph at the given
262
   \a glyphIndex in the underlying font, using the \a transform specified.
263
   If the QRawFont is not valid, this function will return an invalid QImage.
264
265
   If the font is a color font, then the resulting image will contain the rendered
266
   glyph at the current pixel size. In this case, the \a antialiasingType will be
267
   ignored.
268
269
   Otherwise, if \a antialiasingType is set to QRawFont::SubPixelAntialiasing, then the resulting image
270
   will be in QImage::Format_RGB32 and the RGB values of each pixel will represent the subpixel opacities
271
   of the pixel in the rasterization of the glyph. Otherwise, the image will be in the format of
272
   QImage::Format_Indexed8 and each pixel will contain the opacity of the pixel in the
273
   rasterization.
274
275
   \sa pathForGlyph(), QPainter::drawGlyphRun()
276
*/
277
QImage QRawFont::alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialiasingType,
278
                                  const QTransform &transform) const
279
0
{
280
0
    if (!d->isValid())
281
0
        return QImage();
282
283
0
    if (d->fontEngine->glyphFormat == QFontEngine::Format_ARGB)
284
0
        return d->fontEngine->bitmapForGlyph(glyphIndex, QFixed(), transform);
285
286
0
    if (antialiasingType == SubPixelAntialiasing)
287
0
        return d->fontEngine->alphaRGBMapForGlyph(glyphIndex, QFixed(), transform);
288
289
0
    return d->fontEngine->alphaMapForGlyph(glyphIndex, QFixed(), transform);
290
0
}
291
292
/*!
293
   This function returns the shape of the glyph at a given \a glyphIndex in the underlying font
294
   if the QRawFont is valid. Otherwise, it returns an empty QPainterPath.
295
296
   The returned glyph will always be unhinted.
297
298
   \sa alphaMapForGlyph(), QPainterPath::addText()
299
*/
300
QPainterPath QRawFont::pathForGlyph(quint32 glyphIndex) const
301
0
{
302
0
    if (!d->isValid())
303
0
        return QPainterPath();
304
305
0
    QFixedPoint position;
306
0
    QPainterPath path;
307
0
    d->fontEngine->addGlyphsToPath(&glyphIndex, &position, 1, &path, { });
308
0
    return path;
309
0
}
310
311
/*!
312
   Returns \c true if this QRawFont is equal to \a other. Otherwise, returns \c false.
313
*/
314
bool QRawFont::operator==(const QRawFont &other) const
315
0
{
316
0
    return d->fontEngine == other.d->fontEngine;
317
0
}
318
319
/*!
320
    Returns the hash value for \a font. If specified, \a seed is used
321
    to initialize the hash.
322
323
    \relates QRawFont
324
    \since 5.8
325
*/
326
uint qHash(const QRawFont &font, uint seed) noexcept
327
0
{
328
0
    return qHash(QRawFontPrivate::get(font)->fontEngine, seed);
329
0
}
330
331
332
/*!
333
    \fn bool QRawFont::operator!=(const QRawFont &other) const
334
335
    Returns \c true if this QRawFont is not equal to \a other. Otherwise, returns \c false.
336
*/
337
338
/*!
339
   Returns the ascent of this QRawFont in pixel units.
340
341
   The ascent of a font is the distance from the baseline to the
342
   highest position characters extend to. In practice, some font
343
   designers break this rule, e.g. when they put more than one accent
344
   on top of a character, or to accommodate an unusual character in
345
   an exotic language, so it is possible (though rare) that this
346
   value will be too small.
347
348
   \sa QFontMetricsF::ascent()
349
*/
350
qreal QRawFont::ascent() const
351
0
{
352
0
    return d->isValid() ? d->fontEngine->ascent().toReal() : 0.0;
353
0
}
354
355
/*!
356
   Returns the cap height of this QRawFont in pixel units.
357
358
   \since 5.8
359
360
   The cap height of a font is the height of a capital letter above
361
   the baseline. It specifically is the height of capital letters
362
   that are flat - such as H or I - as opposed to round letters such
363
   as O, or pointed letters like A, both of which may display overshoot.
364
365
   \sa QFontMetricsF::capHeight()
366
*/
367
qreal QRawFont::capHeight() const
368
0
{
369
0
    return d->isValid() ? d->fontEngine->capHeight().toReal() : 0.0;
370
0
}
371
372
/*!
373
   Returns the descent of this QRawFont in pixel units.
374
375
   The descent is the distance from the base line to the lowest point
376
   characters extend to. In practice, some font designers break this rule,
377
   e.g. to accommodate an unusual character in an exotic language, so
378
   it is possible (though rare) that this value will be too small.
379
380
   \sa QFontMetricsF::descent()
381
*/
382
qreal QRawFont::descent() const
383
0
{
384
0
    return d->isValid() ? d->fontEngine->descent().toReal() : 0.0;
385
0
}
386
387
/*!
388
   Returns the xHeight of this QRawFont in pixel units.
389
390
   This is often but not always the same as the height of the character 'x'.
391
392
   \sa QFontMetricsF::xHeight()
393
*/
394
qreal QRawFont::xHeight() const
395
0
{
396
0
    return d->isValid() ? d->fontEngine->xHeight().toReal() : 0.0;
397
0
}
398
399
/*!
400
   Returns the leading of this QRawFont in pixel units.
401
402
   This is the natural inter-line spacing.
403
404
   \sa QFontMetricsF::leading()
405
*/
406
qreal QRawFont::leading() const
407
0
{
408
0
    return d->isValid() ? d->fontEngine->leading().toReal() : 0.0;
409
0
}
410
411
/*!
412
   Returns the average character width of this QRawFont in pixel units.
413
414
   \sa QFontMetricsF::averageCharWidth()
415
*/
416
qreal QRawFont::averageCharWidth() const
417
0
{
418
0
    return d->isValid() ? d->fontEngine->averageCharWidth().toReal() : 0.0;
419
0
}
420
421
/*!
422
   Returns the width of the widest character in the font.
423
424
   \sa QFontMetricsF::maxWidth()
425
*/
426
qreal QRawFont::maxCharWidth() const
427
0
{
428
0
    return d->isValid() ? d->fontEngine->maxCharWidth() : 0.0;
429
0
}
430
431
/*!
432
   Returns the pixel size set for this QRawFont. The pixel size affects how glyphs are
433
   rasterized, the size of glyphs returned by pathForGlyph(), and is used to convert
434
   internal metrics from design units to logical pixel units.
435
436
   \sa setPixelSize()
437
*/
438
qreal QRawFont::pixelSize() const
439
0
{
440
0
    return d->isValid() ? d->fontEngine->fontDef.pixelSize : 0.0;
441
0
}
442
443
/*!
444
   Returns the number of design units define the width and height of the em square
445
   for this QRawFont. This value is used together with the pixel size when converting design metrics
446
   to pixel units, as the internal metrics are specified in design units and the pixel size gives
447
   the size of 1 em in pixels.
448
449
   \sa pixelSize(), setPixelSize()
450
*/
451
qreal QRawFont::unitsPerEm() const
452
0
{
453
0
    return d->isValid() ? d->fontEngine->emSquareSize().toReal() : 0.0;
454
0
}
455
456
/*!
457
   Returns the thickness for drawing lines (underline, overline, etc.)
458
   along with text drawn in this font.
459
 */
460
qreal QRawFont::lineThickness() const
461
0
{
462
0
    return d->isValid() ? d->fontEngine->lineThickness().toReal() : 0.0;
463
0
}
464
465
/*!
466
   Returns the position from baseline for drawing underlines below the text
467
   rendered with this font.
468
 */
469
qreal QRawFont::underlinePosition() const
470
0
{
471
0
    return d->isValid() ? d->fontEngine->underlinePosition().toReal() : 0.0;
472
0
}
473
474
/*!
475
   Returns the family name of this QRawFont.
476
*/
477
QString QRawFont::familyName() const
478
0
{
479
0
    return d->isValid() ? d->fontEngine->fontDef.family : QString();
480
0
}
481
482
/*!
483
   Returns the style name of this QRawFont.
484
485
   \sa QFont::styleName()
486
*/
487
QString QRawFont::styleName() const
488
0
{
489
0
    return d->isValid() ? d->fontEngine->fontDef.styleName : QString();
490
0
}
491
492
/*!
493
   Returns the style of this QRawFont.
494
495
   \sa QFont::style()
496
*/
497
QFont::Style QRawFont::style() const
498
0
{
499
0
    return d->isValid() ? QFont::Style(d->fontEngine->fontDef.style) : QFont::StyleNormal;
500
0
}
501
502
/*!
503
   Returns the weight of this QRawFont.
504
505
   \sa QFont::weight()
506
*/
507
int QRawFont::weight() const
508
0
{
509
0
    return d->isValid() ? int(d->fontEngine->fontDef.weight) : -1;
510
0
}
511
512
/*!
513
   Converts the string of unicode points given by \a text to glyph indexes
514
   using the CMAP table in the underlying font, and returns a vector containing
515
   the result.
516
517
   Note that, in cases where there are other tables in the font that affect the
518
   shaping of the text, the returned glyph indexes will not correctly represent
519
   the rendering of the text. To get the correctly shaped text, you can use
520
   QTextLayout to lay out and shape the text, then call QTextLayout::glyphs()
521
   to get the set of glyph index list and QRawFont pairs.
522
523
   \sa advancesForGlyphIndexes(), glyphIndexesForChars(), QGlyphRun, QTextLayout::glyphRuns(), QTextFragment::glyphRuns()
524
*/
525
QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const
526
{
527
    QVector<quint32> glyphIndexes;
528
    if (!d->isValid() || text.isEmpty())
529
        return glyphIndexes;
530
531
    int numGlyphs = text.size();
532
    glyphIndexes.resize(numGlyphs);
533
534
    QGlyphLayout glyphs;
535
    glyphs.numGlyphs = numGlyphs;
536
    glyphs.glyphs = glyphIndexes.data();
537
    if (!d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &numGlyphs, QFontEngine::GlyphIndicesOnly))
538
        Q_UNREACHABLE();
539
540
    glyphIndexes.resize(numGlyphs);
541
    return glyphIndexes;
542
}
543
544
/*!
545
   Converts a string of unicode points to glyph indexes using the CMAP table in the
546
   underlying font. The function works like glyphIndexesForString() except it take
547
   an array (\a chars), the results will be returned though \a glyphIndexes array
548
   and number of glyphs will be set in \a numGlyphs. The size of \a glyphIndexes array
549
   must be at least \a numChars, if that's still not enough, this function will return
550
   false, then you can resize \a glyphIndexes from the size returned in \a numGlyphs.
551
552
   \sa glyphIndexesForString(), advancesForGlyphIndexes(), QGlyphRun, QTextLayout::glyphRuns(), QTextFragment::glyphRuns()
553
*/
554
bool QRawFont::glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const
555
0
{
556
0
    Q_ASSERT(numGlyphs);
557
0
    if (!d->isValid() || numChars <= 0) {
558
0
        *numGlyphs = 0;
559
0
        return false;
560
0
    }
561
562
0
    if (*numGlyphs <= 0 || !glyphIndexes) {
563
0
        *numGlyphs = numChars;
564
0
        return false;
565
0
    }
566
567
0
    QGlyphLayout glyphs;
568
0
    glyphs.numGlyphs = *numGlyphs;
569
0
    glyphs.glyphs = glyphIndexes;
570
0
    return d->fontEngine->stringToCMap(chars, numChars, &glyphs, numGlyphs, QFontEngine::GlyphIndicesOnly);
571
0
}
572
573
/*!
574
   \fn QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes, LayoutFlags layoutFlags) const
575
   \since 5.1
576
577
   Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances
578
   give the distance from the position of a given glyph to where the next glyph should be drawn
579
   to make it appear as if the two glyphs are unspaced. How the advances are calculated is
580
   controlled by \a layoutFlags.
581
582
   \sa QTextLine::horizontalAdvance(), QFontMetricsF::width()
583
*/
584
585
/*!
586
   \fn QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const
587
588
   \overload
589
590
   Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances
591
   give the distance from the position of a given glyph to where the next glyph should be drawn
592
   to make it appear as if the two glyphs are unspaced. The advance of each glyph is calculated
593
   separately.
594
595
   \sa QTextLine::horizontalAdvance(), QFontMetricsF::width()
596
*/
597
598
/*!
599
   \since 5.1
600
601
   Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances
602
   give the distance from the position of a given glyph to where the next glyph should be drawn
603
   to make it appear as if the two glyphs are unspaced. The glyph indexes are given with the
604
   array \a glyphIndexes while the results are returned through \a advances, both of them must
605
   have \a numGlyphs elements. How the advances are calculated is controlled by \a layoutFlags.
606
607
   \sa QTextLine::horizontalAdvance(), QFontMetricsF::width()
608
*/
609
bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs, LayoutFlags layoutFlags) const
610
0
{
611
0
    Q_ASSERT(glyphIndexes && advances);
612
0
    if (!d->isValid() || numGlyphs <= 0)
613
0
        return false;
614
615
0
    QVarLengthArray<QFixed> tmpAdvances(numGlyphs);
616
617
0
    QGlyphLayout glyphs;
618
0
    glyphs.glyphs = const_cast<glyph_t *>(glyphIndexes);
619
0
    glyphs.numGlyphs = numGlyphs;
620
0
    glyphs.advances = tmpAdvances.data();
621
622
0
    bool design = layoutFlags & UseDesignMetrics;
623
624
0
    d->fontEngine->recalcAdvances(&glyphs, design ? QFontEngine::DesignMetrics : QFontEngine::ShaperFlag(0));
625
0
    if (layoutFlags & KernedAdvances)
626
0
        d->fontEngine->doKerning(&glyphs, design ? QFontEngine::DesignMetrics : QFontEngine::ShaperFlag(0));
627
628
0
    for (int i=0; i<numGlyphs; ++i)
629
0
        advances[i] = QPointF(tmpAdvances[i].toReal(), 0.0);
630
631
0
    return true;
632
0
}
633
634
/*!
635
   \overload
636
637
   Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances
638
   give the distance from the position of a given glyph to where the next glyph should be drawn
639
   to make it appear as if the two glyphs are unspaced. The glyph indexes are given with the
640
   array \a glyphIndexes while the results are returned through \a advances, both of them must
641
   have \a numGlyphs elements. The advance of each glyph is calculated separately
642
643
   \sa QTextLine::horizontalAdvance(), QFontMetricsF::width()
644
*/
645
bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const
646
0
{
647
0
    return QRawFont::advancesForGlyphIndexes(glyphIndexes, advances, numGlyphs, SeparateAdvances);
648
0
}
649
650
/*!
651
   Returns the hinting preference used to construct this QRawFont.
652
653
   \sa QFont::hintingPreference()
654
*/
655
QFont::HintingPreference QRawFont::hintingPreference() const
656
0
{
657
0
    return d->isValid() ? d->hintingPreference : QFont::PreferDefaultHinting;
658
0
}
659
660
/*!
661
   Retrieves the sfnt table named \a tagName from the underlying physical font, or an empty
662
   byte array if no such table was found. The returned font table's byte order is Big Endian, like
663
   the sfnt format specifies. The \a tagName must be four characters long and should be formatted
664
   in the default endianness of the current platform.
665
*/
666
QByteArray QRawFont::fontTable(const char *tagName) const
667
0
{
668
0
    if (!d->isValid())
669
0
        return QByteArray();
670
671
0
    return d->fontEngine->getSfntTable(MAKE_TAG(tagName[0], tagName[1], tagName[2], tagName[3]));
672
0
}
673
674
/*!
675
   Returns a list of writing systems supported by the font according to designer supplied
676
   information in the font file. Please note that this does not guarantee support for a
677
   specific unicode point in the font. You can use the supportsCharacter() to check support
678
   for a single, specific character.
679
680
   \note The list is determined based on the unicode ranges and codepage ranges set in the font's
681
   OS/2 table and requires such a table to be present in the underlying font file.
682
683
   \sa supportsCharacter()
684
*/
685
QList<QFontDatabase::WritingSystem> QRawFont::supportedWritingSystems() const
686
0
{
687
0
    QList<QFontDatabase::WritingSystem> writingSystems;
688
0
    if (d->isValid()) {
689
0
        QByteArray os2Table = fontTable("OS/2");
690
0
        if (os2Table.size() > 86) {
691
0
            const uchar * const data = reinterpret_cast<const uchar *>(os2Table.constData());
692
0
            const uchar * const bigEndianUnicodeRanges  = data + 42;
693
0
            const uchar * const bigEndianCodepageRanges = data + 78;
694
695
0
            quint32 unicodeRanges[4];
696
0
            quint32 codepageRanges[2];
697
698
0
            for (size_t i = 0; i < sizeof unicodeRanges / sizeof *unicodeRanges; ++i)
699
0
                unicodeRanges[i] = qFromBigEndian<quint32>(bigEndianUnicodeRanges + i * sizeof(quint32));
700
701
0
            for (size_t i = 0; i < sizeof codepageRanges / sizeof *codepageRanges; ++i)
702
0
                codepageRanges[i] = qFromBigEndian<quint32>(bigEndianCodepageRanges + i * sizeof(quint32));
703
704
0
            QSupportedWritingSystems ws = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRanges, codepageRanges);
705
0
            for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
706
0
                if (ws.supported(QFontDatabase::WritingSystem(i)))
707
0
                    writingSystems.append(QFontDatabase::WritingSystem(i));
708
0
            }
709
0
        }
710
0
    }
711
712
0
    return writingSystems;
713
0
}
714
715
/*!
716
    Returns \c true if the font has a glyph that corresponds to the given \a character.
717
718
    \sa supportedWritingSystems()
719
*/
720
bool QRawFont::supportsCharacter(QChar character) const
721
0
{
722
0
    return supportsCharacter(character.unicode());
723
0
}
724
725
/*!
726
    \overload
727
728
   Returns \c true if the font has a glyph that corresponds to the UCS-4 encoded character \a ucs4.
729
730
   \sa supportedWritingSystems()
731
*/
732
bool QRawFont::supportsCharacter(uint ucs4) const
733
0
{
734
0
    return d->isValid() && d->fontEngine->canRender(ucs4);
735
0
}
736
737
// qfontdatabase.cpp
738
extern int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem);
739
740
/*!
741
   Fetches the physical representation based on a \a font query. The physical font returned is
742
   the font that will be preferred by Qt in order to display text in the selected \a writingSystem.
743
744
   \warning This function is potentially expensive and should not be called in performance
745
   sensitive code.
746
*/
747
QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writingSystem)
748
0
{
749
0
    QRawFont rawFont;
750
0
    const QFontPrivate *font_d = QFontPrivate::get(font);
751
0
    int script = qt_script_for_writing_system(writingSystem);
752
0
    QFontEngine *fe = font_d->engineForScript(script);
753
754
0
    if (fe != nullptr && fe->type() == QFontEngine::Multi) {
755
0
        QFontEngineMulti *multiEngine = static_cast<QFontEngineMulti *>(fe);
756
0
        fe = multiEngine->engine(0);
757
758
0
        if (script > QChar::Script_Latin) {
759
            // keep in sync with QFontEngineMulti::loadEngine()
760
0
            QFontDef request(multiEngine->fontDef);
761
0
            request.styleStrategy |= QFont::NoFontMerging;
762
763
0
            if (QFontEngine *engine = QFontDatabase::findFont(request, script, true)) {
764
0
                if (request.weight > QFont::Normal)
765
0
                    engine->fontDef.weight = request.weight;
766
0
                if (request.style > QFont::StyleNormal)
767
0
                    engine->fontDef.style = request.style;
768
0
                fe = engine;
769
0
            }
770
0
        }
771
0
        Q_ASSERT(fe);
772
0
    }
773
774
0
    if (fe != nullptr) {
775
0
        rawFont.d.data()->setFontEngine(fe);
776
0
        rawFont.d.data()->hintingPreference = font.hintingPreference();
777
0
    }
778
0
    return rawFont;
779
0
}
780
781
/*!
782
   Sets the pixel size with which this font should be rendered to \a pixelSize.
783
*/
784
void QRawFont::setPixelSize(qreal pixelSize)
785
0
{
786
0
    if (!d->isValid() || qFuzzyCompare(d->fontEngine->fontDef.pixelSize, pixelSize))
787
0
        return;
788
789
0
    d.detach();
790
0
    d->setFontEngine(d->fontEngine->cloneWithSize(pixelSize));
791
0
}
792
793
/*!
794
    \internal
795
*/
796
void QRawFontPrivate::loadFromData(const QByteArray &fontData, qreal pixelSize,
797
                                           QFont::HintingPreference hintingPreference)
798
0
{
799
0
    Q_ASSERT(fontEngine == nullptr);
800
801
0
    QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
802
0
    setFontEngine(pfdb->fontEngine(fontData, pixelSize, hintingPreference));
803
0
}
804
805
/*!
806
  Returns the smallest rectangle containing the glyph with the given \a glyphIndex.
807
808
  \since 5.0
809
*/
810
QRectF QRawFont::boundingRect(quint32 glyphIndex) const
811
0
{
812
0
    if (!d->isValid())
813
0
        return QRectF();
814
815
0
    glyph_metrics_t gm = d->fontEngine->boundingBox(glyphIndex);
816
0
    return QRectF(gm.x.toReal(), gm.y.toReal(), gm.width.toReal(), gm.height.toReal());
817
0
}
818
819
#endif // QT_NO_RAWFONT
820
821
QT_END_NAMESPACE