Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qrawfont.cpp
Go to the documentation of this file.
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"
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
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*/
112QRawFont::QRawFont()
113 : d(new QRawFontPrivate)
114{
115}
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*/
124QRawFont::QRawFont(const QString &fileName,
125 qreal pixelSize,
126 QFont::HintingPreference hintingPreference)
127 : d(new QRawFontPrivate)
128{
129 loadFromFile(fileName, pixelSize, hintingPreference);
130}
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*/
139QRawFont::QRawFont(const QByteArray &fontData,
140 qreal pixelSize,
141 QFont::HintingPreference hintingPreference)
142 : d(new QRawFontPrivate)
143{
144 loadFromData(fontData, pixelSize, hintingPreference);
145}
146
147/*!
148 Creates a QRawFont which is a copy of \a other.
149*/
150QRawFont::QRawFont(const QRawFont &other)
151{
152 d = other.d;
153}
154
155/*!
156 Destroys the QRawFont
157*/
158QRawFont::~QRawFont()
159{
160}
161
162/*!
163 Assigns \a other to this QRawFont.
164*/
165QRawFont &QRawFont::operator=(const QRawFont &other)
166{
167 d = other.d;
168 return *this;
169}
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*/
180bool QRawFont::isValid() const
181{
182 return d->isValid();
183}
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*/
194void QRawFont::loadFromFile(const QString &fileName,
195 qreal pixelSize,
196 QFont::HintingPreference hintingPreference)
197{
198 QFile file(fileName);
199 if (file.open(QIODevice::ReadOnly))
200 loadFromData(file.readAll(), pixelSize, hintingPreference);
201}
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*/
212void QRawFont::loadFromData(const QByteArray &fontData,
213 qreal pixelSize,
214 QFont::HintingPreference hintingPreference)
215{
216 d.detach();
217 d->cleanUp();
218 d->hintingPreference = hintingPreference;
219 d->loadFromData(fontData, pixelSize, hintingPreference);
220}
221
222/*!
223 Returns the number of glyphs in this QRawFont.
224
225 \since 6.11
226*/
227int QRawFont::glyphCount() const
228{
229 return d->isValid() ? d->fontEngine->glyphCount() : 0;
230}
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*/
240QString QRawFont::glyphName(quint32 glyphIndex) const
241{
242 return d->isValid() ? d->fontEngine->glyphName(glyphIndex) : QString();
243}
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*/
262QImage QRawFont::alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialiasingType,
263 const QTransform &transform) const
264{
265 if (!d->isValid())
266 return QImage();
267
268 if (d->fontEngine->glyphFormat == QFontEngine::Format_ARGB)
269 return d->fontEngine->bitmapForGlyph(glyphIndex, QFixedPoint(), transform);
270
271 if (antialiasingType == SubPixelAntialiasing)
272 return d->fontEngine->alphaRGBMapForGlyph(glyphIndex, QFixedPoint(), transform);
273
274 return d->fontEngine->alphaMapForGlyph(glyphIndex, QFixedPoint(), transform);
275}
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*/
285QPainterPath QRawFont::pathForGlyph(quint32 glyphIndex) const
286{
287 if (!d->isValid())
288 return QPainterPath();
289
290 QFixedPoint position;
291 QPainterPath path;
292 d->fontEngine->addGlyphsToPath(&glyphIndex, &position, 1, &path, { });
293 return path;
294}
295
296/*!
297 Returns \c true if this QRawFont is equal to \a other. Otherwise, returns \c false.
298*/
299bool QRawFont::operator==(const QRawFont &other) const
300{
301 return d->fontEngine == other.d->fontEngine;
302}
303
304/*!
305 \fn size_t qHash(const QRawFont &key, size_t seed)
306 \qhashold{QRawFont}
307 \since 5.8
308*/
309size_t qHash(const QRawFont &font, size_t seed) noexcept
310{
311 return qHash(QRawFontPrivate::get(font)->fontEngine, seed);
312}
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*/
333qreal QRawFont::ascent() const
334{
335 return d->isValid() ? d->fontEngine->ascent().toReal() : 0.0;
336}
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*/
350qreal QRawFont::capHeight() const
351{
352 return d->isValid() ? d->fontEngine->capHeight().toReal() : 0.0;
353}
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*/
365qreal QRawFont::descent() const
366{
367 return d->isValid() ? d->fontEngine->descent().toReal() : 0.0;
368}
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*/
377qreal QRawFont::xHeight() const
378{
379 return d->isValid() ? d->fontEngine->xHeight().toReal() : 0.0;
380}
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*/
389qreal QRawFont::leading() const
390{
391 return d->isValid() ? d->fontEngine->leading().toReal() : 0.0;
392}
393
394/*!
395 Returns the average character width of this QRawFont in pixel units.
396
397 \sa QFontMetricsF::averageCharWidth()
398*/
399qreal QRawFont::averageCharWidth() const
400{
401 return d->isValid() ? d->fontEngine->averageCharWidth().toReal() : 0.0;
402}
403
404/*!
405 Returns the width of the widest character in the font.
406
407 \sa QFontMetricsF::maxWidth()
408*/
409qreal QRawFont::maxCharWidth() const
410{
411 return d->isValid() ? d->fontEngine->maxCharWidth() : 0.0;
412}
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*/
421qreal QRawFont::pixelSize() const
422{
423 return d->isValid() ? d->fontEngine->fontDef.pixelSize : 0.0;
424}
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*/
434qreal QRawFont::unitsPerEm() const
435{
436 return d->isValid() ? d->fontEngine->emSquareSize().toReal() : 0.0;
437}
438
439/*!
440 Returns the thickness for drawing lines (underline, overline, etc.)
441 along with text drawn in this font.
442 */
443qreal QRawFont::lineThickness() const
444{
445 return d->isValid() ? d->fontEngine->lineThickness().toReal() : 0.0;
446}
447
448/*!
449 Returns the position from baseline for drawing underlines below the text
450 rendered with this font.
451 */
452qreal QRawFont::underlinePosition() const
453{
454 return d->isValid() ? d->fontEngine->underlinePosition().toReal() : 0.0;
455}
456
457/*!
458 Returns the family name of this QRawFont.
459*/
460QString QRawFont::familyName() const
461{
462 return d->isValid() ? d->fontEngine->fontDef.families.constFirst() : QString();
463}
464
465/*!
466 Returns the style name of this QRawFont.
467
468 \sa QFont::styleName()
469*/
470QString QRawFont::styleName() const
471{
472 return d->isValid() ? d->fontEngine->fontDef.styleName : QString();
473}
474
475/*!
476 Returns the style of this QRawFont.
477
478 \sa QFont::style()
479*/
480QFont::Style QRawFont::style() const
481{
482 return d->isValid() ? QFont::Style(d->fontEngine->fontDef.style) : QFont::StyleNormal;
483}
484
485/*!
486 Returns the weight of this QRawFont.
487
488 \sa QFont::weight()
489*/
490int QRawFont::weight() const
491{
492 return d->isValid() ? int(d->fontEngine->fontDef.weight) : -1;
493}
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*/
508QList<quint32> QRawFont::glyphIndexesForString(const QString &text) const
509{
510 QList<quint32> glyphIndexes;
511 if (!d->isValid() || text.isEmpty())
512 return glyphIndexes;
513
514 int numGlyphs = text.size();
515 glyphIndexes.resize(numGlyphs);
516
517 QGlyphLayout glyphs;
518 glyphs.numGlyphs = numGlyphs;
519 glyphs.glyphs = glyphIndexes.data();
520 if (d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &numGlyphs, QFontEngine::GlyphIndicesOnly) < 0)
521 Q_UNREACHABLE();
522
523 glyphIndexes.resize(numGlyphs);
524 return glyphIndexes;
525}
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*/
537bool QRawFont::glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const
538{
539 Q_ASSERT(numGlyphs);
540 if (!d->isValid() || numChars <= 0) {
541 *numGlyphs = 0;
542 return false;
543 }
544
545 if (*numGlyphs <= 0 || !glyphIndexes) {
546 *numGlyphs = numChars;
547 return false;
548 }
549
550 QGlyphLayout glyphs;
551 glyphs.numGlyphs = *numGlyphs;
552 glyphs.glyphs = glyphIndexes;
553 return d->fontEngine->stringToCMap(chars, numChars, &glyphs, numGlyphs, QFontEngine::GlyphIndicesOnly) >= 0;
554}
555
556/*!
557 \fn QList<QPointF> QRawFont::advancesForGlyphIndexes(const QList<quint32> &glyphIndexes, LayoutFlags layoutFlags) const
558 \since 5.1
559
560 Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances
561 give the distance from the position of a given glyph to where the next glyph should be drawn
562 to make it appear as if the two glyphs are unspaced. How the advances are calculated is
563 controlled by \a layoutFlags.
564
565 \note When \c KernedAdvances is requested, this function will apply kerning rules from the
566 TrueType table \c{KERN}, if this is available in the font. In many modern fonts, kerning is
567 handled through OpenType rules or AAT rules, which requires a full shaping step to be applied.
568 To get the results of fully shaping the text, use \l{QTextLayout}.
569
570 \sa QTextLine::horizontalAdvance(), QFontMetricsF::horizontalAdvance(), QTextLayout::glyphRuns()
571*/
572
573/*!
574 \fn QList<QPointF> QRawFont::advancesForGlyphIndexes(const QList<quint32> &glyphIndexes) const
575
576 \overload
577
578 Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances
579 give the distance from the position of a given glyph to where the next glyph should be drawn
580 to make it appear as if the two glyphs are unspaced. The advance of each glyph is calculated
581 separately.
582
583 \sa QTextLine::horizontalAdvance(), QFontMetricsF::horizontalAdvance()
584*/
585
586/*!
587 \since 5.1
588
589 Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances
590 give the distance from the position of a given glyph to where the next glyph should be drawn
591 to make it appear as if the two glyphs are unspaced. The glyph indexes are given with the
592 array \a glyphIndexes while the results are returned through \a advances, both of them must
593 have \a numGlyphs elements. How the advances are calculated is controlled by \a layoutFlags.
594
595 \note When \c KernedAdvances is requested, this function will apply kerning rules from the
596 TrueType table \c{KERN}, if this is available in the font. In many modern fonts, kerning is
597 handled through OpenType rules or AAT rules, which requires a full shaping step to be applied.
598 To get the results of fully shaping the text, use \l{QTextLayout}.
599
600 \sa QTextLine::horizontalAdvance(), QFontMetricsF::horizontalAdvance(), QTextLayout::glyphRuns()
601*/
602bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs, LayoutFlags layoutFlags) const
603{
604 if (!d->isValid() || numGlyphs <= 0)
605 return false;
606 Q_ASSERT(glyphIndexes && advances);
607
608 QVarLengthArray<QFixed> tmpAdvances(numGlyphs);
609
610 QGlyphLayout glyphs;
611 glyphs.glyphs = const_cast<glyph_t *>(glyphIndexes);
612 glyphs.numGlyphs = numGlyphs;
613 glyphs.advances = tmpAdvances.data();
614
615 bool design = layoutFlags & UseDesignMetrics;
616
617 d->fontEngine->recalcAdvances(&glyphs, design ? QFontEngine::DesignMetrics : QFontEngine::ShaperFlag(0));
618 if (layoutFlags & KernedAdvances)
619 d->fontEngine->doKerning(&glyphs, design ? QFontEngine::DesignMetrics : QFontEngine::ShaperFlag(0));
620
621 for (int i=0; i<numGlyphs; ++i)
622 advances[i] = QPointF(tmpAdvances[i].toReal(), 0.0);
623
624 return true;
625}
626
627/*!
628 \overload
629
630 Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances
631 give the distance from the position of a given glyph to where the next glyph should be drawn
632 to make it appear as if the two glyphs are unspaced. The glyph indexes are given with the
633 array \a glyphIndexes while the results are returned through \a advances, both of them must
634 have \a numGlyphs elements. The advance of each glyph is calculated separately
635
636 \sa QTextLine::horizontalAdvance(), QFontMetricsF::horizontalAdvance()
637*/
638bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const
639{
640 return QRawFont::advancesForGlyphIndexes(glyphIndexes, advances, numGlyphs, SeparateAdvances);
641}
642
643/*!
644 Returns the hinting preference used to construct this QRawFont.
645
646 \sa QFont::hintingPreference()
647*/
648QFont::HintingPreference QRawFont::hintingPreference() const
649{
650 return d->isValid() ? d->hintingPreference : QFont::PreferDefaultHinting;
651}
652
653/*!
654 \fn QByteArray QRawFont::fontTable(const char *tag) const
655 \overload fontTable(QFont::Tag)
656
657 The name must be a four-character string.
658*/
659
660/*!
661 \fn QByteArray QRawFont::fontTable(QFont::Tag tag) const
662 \since 6.7
663
664 Retrieves the sfnt table specified by \a tag from the underlying physical font,
665 or an empty byte array if no such table was found. The returned font table's byte order is
666 Big Endian, like the sfnt format specifies.
667*/
668QByteArray QRawFont::fontTable(const char *tag) const
669{
670 if (auto maybeTag = QFont::Tag::fromString(tag))
671 return fontTable(*maybeTag);
672 return QByteArray();
673}
674
675QByteArray QRawFont::fontTable(QFont::Tag tag) const
676{
677 if (!d->isValid())
678 return QByteArray();
679
680 return d->fontEngine->getSfntTable(tag.value());
681}
682
683/*!
684 Returns a list of writing systems supported by the font according to designer supplied
685 information in the font file. Please note that this does not guarantee support for a
686 specific unicode point in the font. You can use the supportsCharacter() to check support
687 for a single, specific character.
688
689 \note The list is determined based on the unicode ranges and codepage ranges set in the font's
690 OS/2 table and requires such a table to be present in the underlying font file.
691
692 \sa supportsCharacter()
693*/
694QList<QFontDatabase::WritingSystem> QRawFont::supportedWritingSystems() const
695{
696 QList<QFontDatabase::WritingSystem> writingSystems;
697 if (d->isValid()) {
698 QByteArray os2Table = fontTable("OS/2");
699 if (os2Table.size() > 86) {
700 const uchar * const data = reinterpret_cast<const uchar *>(os2Table.constData());
701 const uchar * const bigEndianUnicodeRanges = data + 42;
702 const uchar * const bigEndianCodepageRanges = data + 78;
703
704 quint32 unicodeRanges[4];
705 quint32 codepageRanges[2];
706
707 for (size_t i = 0; i < sizeof unicodeRanges / sizeof *unicodeRanges; ++i)
708 unicodeRanges[i] = qFromBigEndian<quint32>(bigEndianUnicodeRanges + i * sizeof(quint32));
709
710 for (size_t i = 0; i < sizeof codepageRanges / sizeof *codepageRanges; ++i)
711 codepageRanges[i] = qFromBigEndian<quint32>(bigEndianCodepageRanges + i * sizeof(quint32));
712
713 QSupportedWritingSystems ws = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRanges, codepageRanges);
714 for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
715 if (ws.supported(QFontDatabase::WritingSystem(i)))
716 writingSystems.append(QFontDatabase::WritingSystem(i));
717 }
718 }
719 }
720
721 return writingSystems;
722}
723
724/*!
725 Returns \c true if the font has a glyph that corresponds to the given \a character.
726
727 \sa supportedWritingSystems()
728*/
729bool QRawFont::supportsCharacter(QChar character) const
730{
731 return supportsCharacter(character.unicode());
732}
733
734/*!
735 \overload
736
737 Returns \c true if the font has a glyph that corresponds to the UCS-4 encoded character \a ucs4.
738
739 \sa supportedWritingSystems()
740*/
741bool QRawFont::supportsCharacter(uint ucs4) const
742{
743 return d->isValid() && d->fontEngine->canRender(ucs4);
744}
745
746// qfontdatabase.cpp
747extern int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem);
748
749/*!
750 Fetches the physical representation based on a \a font query. The physical font returned is
751 the font that will be preferred by Qt in order to display text in the selected \a writingSystem.
752
753 \warning This function is potentially expensive and should not be called in performance
754 sensitive code.
755*/
756QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writingSystem)
757{
758 QRawFont rawFont;
759 const QFontPrivate *font_d = QFontPrivate::get(font);
760 int script = qt_script_for_writing_system(writingSystem);
761 QFontEngine *fe = font_d->engineForScript(script);
762
763 if (fe != nullptr && fe->type() == QFontEngine::Multi) {
764 QFontEngineMulti *multiEngine = static_cast<QFontEngineMulti *>(fe);
765 fe = multiEngine->engine(0);
766
767 if (script > QChar::Script_Latin) {
768 // keep in sync with QFontEngineMulti::loadEngine()
769 QFontDef request(multiEngine->fontDef);
770 request.styleStrategy |= QFont::NoFontMerging;
771
772 if (QFontEngine *engine = QFontDatabasePrivate::findFont(request, script, true)) {
773 if (request.weight > QFont::Normal)
774 engine->fontDef.weight = request.weight;
775 if (request.style > QFont::StyleNormal)
776 engine->fontDef.style = request.style;
777 fe = engine;
778 }
779 }
780 Q_ASSERT(fe);
781 }
782
783 if (fe != nullptr) {
784 rawFont.d.data()->setFontEngine(fe);
785 rawFont.d.data()->hintingPreference = font.hintingPreference();
786 }
787 return rawFont;
788}
789
790/*!
791 Sets the pixel size with which this font should be rendered to \a pixelSize.
792*/
793void QRawFont::setPixelSize(qreal pixelSize)
794{
795 if (!d->isValid() || qFuzzyCompare(d->fontEngine->fontDef.pixelSize, pixelSize))
796 return;
797
798 d.detach();
799 d->setFontEngine(d->fontEngine->cloneWithSize(pixelSize));
800}
801
802/*!
803 \internal
804*/
805void QRawFontPrivate::loadFromData(const QByteArray &fontData, qreal pixelSize,
806 QFont::HintingPreference hintingPreference)
807{
808 Q_ASSERT(fontEngine == nullptr);
809
810 QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
811 setFontEngine(pfdb->fontEngine(fontData, pixelSize, hintingPreference));
812}
813
814/*!
815 Returns the smallest rectangle containing the glyph with the given \a glyphIndex.
816
817 \since 5.0
818*/
819QRectF QRawFont::boundingRect(quint32 glyphIndex) const
820{
821 if (!d->isValid())
822 return QRectF();
823
824 glyph_metrics_t gm = d->fontEngine->boundingBox(glyphIndex);
825 return QRectF(gm.x.toReal(), gm.y.toReal(), gm.width.toReal(), gm.height.toReal());
826}
827
828#endif // QT_NO_RAWFONT
829
830QT_END_NAMESPACE
Q_GUI_EXPORT int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem)
constexpr size_t qHash(const QSize &s, size_t seed=0) noexcept
Definition qsize.h:191