1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtGui module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qabstractfontengine_qws.h"
43 #include "qabstractfontengine_p.h"
45 #include <private/qtextengine_p.h>
46 #include <private/qpaintengine_raster_p.h>
52 class QFontEngineInfoPrivate
55 inline QFontEngineInfoPrivate()
56 : pixelSize(0), weight(QFont::Normal), style(QFont::StyleNormal)
63 QList<QFontDatabase::WritingSystem> writingSystems;
67 \class QFontEngineInfo
69 \brief The QFontEngineInfo class describes a specific font provided by a font engine plugin.
75 QFontEngineInfo is used to describe a request of a font to a font engine plugin as well as to
76 describe the actual fonts a plugin provides.
78 \sa QAbstractFontEngine, QFontEnginePlugin
82 Constructs a new empty QFontEngineInfo.
84 QFontEngineInfo::QFontEngineInfo()
86 d = new QFontEngineInfoPrivate;
90 Constructs a new QFontEngineInfo with the specified \a family.
91 The resulting object represents a freely scalable font with normal
94 QFontEngineInfo::QFontEngineInfo(const QString &family)
96 d = new QFontEngineInfoPrivate;
101 Creates a new font engine info object with the same attributes as \a other.
103 QFontEngineInfo::QFontEngineInfo(const QFontEngineInfo &other)
104 : d(new QFontEngineInfoPrivate(*other.d))
109 Assigns \a other to this font engine info object, and returns a reference
112 QFontEngineInfo &QFontEngineInfo::operator=(const QFontEngineInfo &other)
119 Destroys this QFontEngineInfo object.
121 QFontEngineInfo::~QFontEngineInfo()
127 \property QFontEngineInfo::family
128 the family name of the font
131 void QFontEngineInfo::setFamily(const QString &family)
136 QString QFontEngineInfo::family() const
142 \property QFontEngineInfo::pixelSize
143 the pixel size of the font
145 A pixel size of 0 represents a freely scalable font.
148 void QFontEngineInfo::setPixelSize(qreal size)
153 qreal QFontEngineInfo::pixelSize() const
159 \property QFontEngineInfo::weight
160 the weight of the font
162 The value should be from the \l{QFont::Weight} enumeration.
165 void QFontEngineInfo::setWeight(int weight)
170 int QFontEngineInfo::weight() const
176 \property QFontEngineInfo::style
177 the style of the font
180 void QFontEngineInfo::setStyle(QFont::Style style)
185 QFont::Style QFontEngineInfo::style() const
191 \property QFontEngineInfo::writingSystems
192 the writing systems supported by the font
194 An empty list means that any writing system is supported.
197 QList<QFontDatabase::WritingSystem> QFontEngineInfo::writingSystems() const
199 return d->writingSystems;
202 void QFontEngineInfo::setWritingSystems(const QList<QFontDatabase::WritingSystem> &writingSystems)
204 d->writingSystems = writingSystems;
207 class QFontEnginePluginPrivate : public QObjectPrivate
209 Q_DECLARE_PUBLIC(QFontEnginePlugin)
215 \class QFontEnginePlugin
217 \brief The QFontEnginePlugin class is the base class for font engine factory plugins in Qt for Embedded Linux.
224 QFontEnginePlugin is provided by font engine plugins to create
225 instances of subclasses of QAbstractFontEngine.
227 The member functions create() and availableFontEngines() must be
230 \sa QAbstractFontEngine, QFontEngineInfo
234 Creates a font engine plugin that creates font engines with the
235 specified \a foundry and \a parent.
237 QFontEnginePlugin::QFontEnginePlugin(const QString &foundry, QObject *parent)
238 : QObject(*new QFontEnginePluginPrivate, parent)
240 Q_D(QFontEnginePlugin);
241 d->foundry = foundry;
245 Destroys this font engine plugin.
247 QFontEnginePlugin::~QFontEnginePlugin()
252 Returns a list of foundries the font engine plugin provides.
253 The default implementation returns the foundry specified with the constructor.
255 QStringList QFontEnginePlugin::keys() const
257 Q_D(const QFontEnginePlugin);
258 return QStringList(d->foundry);
262 \fn QAbstractFontEngine *QFontEnginePlugin::create(const QFontEngineInfo &info)
264 Implemented in subclasses to create a new font engine that provides a font that
269 \fn QList<QFontEngineInfo> QFontEnginePlugin::availableFontEngines() const
271 Implemented in subclasses to return a list of QFontEngineInfo objects that represents all font
272 engines the plugin can create.
275 class QAbstractFontEnginePrivate : public QObjectPrivate
277 Q_DECLARE_PUBLIC(QAbstractFontEngine)
281 //The <classname> class is|provides|contains|specifies...
283 \class QAbstractFontEngine
285 \brief The QAbstractFontEngine class is the base class for font engine plugins in Qt for Embedded Linux.
291 QAbstractFontEngine is implemented by font engine plugins through QFontEnginePlugin.
293 \sa QFontEnginePlugin, QFontEngineInfo
297 \enum QAbstractFontEngine::Capability
299 This enum describes the capabilities of a font engine.
301 \value CanRenderGlyphs_Gray The font engine can render individual glyphs into 8 bpp images.
302 \value CanRenderGlyphs_Mono The font engine can render individual glyphs into 1 bpp images.
303 \value CanRenderGlyphs The font engine can render individual glyphs into images.
304 \value CanOutlineGlyphs The font engine can convert glyphs to painter paths.
308 \enum QAbstractFontEngine::FontProperty
310 This enum describes the properties of a font provided by a font engine.
312 \value Ascent The ascent of the font, specified as a 26.6 fixed point value.
313 \value Descent The descent of the font, specified as a 26.6 fixed point value.
314 \value Leading The leading of the font, specified as a 26.6 fixed point value.
315 \value XHeight The 'x' height of the font, specified as a 26.6 fixed point value.
316 \value AverageCharWidth The average character width of the font, specified as a 26.6 fixed point value.
317 \value LineThickness The thickness of the underline and strikeout lines for the font, specified as a 26.6 fixed point value.
318 \value UnderlinePosition The distance from the base line to the underline position for the font, specified as a 26.6 fixed point value.
319 \value MaxCharWidth The width of the widest character in the font, specified as a 26.6 fixed point value.
320 \value MinLeftBearing The minimum left bearing of the font, specified as a 26.6 fixed point value.
321 \value MinRightBearing The maximum right bearing of the font, specified as a 26.6 fixed point value.
322 \value GlyphCount The number of glyphs in the font, specified as an integer value.
323 \value CacheGlyphsHint A boolean value specifying whether rendered glyphs should be cached by Qt.
324 \value OutlineGlyphsHint A boolean value specifying whether the font engine prefers outline drawing over image rendering for uncached glyphs.
328 \enum QAbstractFontEngine::TextShapingFlag
330 This enum describes flags controlling conversion of characters to glyphs and their metrics.
332 \value RightToLeft The text is used in a right-to-left context.
333 \value ReturnDesignMetrics Return font design metrics instead of pixel metrics.
337 \typedef QAbstractFontEngine::Fixed
339 This type is \c int, interpreted as a 26.6 fixed point value.
343 \class QAbstractFontEngine::GlyphMetrics
344 \brief QAbstractFontEngine::GlyphMetrics defines the metrics of a single glyph.
350 \variable QAbstractFontEngine::GlyphMetrics::x
352 The horizontal offset from the origin.
356 \fn QAbstractFontEngine::GlyphMetrics::GlyphMetrics()
358 Constructs an empty glyph metrics object with all values
363 \variable QAbstractFontEngine::GlyphMetrics::y
365 The vertical offset from the origin (baseline).
369 \variable QAbstractFontEngine::GlyphMetrics::width
371 The width of the glyph.
375 \variable QAbstractFontEngine::GlyphMetrics::height
377 The height of the glyph.
381 \variable QAbstractFontEngine::GlyphMetrics::advance
383 The advance of the glyph.
387 \class QAbstractFontEngine::FixedPoint
388 \brief QAbstractFontEngine::FixedPoint defines a point in the place using 26.6 fixed point precision.
394 \variable QAbstractFontEngine::FixedPoint::x
396 The x coordinate of this point.
400 \variable QAbstractFontEngine::FixedPoint::y
402 The y coordinate of this point.
406 Constructs a new QAbstractFontEngine with the given \a parent.
408 QAbstractFontEngine::QAbstractFontEngine(QObject *parent)
409 : QObject(*new QAbstractFontEnginePrivate, parent)
414 Destroys this QAbstractFontEngine object.
416 QAbstractFontEngine::~QAbstractFontEngine()
421 \fn QAbstractFontEngine::Capabilities QAbstractFontEngine::capabilities() const
423 Implemented in subclasses to specify the font engine's capabilities. The return value
424 may be cached by the caller and is expected not to change during the lifetime of the
429 \fn QVariant QAbstractFontEngine::fontProperty(FontProperty property) const
431 Implemented in subclasses to return the value of the font attribute \a property. The return
432 value may be cached by the caller and is expected not to change during the lifetime of the font
437 \fn bool QAbstractFontEngine::convertStringToGlyphIndices(const QChar *string, int length, uint *glyphs, int *numGlyphs, TextShapingFlags flags) const
439 Implemented in subclasses to convert the characters specified by \a string and \a length to
440 glyph indicies, using \a flags. The glyph indicies should be returned in the \a glyphs array
441 provided by the caller. The maximum size of \a glyphs is specified by the value pointed to by \a
442 numGlyphs. If successful, the subclass implementation sets the value pointed to by \a numGlyphs
443 to the actual number of glyph indices generated, and returns true. Otherwise, e.g. if there is
444 not enough space in the provided \a glyphs array, it should set \a numGlyphs to the number of
445 glyphs needed for the conversion and return false.
449 \fn void QAbstractFontEngine::getGlyphAdvances(const uint *glyphs, int numGlyphs, Fixed *advances, TextShapingFlags flags) const
451 Implemented in subclasses to retrieve the advances of the array specified by \a glyphs and \a
452 numGlyphs, using \a flags. The result is returned in \a advances, which is allocated by the
453 caller and contains \a numGlyphs elements.
457 \fn QAbstractFontEngine::GlyphMetrics QAbstractFontEngine::glyphMetrics(uint glyph) const
459 Implemented in subclass to return the metrics for \a glyph.
463 Implemented in subclasses to render the specified \a glyph into a \a buffer with the given \a depth ,
464 \a bytesPerLine and \a height.
466 Returns true if rendering succeeded, false otherwise.
468 bool QAbstractFontEngine::renderGlyph(uint glyph, int depth, int bytesPerLine, int height, uchar *buffer)
472 Q_UNUSED(bytesPerLine)
475 qWarning("QAbstractFontEngine: renderGlyph is not implemented in font plugin!");
480 Implemented in subclasses to add the outline of the glyphs specified by \a glyphs and \a
481 numGlyphs at the specified \a positions to the painter path \a path.
483 void QAbstractFontEngine::addGlyphOutlinesToPath(uint *glyphs, int numGlyphs, FixedPoint *positions, QPainterPath *path)
489 qWarning("QAbstractFontEngine: addGlyphOutlinesToPath is not implemented in font plugin!");
493 bool QAbstractFontEngine::supportsExtension(Extension extension) const
499 QVariant QAbstractFontEngine::extension(Extension extension, const QVariant &argument)
507 QProxyFontEngine::QProxyFontEngine(QAbstractFontEngine *customEngine, const QFontDef &def)
508 : engine(customEngine)
511 engineCapabilities = engine->capabilities();
514 QProxyFontEngine::~QProxyFontEngine()
519 bool QProxyFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
521 if (*nglyphs < len) {
526 QVarLengthArray<uint> glyphIndicies(*nglyphs);
527 if (!engine->convertStringToGlyphIndices(str, len, glyphIndicies.data(), nglyphs, QAbstractFontEngine::TextShapingFlags(int(flags))))
530 // ### use memcopy instead
531 for (int i = 0; i < *nglyphs; ++i) {
532 glyphs->glyphs[i] = glyphIndicies[i];
534 glyphs->numGlyphs = *nglyphs;
536 recalcAdvances(glyphs, flags);
540 void QProxyFontEngine::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
542 const int nglyphs = glyphs->numGlyphs;
544 QVarLengthArray<QAbstractFontEngine::Fixed> advances(nglyphs);
545 engine->getGlyphAdvances(glyphs->glyphs, nglyphs, advances.data(), QAbstractFontEngine::TextShapingFlags(int(flags)));
548 // ### use memcopy instead
549 for (int i = 0; i < nglyphs; ++i) {
550 glyphs->advances_x[i] = QFixed::fromFixed(advances[i]);
551 glyphs->advances_y[i] = 0;
556 static QImage alphaMapFromPath(QFontEngine *fe, glyph_t glyph)
558 glyph_metrics_t gm = fe->boundingBox(glyph);
559 int glyph_x = qFloor(gm.x.toReal());
560 int glyph_y = qFloor(gm.y.toReal());
561 int glyph_width = qCeil((gm.x + gm.width).toReal()) - glyph_x;
562 int glyph_height = qCeil((gm.y + gm.height).toReal()) - glyph_y;
564 if (glyph_width <= 0 || glyph_height <= 0)
568 pt.y = -glyph_y; // the baseline
570 QImage im(glyph_width + qAbs(glyph_x) + 4, glyph_height, QImage::Format_ARGB32_Premultiplied);
571 im.fill(Qt::transparent);
573 p.setRenderHint(QPainter::Antialiasing);
574 fe->addGlyphsToPath(&glyph, &pt, 1, &path, 0);
576 p.setBrush(Qt::black);
580 QImage indexed(im.width(), im.height(), QImage::Format_Indexed8);
581 QVector<QRgb> colors(256);
582 for (int i=0; i<256; ++i)
583 colors[i] = qRgba(0, 0, 0, i);
584 indexed.setColorTable(colors);
586 for (int y=0; y<im.height(); ++y) {
587 uchar *dst = (uchar *) indexed.scanLine(y);
588 uint *src = (uint *) im.scanLine(y);
589 for (int x=0; x<im.width(); ++x)
590 dst[x] = qAlpha(src[x]);
597 QImage QProxyFontEngine::alphaMapForGlyph(glyph_t glyph)
599 if (!(engineCapabilities & QAbstractFontEngine::CanRenderGlyphs_Gray))
600 return alphaMapFromPath(this, glyph);
602 QAbstractFontEngine::GlyphMetrics metrics = engine->glyphMetrics(glyph);
603 if (metrics.width <= 0 || metrics.height <= 0)
606 QImage img(metrics.width >> 6, metrics.height >> 6, QImage::Format_Indexed8);
608 // ### we should have QImage::Format_GrayScale8
609 static QVector<QRgb> colorMap;
610 if (colorMap.isEmpty()) {
611 colorMap.resize(256);
612 for (int i=0; i<256; ++i)
613 colorMap[i] = qRgba(0, 0, 0, i);
616 img.setColorTable(colorMap);
618 engine->renderGlyph(glyph, /*depth*/8, img.bytesPerLine(), img.height(), img.bits());
623 void QProxyFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs, QPainterPath *path, QTextItem::RenderFlags flags)
625 if (engineCapabilities & QAbstractFontEngine::CanOutlineGlyphs)
626 engine->addGlyphOutlinesToPath(glyphs, nglyphs, reinterpret_cast<QAbstractFontEngine::FixedPoint *>(positions), path);
628 QFontEngine::addGlyphsToPath(glyphs, positions, nglyphs, path, flags);
631 glyph_metrics_t QProxyFontEngine::boundingBox(const QGlyphLayout &glyphs)
633 if (glyphs.numGlyphs == 0)
634 return glyph_metrics_t();
637 for (int i = 0; i < glyphs.numGlyphs; ++i)
638 w += glyphs.effectiveAdvance(i);
640 return glyph_metrics_t(0, -ascent(), w, ascent() + descent(), w, 0);
643 glyph_metrics_t QProxyFontEngine::boundingBox(glyph_t glyph)
647 QAbstractFontEngine::GlyphMetrics metrics = engine->glyphMetrics(glyph);
648 m.x = QFixed::fromFixed(metrics.x);
649 m.y = QFixed::fromFixed(metrics.y);
650 m.width = QFixed::fromFixed(metrics.width);
651 m.height = QFixed::fromFixed(metrics.height);
652 m.xoff = QFixed::fromFixed(metrics.advance);
657 QFixed QProxyFontEngine::ascent() const
659 return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::Ascent).toInt());
662 QFixed QProxyFontEngine::descent() const
664 return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::Descent).toInt());
667 QFixed QProxyFontEngine::leading() const
669 return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::Leading).toInt());
672 QFixed QProxyFontEngine::xHeight() const
674 return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::XHeight).toInt());
677 QFixed QProxyFontEngine::averageCharWidth() const
679 return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::AverageCharWidth).toInt());
682 QFixed QProxyFontEngine::lineThickness() const
684 return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::LineThickness).toInt());
687 QFixed QProxyFontEngine::underlinePosition() const
689 return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::UnderlinePosition).toInt());
692 qreal QProxyFontEngine::maxCharWidth() const
694 return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::MaxCharWidth).toInt()).toReal();
697 qreal QProxyFontEngine::minLeftBearing() const
699 return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::MinLeftBearing).toInt()).toReal();
702 qreal QProxyFontEngine::minRightBearing() const
704 return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::MinRightBearing).toInt()).toReal();
707 int QProxyFontEngine::glyphCount() const
709 return engine->fontProperty(QAbstractFontEngine::GlyphCount).toInt();
712 bool QProxyFontEngine::canRender(const QChar *string, int len)
714 QVarLengthArray<uint> glyphs(len);
717 if (!engine->convertStringToGlyphIndices(string, len, glyphs.data(), &numGlyphs, /*flags*/0))
720 for (int i = 0; i < numGlyphs; ++i)
727 void QProxyFontEngine::draw(QPaintEngine *p, qreal _x, qreal _y, const QTextItemInt &si)
729 QPaintEngineState *pState = p->state;
730 QRasterPaintEngine *paintEngine = static_cast<QRasterPaintEngine*>(p);
732 QTransform matrix = pState->transform();
733 matrix.translate(_x, _y);
734 QFixed x = QFixed::fromReal(matrix.dx());
735 QFixed y = QFixed::fromReal(matrix.dy());
737 QVarLengthArray<QFixedPoint> positions;
738 QVarLengthArray<glyph_t> glyphs;
739 getGlyphPositions(si.glyphs, matrix, si.flags, glyphs, positions);
740 if (glyphs.size() == 0)
743 for(int i = 0; i < glyphs.size(); i++) {
744 QImage glyph = alphaMapForGlyph(glyphs[i]);
748 if (glyph.format() != QImage::Format_Indexed8
749 && glyph.format() != QImage::Format_Mono)
752 QAbstractFontEngine::GlyphMetrics metrics = engine->glyphMetrics(glyphs[i]);
754 int depth = glyph.format() == QImage::Format_Mono ? 1 : 8;
755 paintEngine->alphaPenBlt(glyph.bits(), glyph.bytesPerLine(), depth,
756 qRound(positions[i].x + QFixed::fromFixed(metrics.x)),
757 qRound(positions[i].y + QFixed::fromFixed(metrics.y)),
758 glyph.width(), glyph.height());
763 * This is only called when we use the proxy fontengine directly (without sharing the rendered
764 * glyphs). So we prefer outline rendering over rendering of unshared glyphs. That decision is
765 * done in qfontdatabase_qws.cpp by looking at the ShareGlyphsHint and the pixel size of the font.
767 bool QProxyFontEngine::drawAsOutline() const
769 if (!(engineCapabilities & QAbstractFontEngine::CanOutlineGlyphs))
772 QVariant outlineHint = engine->fontProperty(QAbstractFontEngine::OutlineGlyphsHint);
773 return !outlineHint.isValid() || outlineHint.toBool();