Coverage Report

Created: 2026-05-31 06:50

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