1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
44 #if !defined(QT_NO_RAWFONT)
47 #include "qrawfont_p.h"
49 #include <QtCore/qendian.h>
55 \brief The QRawFont class provides access to a single physical instance of a font.
62 \note QRawFont is a low level class. For most purposes QFont is a more appropriate class.
64 Most commonly, when presenting text in a user interface, the exact fonts used
65 to render the characters is to some extent unknown. This can be the case for several
66 reasons: For instance, the actual, physical fonts present on the target system could be
67 unexpected to the developers, or the text could contain user selected styles, sizes or
68 writing systems that are not supported by font chosen in the code.
70 Therefore, Qt's QFont class really represents a query for fonts. When text is interpreted,
71 Qt will do its best to match the text to the query, but depending on the support, different
72 fonts can be used behind the scenes.
74 For most use cases, this is both expected and necessary, as it minimizes the possibility of
75 text in the user interface being undisplayable. In some cases, however, more direct control
76 over the process might be useful. It is for these use cases the QRawFont class exists.
78 A QRawFont object represents a single, physical instance of a given font in a given pixel size.
79 I.e. in the typical case it represents a set of TrueType or OpenType font tables and uses a
80 user specified pixel size to convert metrics into logical pixel units. It can be used in
81 combination with the QGlyphRun class to draw specific glyph indexes at specific positions, and
82 also have accessors to some relevant data in the physical font.
84 QRawFont only provides support for the main font technologies: GDI and DirectWrite on Windows
85 platforms, FreeType on Linux platforms and CoreText on Mac OS X. For other
86 font back-ends, the APIs will be disabled.
88 QRawFont can be constructed in a number of ways:
90 \li It can be constructed by calling QTextLayout::glyphs() or QTextFragment::glyphs(). The
91 returned QGlyphs objects will contain QRawFont objects which represent the actual fonts
92 used to render each portion of the text.
93 \li It can be constructed by passing a QFont object to QRawFont::fromFont(). The function
94 will return a QRawFont object representing the font that will be selected as response to
95 the QFont query and the selected writing system.
96 \li It can be constructed by passing a file name or QByteArray directly to the QRawFont
97 constructor, or by calling loadFromFile() or loadFromData(). In this case, the
98 font will not be registered in QFontDatabase, and it will not be available as part of
99 regular font selection.
102 QRawFont is considered local to the thread in which it is constructed (either using a
103 constructor, or by calling loadFromData() or loadFromFile()). The QRawFont cannot be moved to a
104 different thread, but will have to be recreated in the thread in question.
106 \note For the requirement of caching glyph indexes and font selections for static text to avoid
107 reshaping and relayouting in the inner loop of an application, a better choice is the QStaticText
108 class, since it optimizes the memory cost of the cache and also provides the possibility of paint
109 engine specific caches for an additional speed-up.
113 \enum QRawFont::AntialiasingType
115 This enum represents the different ways a glyph can be rasterized in the function
118 \value PixelAntialiasing Will rasterize by measuring the coverage of the shape on whole pixels.
119 The returned image contains the alpha values of each pixel based on the coverage of
121 \value SubPixelAntialiasing Will rasterize by measuring the coverage of each subpixel,
122 returning a separate alpha value for each of the red, green and blue components of
127 Constructs an invalid QRawFont.
130 : d(new QRawFontPrivate)
135 Constructs a QRawFont representing the font contained in the file referenced
136 by \a fileName for the size (in pixels) given by \a pixelSize, and using the
137 hinting preference specified by \a hintingPreference.
139 \note The referenced file must contain a TrueType or OpenType font.
141 QRawFont::QRawFont(const QString &fileName,
143 QFont::HintingPreference hintingPreference)
144 : d(new QRawFontPrivate)
146 loadFromFile(fileName, pixelSize, hintingPreference);
150 Constructs a QRawFont representing the font contained in the supplied
151 \a fontData for the size (in pixels) given by \a pixelSize, and using the
152 hinting preference specified by \a hintingPreference.
154 \note The data must contain a TrueType or OpenType font.
156 QRawFont::QRawFont(const QByteArray &fontData,
158 QFont::HintingPreference hintingPreference)
159 : d(new QRawFontPrivate)
161 loadFromData(fontData, pixelSize, hintingPreference);
165 Creates a QRawFont which is a copy of \a other.
167 QRawFont::QRawFont(const QRawFont &other)
173 Destroys the QRawFont
175 QRawFont::~QRawFont()
180 Assigns \a other to this QRawFont.
182 QRawFont &QRawFont::operator=(const QRawFont &other)
189 Returns true if the QRawFont is valid and false otherwise.
191 bool QRawFont::isValid() const
197 Replaces the current QRawFont with the contents of the file referenced
198 by \a fileName for the size (in pixels) given by \a pixelSize, and using the
199 hinting preference specified by \a hintingPreference.
201 The file must reference a TrueType or OpenType font.
205 void QRawFont::loadFromFile(const QString &fileName,
207 QFont::HintingPreference hintingPreference)
209 QFile file(fileName);
210 if (file.open(QIODevice::ReadOnly))
211 loadFromData(file.readAll(), pixelSize, hintingPreference);
215 Replaces the current QRawFont with the font contained in the supplied
216 \a fontData for the size (in pixels) given by \a pixelSize, and using the
217 hinting preference specified by \a hintingPreference.
219 The \a fontData must contain a TrueType or OpenType font.
223 void QRawFont::loadFromData(const QByteArray &fontData,
225 QFont::HintingPreference hintingPreference)
229 d->hintingPreference = hintingPreference;
230 d->thread = QThread::currentThread();
231 d->platformLoadFromData(fontData, pixelSize, hintingPreference);
235 This function returns a rasterized image of the glyph at the given
236 \a glyphIndex in the underlying font, using the \a transform specified.
237 If the QRawFont is not valid, this function will return an invalid QImage.
239 If \a antialiasingType is set to QRawFont::SubPixelAntialiasing, then the resulting image will be
240 in QImage::Format_RGB32 and the RGB values of each pixel will represent the subpixel opacities of
241 the pixel in the rasterization of the glyph. Otherwise, the image will be in the format of
242 QImage::Format_Indexed8 and each pixel will contain the opacity of the pixel in the
245 \sa pathForGlyph(), QPainter::drawGlyphRun()
247 QImage QRawFont::alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialiasingType,
248 const QTransform &transform) const
253 if (antialiasingType == SubPixelAntialiasing)
254 return d->fontEngine->alphaRGBMapForGlyph(glyphIndex, QFixed(), transform);
256 return d->fontEngine->alphaMapForGlyph(glyphIndex, QFixed(), transform);
260 This function returns the shape of the glyph at a given \a glyphIndex in the underlying font
261 if the QRawFont is valid. Otherwise, it returns an empty QPainterPath.
263 The returned glyph will always be unhinted.
265 \sa alphaMapForGlyph(), QPainterPath::addText()
267 QPainterPath QRawFont::pathForGlyph(quint32 glyphIndex) const
270 return QPainterPath();
272 QFixedPoint position;
274 d->fontEngine->addGlyphsToPath(&glyphIndex, &position, 1, &path, 0);
279 Returns true if this QRawFont is equal to \a other. Otherwise, returns false.
281 bool QRawFont::operator==(const QRawFont &other) const
283 return d->fontEngine == other.d->fontEngine;
287 \fn bool QRawFont::operator!=(const QRawFont &other) const
289 Returns true if this QRawFont is not equal to \a other. Otherwise, returns false.
293 Returns the ascent of this QRawFont in pixel units.
295 \sa QFontMetricsF::ascent()
297 qreal QRawFont::ascent() const
299 return d->isValid() ? d->fontEngine->ascent().toReal() : 0.0;
303 Returns the descent of this QRawFont in pixel units.
305 \sa QFontMetricsF::descent()
307 qreal QRawFont::descent() const
309 return d->isValid() ? d->fontEngine->descent().toReal() : 0.0;
313 Returns the xHeight of this QRawFont in pixel units.
315 \sa QFontMetricsF::xHeight()
317 qreal QRawFont::xHeight() const
319 return d->isValid() ? d->fontEngine->xHeight().toReal() : 0.0;
323 Returns the leading of this QRawFont in pixel units.
325 \sa QFontMetricsF::leading()
327 qreal QRawFont::leading() const
329 return d->isValid() ? d->fontEngine->leading().toReal() : 0.0;
333 Returns the average character width of this QRawFont in pixel units.
335 \sa QFontMetricsF::averageCharWidth()
337 qreal QRawFont::averageCharWidth() const
339 return d->isValid() ? d->fontEngine->averageCharWidth().toReal() : 0.0;
343 Returns the width of the widest character in the font.
345 \sa QFontMetricsF::maxWidth()
347 qreal QRawFont::maxCharWidth() const
349 return d->isValid() ? d->fontEngine->maxCharWidth() : 0.0;
353 Returns the pixel size set for this QRawFont. The pixel size affects how glyphs are
354 rasterized, the size of glyphs returned by pathForGlyph(), and is used to convert
355 internal metrics from design units to logical pixel units.
359 qreal QRawFont::pixelSize() const
361 return d->isValid() ? d->fontEngine->fontDef.pixelSize : 0.0;
365 Returns the number of design units define the width and height of the em square
366 for this QRawFont. This value is used together with the pixel size when converting design metrics
367 to pixel units, as the internal metrics are specified in design units and the pixel size gives
368 the size of 1 em in pixels.
370 \sa pixelSize(), setPixelSize()
372 qreal QRawFont::unitsPerEm() const
374 return d->isValid() ? d->fontEngine->emSquareSize().toReal() : 0.0;
378 Returns the thickness for drawing lines (underline, overline, etc.)
379 along with text drawn in this font.
381 qreal QRawFont::lineThickness() const
386 return d->fontEngine->lineThickness().toReal();
390 Returns the position from baseline for drawing underlines below the text
391 rendered with this font.
393 qreal QRawFont::underlinePosition() const
398 return d->fontEngine->underlinePosition().toReal();
402 Returns the family name of this QRawFont.
404 QString QRawFont::familyName() const
406 return d->isValid() ? d->fontEngine->fontDef.family : QString();
410 Returns the style name of this QRawFont.
412 \sa QFont::styleName()
414 QString QRawFont::styleName() const
416 return d->isValid() ? d->fontEngine->fontDef.styleName : QString();
420 Returns the style of this QRawFont.
424 QFont::Style QRawFont::style() const
426 return d->isValid() ? QFont::Style(d->fontEngine->fontDef.style) : QFont::StyleNormal;
430 Returns the weight of this QRawFont.
434 int QRawFont::weight() const
436 return d->isValid() ? int(d->fontEngine->fontDef.weight) : -1;
440 Converts the string of unicode points given by \a text to glyph indexes
441 using the CMAP table in the underlying font, and returns a vector containing
444 Note that, in cases where there are other tables in the font that affect the
445 shaping of the text, the returned glyph indexes will not correctly represent
446 the rendering of the text. To get the correctly shaped text, you can use
447 QTextLayout to lay out and shape the text, then call QTextLayout::glyphs()
448 to get the set of glyph index list and QRawFont pairs.
450 \sa advancesForGlyphIndexes(), glyphIndexesForChars(), QGlyphRun, QTextLayout::glyphRuns(), QTextFragment::glyphRuns()
452 QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const
455 return QVector<quint32>();
457 int nglyphs = text.size();
458 QVarLengthGlyphLayoutArray glyphs(nglyphs);
459 if (!glyphIndexesForChars(text.data(), text.size(), glyphs.glyphs, &nglyphs)) {
460 glyphs.resize(nglyphs);
461 if (!glyphIndexesForChars(text.data(), text.size(), glyphs.glyphs, &nglyphs)) {
462 Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice");
463 return QVector<quint32>();
467 QVector<quint32> glyphIndexes;
468 for (int i=0; i<nglyphs; ++i)
469 glyphIndexes.append(glyphs.glyphs[i]);
475 Converts a string of unicode points to glyph indexes using the CMAP table in the
476 underlying font. The function works like glyphIndexesForString() except it take
477 an array (\a chars), the results will be returned though \a glyphIndexes array
478 and number of glyphs will be set in \a numGlyphs. The size of \a glyphIndexes array
479 must be at least \a numChars, if that's still not enough, this function will return
480 false, then you can resize \a glyphIndexes from the size returned in \a numGlyphs.
482 \sa glyphIndexesForString(), advancesForGlyphIndexes(), QGlyphs, QTextLayout::glyphs(), QTextFragment::glyphs()
484 bool QRawFont::glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const
490 glyphs.glyphs = glyphIndexes;
491 return d->fontEngine->stringToCMap(chars, numChars, &glyphs, numGlyphs, QTextEngine::GlyphIndicesOnly);
495 Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances
496 give the distance from the position of a given glyph to where the next glyph should be drawn
497 to make it appear as if the two glyphs are unspaced.
499 \sa QTextLine::horizontalAdvance(), QFontMetricsF::width()
501 QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const
504 return QVector<QPointF>();
506 int numGlyphs = glyphIndexes.size();
507 QVarLengthGlyphLayoutArray glyphs(numGlyphs);
508 memcpy(glyphs.glyphs, glyphIndexes.data(), numGlyphs * sizeof(quint32));
510 d->fontEngine->recalcAdvances(&glyphs, 0);
512 QVector<QPointF> advances;
513 for (int i=0; i<numGlyphs; ++i)
514 advances.append(QPointF(glyphs.advances_x[i].toReal(), glyphs.advances_y[i].toReal()));
520 Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances
521 give the distance from the position of a given glyph to where the next glyph should be drawn
522 to make it appear as if the two glyphs are unspaced. The glyph indexes are given with the
523 array \a glyphIndexes while the results are returned through \a advances, both of them must
524 have \a numGlyphs elements.
526 \sa QTextLine::horizontalAdvance(), QFontMetricsF::width()
528 bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const
534 glyphs.glyphs = const_cast<HB_Glyph *>(glyphIndexes);
535 glyphs.numGlyphs = numGlyphs;
536 QVarLengthArray<QFixed> advances_x(numGlyphs);
537 QVarLengthArray<QFixed> advances_y(numGlyphs);
538 glyphs.advances_x = advances_x.data();
539 glyphs.advances_y = advances_y.data();
541 d->fontEngine->recalcAdvances(&glyphs, 0);
543 for (int i=0; i<numGlyphs; ++i)
544 advances[i] = QPointF(glyphs.advances_x[i].toReal(), glyphs.advances_y[i].toReal());
550 Returns the hinting preference used to construct this QRawFont.
552 \sa QFont::hintingPreference()
554 QFont::HintingPreference QRawFont::hintingPreference() const
556 return d->isValid() ? d->hintingPreference : QFont::PreferDefaultHinting;
560 Retrieves the sfnt table named \a tagName from the underlying physical font, or an empty
561 byte array if no such table was found. The returned font table's byte order is Big Endian, like
562 the sfnt format specifies. The \a tagName must be four characters long and should be formatted
563 in the default endianness of the current platform.
565 QByteArray QRawFont::fontTable(const char *tagName) const
570 const quint32 *tagId = reinterpret_cast<const quint32 *>(tagName);
571 return d->fontEngine->getSfntTable(qToBigEndian(*tagId));
574 // From qfontdatabase.cpp
575 extern QList<QFontDatabase::WritingSystem> qt_determine_writing_systems_from_truetype_bits(quint32 unicodeRange[4], quint32 codePageRange[2]);
578 Returns a list of writing systems supported by the font according to designer supplied
579 information in the font file. Please note that this does not guarantee support for a
580 specific unicode point in the font. You can use the supportsCharacter() to check support
581 for a single, specific character.
583 \note The list is determined based on the unicode ranges and codepage ranges set in the font's
584 OS/2 table and requires such a table to be present in the underlying font file.
586 \sa supportsCharacter()
588 QList<QFontDatabase::WritingSystem> QRawFont::supportedWritingSystems() const
591 QByteArray os2Table = fontTable("OS/2");
592 if (os2Table.size() > 86) {
593 char *data = os2Table.data();
594 quint32 *bigEndianUnicodeRanges = reinterpret_cast<quint32 *>(data + 42);
595 quint32 *bigEndianCodepageRanges = reinterpret_cast<quint32 *>(data + 78);
597 quint32 unicodeRanges[4];
598 quint32 codepageRanges[2];
600 for (int i=0; i<4; ++i) {
602 codepageRanges[i] = qFromBigEndian(bigEndianCodepageRanges[i]);
603 unicodeRanges[i] = qFromBigEndian(bigEndianUnicodeRanges[i]);
606 return qt_determine_writing_systems_from_truetype_bits(unicodeRanges, codepageRanges);
610 return QList<QFontDatabase::WritingSystem>();
614 Returns true if the font has a glyph that corresponds to the given \a character.
616 \sa supportedWritingSystems()
618 bool QRawFont::supportsCharacter(QChar character) const
620 return d->isValid() && d->fontEngine->canRender(&character, 1);
626 Returns true if the font has a glyph that corresponds to the UCS-4 encoded character \a ucs4.
628 \sa supportedWritingSystems()
630 bool QRawFont::supportsCharacter(uint ucs4) const
632 return d->isValid() && d->fontEngine->canRender(ucs4);
636 extern int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem);
639 Fetches the physical representation based on a \a font query. The physical font returned is
640 the font that will be preferred by Qt in order to display text in the selected \a writingSystem.
642 \warning This function is potentially expensive and should not be called in performance
645 QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writingSystem)
648 QFontPrivate *font_d = QFontPrivate::get(font);
649 int script = qt_script_for_writing_system(writingSystem);
650 QFontEngine *fe = font_d->engineForScript(script);
652 if (fe != 0 && fe->type() == QFontEngine::Multi) {
653 QFontEngineMulti *multiEngine = static_cast<QFontEngineMulti *>(fe);
654 fe = multiEngine->engine(0);
656 multiEngine->loadEngine(0);
657 fe = multiEngine->engine(0);
662 rawFont.d.data()->fontEngine = fe;
663 rawFont.d.data()->fontEngine->ref.ref();
664 rawFont.d.data()->hintingPreference = font.hintingPreference();
670 Sets the pixel size with which this font should be rendered to \a pixelSize.
672 void QRawFont::setPixelSize(qreal pixelSize)
674 if (d->fontEngine == 0 || qFuzzyCompare(d->fontEngine->fontDef.pixelSize, pixelSize))
678 QFontEngine *oldFontEngine = d->fontEngine;
680 d->fontEngine = d->fontEngine->cloneWithSize(pixelSize);
681 if (d->fontEngine != 0)
682 d->fontEngine->ref.ref();
684 oldFontEngine->ref.deref();
685 if (oldFontEngine->cache_count == 0 && oldFontEngine->ref.load() == 0)
686 delete oldFontEngine;
692 void QRawFontPrivate::cleanUp()
695 if (fontEngine != 0) {
696 fontEngine->ref.deref();
697 if (fontEngine->cache_count == 0 && fontEngine->ref.load() == 0)
701 hintingPreference = QFont::PreferDefaultHinting;
705 Returns the smallest rectangle containing the glyph with the given \a glyphIndex.
709 QRectF QRawFont::boundingRect(quint32 glyphIndex) const
714 glyph_metrics_t gm = d->fontEngine->boundingBox(glyphIndex);
715 return QRectF(gm.x.toReal(), gm.y.toReal(), gm.width.toReal(), gm.height.toReal());
718 #endif // QT_NO_RAWFONT