summaryrefslogtreecommitdiffstats
path: root/src/gui/text
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/text')
-rw-r--r--src/gui/text/qabstractfontengine_qws.cpp776
-rw-r--r--src/gui/text/qabstractfontengine_qws.h221
-rw-r--r--src/gui/text/qabstracttextdocumentlayout.h1
-rw-r--r--src/gui/text/qcssparser.cpp6
-rw-r--r--src/gui/text/qcssparser_p.h14
-rw-r--r--src/gui/text/qfont.cpp101
-rw-r--r--src/gui/text/qfont.h8
-rw-r--r--src/gui/text/qfont_mac.cpp166
-rw-r--r--src/gui/text/qfont_qpa.cpp6
-rw-r--r--src/gui/text/qfont_qws.cpp135
-rw-r--r--src/gui/text/qfont_s60.cpp136
-rw-r--r--src/gui/text/qfont_win.cpp166
-rw-r--r--src/gui/text/qfont_x11.cpp368
-rw-r--r--src/gui/text/qfontdatabase.cpp48
-rw-r--r--src/gui/text/qfontdatabase.h4
-rw-r--r--src/gui/text/qfontdatabase_mac.cpp494
-rw-r--r--src/gui/text/qfontdatabase_qpa.cpp31
-rw-r--r--src/gui/text/qfontdatabase_qws.cpp972
-rw-r--r--src/gui/text/qfontdatabase_s60.cpp1099
-rw-r--r--src/gui/text/qfontdatabase_win.cpp1348
-rw-r--r--src/gui/text/qfontdatabase_x11.cpp2154
-rw-r--r--src/gui/text/qfontengine.cpp37
-rw-r--r--src/gui/text/qfontengine_coretext.mm870
-rw-r--r--src/gui/text/qfontengine_coretext_p.h153
-rw-r--r--src/gui/text/qfontengine_ft_p.h2
-rw-r--r--src/gui/text/qfontengine_mac.mm1236
-rw-r--r--src/gui/text/qfontengine_mac_p.h165
-rw-r--r--src/gui/text/qfontengine_p.h6
-rw-r--r--src/gui/text/qfontengine_qpa.cpp3
-rw-r--r--src/gui/text/qfontengine_qws.cpp665
-rw-r--r--src/gui/text/qfontengine_s60.cpp569
-rw-r--r--src/gui/text/qfontengine_s60_p.h167
-rw-r--r--src/gui/text/qfontengine_win.cpp1339
-rw-r--r--src/gui/text/qfontengine_win_p.h164
-rw-r--r--src/gui/text/qfontengine_x11.cpp1205
-rw-r--r--src/gui/text/qfontengine_x11_p.h180
-rw-r--r--src/gui/text/qfontmetrics.h9
-rw-r--r--src/gui/text/qfontsubset.cpp249
-rw-r--r--src/gui/text/qfontsubset_p.h6
-rw-r--r--src/gui/text/qlinecontrol.cpp1711
-rw-r--r--src/gui/text/qlinecontrol_p.h455
-rw-r--r--src/gui/text/qplatformfontdatabase_qpa.cpp24
-rw-r--r--src/gui/text/qplatformfontdatabase_qpa.h4
-rw-r--r--src/gui/text/qrawfont_mac.cpp83
-rw-r--r--src/gui/text/qrawfont_qpa.cpp4
-rw-r--r--src/gui/text/qrawfont_win.cpp709
-rw-r--r--src/gui/text/qstatictext.cpp2
-rw-r--r--src/gui/text/qsyntaxhighlighter.cpp21
-rw-r--r--src/gui/text/qsyntaxhighlighter.h2
-rw-r--r--src/gui/text/qtextcontrol.cpp451
-rw-r--r--src/gui/text/qtextcontrol_p.h51
-rw-r--r--src/gui/text/qtextcontrol_p_p.h12
-rw-r--r--src/gui/text/qtextcursor.h3
-rw-r--r--src/gui/text/qtextcursor_p.h4
-rw-r--r--src/gui/text/qtextdocument.cpp119
-rw-r--r--src/gui/text/qtextdocument.h6
-rw-r--r--src/gui/text/qtextdocumentlayout.cpp4
-rw-r--r--src/gui/text/qtextdocumentlayout_p.h2
-rw-r--r--src/gui/text/qtextengine.cpp4
-rw-r--r--src/gui/text/qtextengine_mac.cpp656
-rw-r--r--src/gui/text/qtextengine_p.h6
-rw-r--r--src/gui/text/qtexthtmlparser.cpp6
-rw-r--r--src/gui/text/qtextimagehandler.cpp14
-rw-r--r--src/gui/text/qtextlayout.cpp2
-rw-r--r--src/gui/text/qtextoption.cpp4
-rw-r--r--src/gui/text/text.pri36
66 files changed, 2504 insertions, 17170 deletions
diff --git a/src/gui/text/qabstractfontengine_qws.cpp b/src/gui/text/qabstractfontengine_qws.cpp
deleted file mode 100644
index b2c9cc478a..0000000000
--- a/src/gui/text/qabstractfontengine_qws.cpp
+++ /dev/null
@@ -1,776 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qabstractfontengine_qws.h"
-#include "qabstractfontengine_p.h"
-
-#include <private/qtextengine_p.h>
-#include <private/qpaintengine_raster_p.h>
-
-#include <qmath.h>
-
-QT_BEGIN_NAMESPACE
-
-class QFontEngineInfoPrivate
-{
-public:
- inline QFontEngineInfoPrivate()
- : pixelSize(0), weight(QFont::Normal), style(QFont::StyleNormal)
- {}
-
- QString family;
- qreal pixelSize;
- int weight;
- QFont::Style style;
- QList<QFontDatabase::WritingSystem> writingSystems;
-};
-
-/*!
- \class QFontEngineInfo
- \preliminary
- \brief The QFontEngineInfo class describes a specific font provided by a font engine plugin.
- \since 4.3
- \ingroup qws
-
- \tableofcontents
-
- QFontEngineInfo is used to describe a request of a font to a font engine plugin as well as to
- describe the actual fonts a plugin provides.
-
- \sa QAbstractFontEngine, QFontEnginePlugin
-*/
-
-/*!
- Constructs a new empty QFontEngineInfo.
-*/
-QFontEngineInfo::QFontEngineInfo()
-{
- d = new QFontEngineInfoPrivate;
-}
-
-/*!
- Constructs a new QFontEngineInfo with the specified \a family.
- The resulting object represents a freely scalable font with normal
- weight and style.
-*/
-QFontEngineInfo::QFontEngineInfo(const QString &family)
-{
- d = new QFontEngineInfoPrivate;
- d->family = family;
-}
-
-/*!
- Creates a new font engine info object with the same attributes as \a other.
-*/
-QFontEngineInfo::QFontEngineInfo(const QFontEngineInfo &other)
- : d(new QFontEngineInfoPrivate(*other.d))
-{
-}
-
-/*!
- Assigns \a other to this font engine info object, and returns a reference
- to this.
-*/
-QFontEngineInfo &QFontEngineInfo::operator=(const QFontEngineInfo &other)
-{
- *d = *other.d;
- return *this;
-}
-
-/*!
- Destroys this QFontEngineInfo object.
-*/
-QFontEngineInfo::~QFontEngineInfo()
-{
- delete d;
-}
-
-/*!
- \property QFontEngineInfo::family
- the family name of the font
-*/
-
-void QFontEngineInfo::setFamily(const QString &family)
-{
- d->family = family;
-}
-
-QString QFontEngineInfo::family() const
-{
- return d->family;
-}
-
-/*!
- \property QFontEngineInfo::pixelSize
- the pixel size of the font
-
- A pixel size of 0 represents a freely scalable font.
-*/
-
-void QFontEngineInfo::setPixelSize(qreal size)
-{
- d->pixelSize = size;
-}
-
-qreal QFontEngineInfo::pixelSize() const
-{
- return d->pixelSize;
-}
-
-/*!
- \property QFontEngineInfo::weight
- the weight of the font
-
- The value should be from the \l{QFont::Weight} enumeration.
-*/
-
-void QFontEngineInfo::setWeight(int weight)
-{
- d->weight = weight;
-}
-
-int QFontEngineInfo::weight() const
-{
- return d->weight;
-}
-
-/*!
- \property QFontEngineInfo::style
- the style of the font
-*/
-
-void QFontEngineInfo::setStyle(QFont::Style style)
-{
- d->style = style;
-}
-
-QFont::Style QFontEngineInfo::style() const
-{
- return d->style;
-}
-
-/*!
- \property QFontEngineInfo::writingSystems
- the writing systems supported by the font
-
- An empty list means that any writing system is supported.
-*/
-
-QList<QFontDatabase::WritingSystem> QFontEngineInfo::writingSystems() const
-{
- return d->writingSystems;
-}
-
-void QFontEngineInfo::setWritingSystems(const QList<QFontDatabase::WritingSystem> &writingSystems)
-{
- d->writingSystems = writingSystems;
-}
-
-class QFontEnginePluginPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QFontEnginePlugin)
-
- QString foundry;
-};
-
-/*!
- \class QFontEnginePlugin
- \preliminary
- \brief The QFontEnginePlugin class is the base class for font engine factory plugins in Qt for Embedded Linux.
- \since 4.3
- \ingroup qws
- \ingroup plugins
-
- \tableofcontents
-
- QFontEnginePlugin is provided by font engine plugins to create
- instances of subclasses of QAbstractFontEngine.
-
- The member functions create() and availableFontEngines() must be
- implemented.
-
- \sa QAbstractFontEngine, QFontEngineInfo
-*/
-
-/*!
- Creates a font engine plugin that creates font engines with the
- specified \a foundry and \a parent.
-*/
-QFontEnginePlugin::QFontEnginePlugin(const QString &foundry, QObject *parent)
- : QObject(*new QFontEnginePluginPrivate, parent)
-{
- Q_D(QFontEnginePlugin);
- d->foundry = foundry;
-}
-
-/*!
- Destroys this font engine plugin.
-*/
-QFontEnginePlugin::~QFontEnginePlugin()
-{
-}
-
-/*!
- Returns a list of foundries the font engine plugin provides.
- The default implementation returns the foundry specified with the constructor.
-*/
-QStringList QFontEnginePlugin::keys() const
-{
- Q_D(const QFontEnginePlugin);
- return QStringList(d->foundry);
-}
-
-/*!
- \fn QAbstractFontEngine *QFontEnginePlugin::create(const QFontEngineInfo &info)
-
- Implemented in subclasses to create a new font engine that provides a font that
- matches \a info.
-*/
-
-/*!
- \fn QList<QFontEngineInfo> QFontEnginePlugin::availableFontEngines() const
-
- Implemented in subclasses to return a list of QFontEngineInfo objects that represents all font
- engines the plugin can create.
-*/
-
-class QAbstractFontEnginePrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QAbstractFontEngine)
-public:
-};
-
-//The <classname> class is|provides|contains|specifies...
-/*!
- \class QAbstractFontEngine
- \preliminary
- \brief The QAbstractFontEngine class is the base class for font engine plugins in Qt for Embedded Linux.
- \since 4.3
- \ingroup qws
-
- \tableofcontents
-
- QAbstractFontEngine is implemented by font engine plugins through QFontEnginePlugin.
-
- \sa QFontEnginePlugin, QFontEngineInfo
-*/
-
-/*!
- \enum QAbstractFontEngine::Capability
-
- This enum describes the capabilities of a font engine.
-
- \value CanRenderGlyphs_Gray The font engine can render individual glyphs into 8 bpp images.
- \value CanRenderGlyphs_Mono The font engine can render individual glyphs into 1 bpp images.
- \value CanRenderGlyphs The font engine can render individual glyphs into images.
- \value CanOutlineGlyphs The font engine can convert glyphs to painter paths.
-*/
-
-/*!
- \enum QAbstractFontEngine::FontProperty
-
- This enum describes the properties of a font provided by a font engine.
-
- \value Ascent The ascent of the font, specified as a 26.6 fixed point value.
- \value Descent The descent of the font, specified as a 26.6 fixed point value.
- \value Leading The leading of the font, specified as a 26.6 fixed point value.
- \value XHeight The 'x' height of the font, specified as a 26.6 fixed point value.
- \value AverageCharWidth The average character width of the font, specified as a 26.6 fixed point value.
- \value LineThickness The thickness of the underline and strikeout lines for the font, specified as a 26.6 fixed point value.
- \value UnderlinePosition The distance from the base line to the underline position for the font, specified as a 26.6 fixed point value.
- \value MaxCharWidth The width of the widest character in the font, specified as a 26.6 fixed point value.
- \value MinLeftBearing The minimum left bearing of the font, specified as a 26.6 fixed point value.
- \value MinRightBearing The maximum right bearing of the font, specified as a 26.6 fixed point value.
- \value GlyphCount The number of glyphs in the font, specified as an integer value.
- \value CacheGlyphsHint A boolean value specifying whether rendered glyphs should be cached by Qt.
- \value OutlineGlyphsHint A boolean value specifying whether the font engine prefers outline drawing over image rendering for uncached glyphs.
-*/
-
-/*!
- \enum QAbstractFontEngine::TextShapingFlag
-
- This enum describes flags controlling conversion of characters to glyphs and their metrics.
-
- \value RightToLeft The text is used in a right-to-left context.
- \value ReturnDesignMetrics Return font design metrics instead of pixel metrics.
-*/
-
-/*!
- \typedef QAbstractFontEngine::Fixed
-
- This type is \c int, interpreted as a 26.6 fixed point value.
-*/
-
-/*!
- \class QAbstractFontEngine::GlyphMetrics
- \brief QAbstractFontEngine::GlyphMetrics defines the metrics of a single glyph.
- \preliminary
- \since 4.3
-*/
-
-/*!
- \variable QAbstractFontEngine::GlyphMetrics::x
-
- The horizontal offset from the origin.
-*/
-
-/*!
- \fn QAbstractFontEngine::GlyphMetrics::GlyphMetrics()
-
- Constructs an empty glyph metrics object with all values
- set to zero.
-*/
-
-/*!
- \variable QAbstractFontEngine::GlyphMetrics::y
-
- The vertical offset from the origin (baseline).
-*/
-
-/*!
- \variable QAbstractFontEngine::GlyphMetrics::width
-
- The width of the glyph.
-*/
-
-/*!
- \variable QAbstractFontEngine::GlyphMetrics::height
-
- The height of the glyph.
-*/
-
-/*!
- \variable QAbstractFontEngine::GlyphMetrics::advance
-
- The advance of the glyph.
-*/
-
-/*!
- \class QAbstractFontEngine::FixedPoint
- \brief QAbstractFontEngine::FixedPoint defines a point in the place using 26.6 fixed point precision.
- \preliminary
- \since 4.3
-*/
-
-/*!
- \variable QAbstractFontEngine::FixedPoint::x
-
- The x coordinate of this point.
-*/
-
-/*!
- \variable QAbstractFontEngine::FixedPoint::y
-
- The y coordinate of this point.
-*/
-
-/*!
- Constructs a new QAbstractFontEngine with the given \a parent.
-*/
-QAbstractFontEngine::QAbstractFontEngine(QObject *parent)
- : QObject(*new QAbstractFontEnginePrivate, parent)
-{
-}
-
-/*!
- Destroys this QAbstractFontEngine object.
-*/
-QAbstractFontEngine::~QAbstractFontEngine()
-{
-}
-
-/*!
- \fn QAbstractFontEngine::Capabilities QAbstractFontEngine::capabilities() const
-
- Implemented in subclasses to specify the font engine's capabilities. The return value
- may be cached by the caller and is expected not to change during the lifetime of the
- font engine.
-*/
-
-/*!
- \fn QVariant QAbstractFontEngine::fontProperty(FontProperty property) const
-
- Implemented in subclasses to return the value of the font attribute \a property. The return
- value may be cached by the caller and is expected not to change during the lifetime of the font
- engine.
-*/
-
-/*!
- \fn bool QAbstractFontEngine::convertStringToGlyphIndices(const QChar *string, int length, uint *glyphs, int *numGlyphs, TextShapingFlags flags) const
-
- Implemented in subclasses to convert the characters specified by \a string and \a length to
- glyph indicies, using \a flags. The glyph indicies should be returned in the \a glyphs array
- provided by the caller. The maximum size of \a glyphs is specified by the value pointed to by \a
- numGlyphs. If successful, the subclass implementation sets the value pointed to by \a numGlyphs
- to the actual number of glyph indices generated, and returns true. Otherwise, e.g. if there is
- not enough space in the provided \a glyphs array, it should set \a numGlyphs to the number of
- glyphs needed for the conversion and return false.
-*/
-
-/*!
- \fn void QAbstractFontEngine::getGlyphAdvances(const uint *glyphs, int numGlyphs, Fixed *advances, TextShapingFlags flags) const
-
- Implemented in subclasses to retrieve the advances of the array specified by \a glyphs and \a
- numGlyphs, using \a flags. The result is returned in \a advances, which is allocated by the
- caller and contains \a numGlyphs elements.
-*/
-
-/*!
- \fn QAbstractFontEngine::GlyphMetrics QAbstractFontEngine::glyphMetrics(uint glyph) const
-
- Implemented in subclass to return the metrics for \a glyph.
-*/
-
-/*!
- Implemented in subclasses to render the specified \a glyph into a \a buffer with the given \a depth ,
- \a bytesPerLine and \a height.
-
- Returns true if rendering succeeded, false otherwise.
-*/
-bool QAbstractFontEngine::renderGlyph(uint glyph, int depth, int bytesPerLine, int height, uchar *buffer)
-{
- Q_UNUSED(glyph)
- Q_UNUSED(depth)
- Q_UNUSED(bytesPerLine)
- Q_UNUSED(height)
- Q_UNUSED(buffer)
- qWarning("QAbstractFontEngine: renderGlyph is not implemented in font plugin!");
- return false;
-}
-
-/*!
- Implemented in subclasses to add the outline of the glyphs specified by \a glyphs and \a
- numGlyphs at the specified \a positions to the painter path \a path.
-*/
-void QAbstractFontEngine::addGlyphOutlinesToPath(uint *glyphs, int numGlyphs, FixedPoint *positions, QPainterPath *path)
-{
- Q_UNUSED(glyphs)
- Q_UNUSED(numGlyphs)
- Q_UNUSED(positions)
- Q_UNUSED(path)
- qWarning("QAbstractFontEngine: addGlyphOutlinesToPath is not implemented in font plugin!");
-}
-
-/*
-bool QAbstractFontEngine::supportsExtension(Extension extension) const
-{
- Q_UNUSED(extension)
- return false;
-}
-
-QVariant QAbstractFontEngine::extension(Extension extension, const QVariant &argument)
-{
- Q_UNUSED(argument)
- Q_UNUSED(extension)
- return QVariant();
-}
-*/
-
-QProxyFontEngine::QProxyFontEngine(QAbstractFontEngine *customEngine, const QFontDef &def)
- : engine(customEngine)
-{
- fontDef = def;
- engineCapabilities = engine->capabilities();
-}
-
-QProxyFontEngine::~QProxyFontEngine()
-{
- delete engine;
-}
-
-bool QProxyFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
-{
- if (*nglyphs < len) {
- *nglyphs = len;
- return false;
- }
-
- QVarLengthArray<uint> glyphIndicies(*nglyphs);
- if (!engine->convertStringToGlyphIndices(str, len, glyphIndicies.data(), nglyphs, QAbstractFontEngine::TextShapingFlags(int(flags))))
- return false;
-
- // ### use memcopy instead
- for (int i = 0; i < *nglyphs; ++i) {
- glyphs->glyphs[i] = glyphIndicies[i];
- }
- glyphs->numGlyphs = *nglyphs;
-
- recalcAdvances(glyphs, flags);
- return true;
-}
-
-void QProxyFontEngine::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
-{
- const int nglyphs = glyphs->numGlyphs;
-
- QVarLengthArray<QAbstractFontEngine::Fixed> advances(nglyphs);
- engine->getGlyphAdvances(glyphs->glyphs, nglyphs, advances.data(), QAbstractFontEngine::TextShapingFlags(int(flags)));
-
-
- // ### use memcopy instead
- for (int i = 0; i < nglyphs; ++i) {
- glyphs->advances_x[i] = QFixed::fromFixed(advances[i]);
- glyphs->advances_y[i] = 0;
- }
-}
-
-
-static QImage alphaMapFromPath(QFontEngine *fe, glyph_t glyph)
-{
- glyph_metrics_t gm = fe->boundingBox(glyph);
- int glyph_x = qFloor(gm.x.toReal());
- int glyph_y = qFloor(gm.y.toReal());
- int glyph_width = qCeil((gm.x + gm.width).toReal()) - glyph_x;
- int glyph_height = qCeil((gm.y + gm.height).toReal()) - glyph_y;
-
- if (glyph_width <= 0 || glyph_height <= 0)
- return QImage();
- QFixedPoint pt;
- pt.x = 0;
- pt.y = -glyph_y; // the baseline
- QPainterPath path;
- QImage im(glyph_width + qAbs(glyph_x) + 4, glyph_height, QImage::Format_ARGB32_Premultiplied);
- im.fill(Qt::transparent);
- QPainter p(&im);
- p.setRenderHint(QPainter::Antialiasing);
- fe->addGlyphsToPath(&glyph, &pt, 1, &path, 0);
- p.setPen(Qt::NoPen);
- p.setBrush(Qt::black);
- p.drawPath(path);
- p.end();
-
- QImage indexed(im.width(), im.height(), QImage::Format_Indexed8);
- QVector<QRgb> colors(256);
- for (int i=0; i<256; ++i)
- colors[i] = qRgba(0, 0, 0, i);
- indexed.setColorTable(colors);
-
- for (int y=0; y<im.height(); ++y) {
- uchar *dst = (uchar *) indexed.scanLine(y);
- uint *src = (uint *) im.scanLine(y);
- for (int x=0; x<im.width(); ++x)
- dst[x] = qAlpha(src[x]);
- }
-
- return indexed;
-}
-
-
-QImage QProxyFontEngine::alphaMapForGlyph(glyph_t glyph)
-{
- if (!(engineCapabilities & QAbstractFontEngine::CanRenderGlyphs_Gray))
- return alphaMapFromPath(this, glyph);
-
- QAbstractFontEngine::GlyphMetrics metrics = engine->glyphMetrics(glyph);
- if (metrics.width <= 0 || metrics.height <= 0)
- return QImage();
-
- QImage img(metrics.width >> 6, metrics.height >> 6, QImage::Format_Indexed8);
-
- // ### we should have QImage::Format_GrayScale8
- static QVector<QRgb> colorMap;
- if (colorMap.isEmpty()) {
- colorMap.resize(256);
- for (int i=0; i<256; ++i)
- colorMap[i] = qRgba(0, 0, 0, i);
- }
-
- img.setColorTable(colorMap);
-
- engine->renderGlyph(glyph, /*depth*/8, img.bytesPerLine(), img.height(), img.bits());
-
- return img;
-}
-
-void QProxyFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs, QPainterPath *path, QTextItem::RenderFlags flags)
-{
- if (engineCapabilities & QAbstractFontEngine::CanOutlineGlyphs)
- engine->addGlyphOutlinesToPath(glyphs, nglyphs, reinterpret_cast<QAbstractFontEngine::FixedPoint *>(positions), path);
- else
- QFontEngine::addGlyphsToPath(glyphs, positions, nglyphs, path, flags);
-}
-
-glyph_metrics_t QProxyFontEngine::boundingBox(const QGlyphLayout &glyphs)
-{
- if (glyphs.numGlyphs == 0)
- return glyph_metrics_t();
-
- QFixed w = 0;
- for (int i = 0; i < glyphs.numGlyphs; ++i)
- w += glyphs.effectiveAdvance(i);
-
- return glyph_metrics_t(0, -ascent(), w, ascent() + descent(), w, 0);
-}
-
-glyph_metrics_t QProxyFontEngine::boundingBox(glyph_t glyph)
-{
- glyph_metrics_t m;
-
- QAbstractFontEngine::GlyphMetrics metrics = engine->glyphMetrics(glyph);
- m.x = QFixed::fromFixed(metrics.x);
- m.y = QFixed::fromFixed(metrics.y);
- m.width = QFixed::fromFixed(metrics.width);
- m.height = QFixed::fromFixed(metrics.height);
- m.xoff = QFixed::fromFixed(metrics.advance);
-
- return m;
-}
-
-QFixed QProxyFontEngine::ascent() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::Ascent).toInt());
-}
-
-QFixed QProxyFontEngine::descent() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::Descent).toInt());
-}
-
-QFixed QProxyFontEngine::leading() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::Leading).toInt());
-}
-
-QFixed QProxyFontEngine::xHeight() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::XHeight).toInt());
-}
-
-QFixed QProxyFontEngine::averageCharWidth() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::AverageCharWidth).toInt());
-}
-
-QFixed QProxyFontEngine::lineThickness() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::LineThickness).toInt());
-}
-
-QFixed QProxyFontEngine::underlinePosition() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::UnderlinePosition).toInt());
-}
-
-qreal QProxyFontEngine::maxCharWidth() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::MaxCharWidth).toInt()).toReal();
-}
-
-qreal QProxyFontEngine::minLeftBearing() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::MinLeftBearing).toInt()).toReal();
-}
-
-qreal QProxyFontEngine::minRightBearing() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::MinRightBearing).toInt()).toReal();
-}
-
-int QProxyFontEngine::glyphCount() const
-{
- return engine->fontProperty(QAbstractFontEngine::GlyphCount).toInt();
-}
-
-bool QProxyFontEngine::canRender(const QChar *string, int len)
-{
- QVarLengthArray<uint> glyphs(len);
- int numGlyphs = len;
-
- if (!engine->convertStringToGlyphIndices(string, len, glyphs.data(), &numGlyphs, /*flags*/0))
- return false;
-
- for (int i = 0; i < numGlyphs; ++i)
- if (!glyphs[i])
- return false;
-
- return true;
-}
-
-void QProxyFontEngine::draw(QPaintEngine *p, qreal _x, qreal _y, const QTextItemInt &si)
-{
- QPaintEngineState *pState = p->state;
- QRasterPaintEngine *paintEngine = static_cast<QRasterPaintEngine*>(p);
-
- QTransform matrix = pState->transform();
- matrix.translate(_x, _y);
- QFixed x = QFixed::fromReal(matrix.dx());
- QFixed y = QFixed::fromReal(matrix.dy());
-
- QVarLengthArray<QFixedPoint> positions;
- QVarLengthArray<glyph_t> glyphs;
- getGlyphPositions(si.glyphs, matrix, si.flags, glyphs, positions);
- if (glyphs.size() == 0)
- return;
-
- for(int i = 0; i < glyphs.size(); i++) {
- QImage glyph = alphaMapForGlyph(glyphs[i]);
- if (glyph.isNull())
- continue;
-
- if (glyph.format() != QImage::Format_Indexed8
- && glyph.format() != QImage::Format_Mono)
- continue;
-
- QAbstractFontEngine::GlyphMetrics metrics = engine->glyphMetrics(glyphs[i]);
-
- int depth = glyph.format() == QImage::Format_Mono ? 1 : 8;
- paintEngine->alphaPenBlt(glyph.bits(), glyph.bytesPerLine(), depth,
- qRound(positions[i].x + QFixed::fromFixed(metrics.x)),
- qRound(positions[i].y + QFixed::fromFixed(metrics.y)),
- glyph.width(), glyph.height());
- }
-}
-
-/*
- * This is only called when we use the proxy fontengine directly (without sharing the rendered
- * glyphs). So we prefer outline rendering over rendering of unshared glyphs. That decision is
- * done in qfontdatabase_qws.cpp by looking at the ShareGlyphsHint and the pixel size of the font.
- */
-bool QProxyFontEngine::drawAsOutline() const
-{
- if (!(engineCapabilities & QAbstractFontEngine::CanOutlineGlyphs))
- return false;
-
- QVariant outlineHint = engine->fontProperty(QAbstractFontEngine::OutlineGlyphsHint);
- return !outlineHint.isValid() || outlineHint.toBool();
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qabstractfontengine_qws.h b/src/gui/text/qabstractfontengine_qws.h
deleted file mode 100644
index 4c85a0a063..0000000000
--- a/src/gui/text/qabstractfontengine_qws.h
+++ /dev/null
@@ -1,221 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QABSTRACTFONTENGINE_QWS_H
-#define QABSTRACTFONTENGINE_QWS_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qhash.h>
-#include <QtCore/qvariant.h>
-#include <QtCore/qfactoryinterface.h>
-#include <QtGui/qpaintengine.h>
-#include <QtGui/qfontdatabase.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QFontEngineInfoPrivate;
-
-class Q_GUI_EXPORT QFontEngineInfo
-{
-public:
- QDOC_PROPERTY(QString family READ family WRITE setFamily)
- QDOC_PROPERTY(qreal pixelSize READ pixelSize WRITE setPixelSize)
- QDOC_PROPERTY(int weight READ weight WRITE setWeight)
- QDOC_PROPERTY(QFont::Style style READ style WRITE setStyle)
- QDOC_PROPERTY(QList<QFontDatabase::WritingSystem> writingSystems READ writingSystems WRITE setWritingSystems)
-
- QFontEngineInfo();
- explicit QFontEngineInfo(const QString &family);
- QFontEngineInfo(const QFontEngineInfo &other);
- QFontEngineInfo &operator=(const QFontEngineInfo &other);
- ~QFontEngineInfo();
-
- void setFamily(const QString &name);
- QString family() const;
-
- void setPixelSize(qreal size);
- qreal pixelSize() const;
-
- void setWeight(int weight);
- int weight() const;
-
- void setStyle(QFont::Style style);
- QFont::Style style() const;
-
- QList<QFontDatabase::WritingSystem> writingSystems() const;
- void setWritingSystems(const QList<QFontDatabase::WritingSystem> &writingSystems);
-
-private:
- QFontEngineInfoPrivate *d;
-};
-
-class QAbstractFontEngine;
-
-struct Q_GUI_EXPORT QFontEngineFactoryInterface : public QFactoryInterface
-{
- virtual QAbstractFontEngine *create(const QFontEngineInfo &info) = 0;
- virtual QList<QFontEngineInfo> availableFontEngines() const = 0;
-};
-
-#define QFontEngineFactoryInterface_iid "com.trolltech.Qt.QFontEngineFactoryInterface"
-Q_DECLARE_INTERFACE(QFontEngineFactoryInterface, QFontEngineFactoryInterface_iid)
-
-class QFontEnginePluginPrivate;
-
-class Q_GUI_EXPORT QFontEnginePlugin : public QObject, public QFontEngineFactoryInterface
-{
- Q_OBJECT
- Q_INTERFACES(QFontEngineFactoryInterface:QFactoryInterface)
-public:
- QFontEnginePlugin(const QString &foundry, QObject *parent = 0);
- ~QFontEnginePlugin();
-
- virtual QStringList keys() const;
-
- virtual QAbstractFontEngine *create(const QFontEngineInfo &info) = 0;
- virtual QList<QFontEngineInfo> availableFontEngines() const = 0;
-
-private:
- Q_DECLARE_PRIVATE(QFontEnginePlugin)
- Q_DISABLE_COPY(QFontEnginePlugin)
-};
-
-class QAbstractFontEnginePrivate;
-
-class Q_GUI_EXPORT QAbstractFontEngine : public QObject
-{
- Q_OBJECT
-public:
- enum Capability {
- CanOutlineGlyphs = 1,
- CanRenderGlyphs_Mono = 2,
- CanRenderGlyphs_Gray = 4,
- CanRenderGlyphs = CanRenderGlyphs_Mono | CanRenderGlyphs_Gray
- };
- Q_DECLARE_FLAGS(Capabilities, Capability)
-
- explicit QAbstractFontEngine(QObject *parent = 0);
- ~QAbstractFontEngine();
-
- typedef int Fixed; // 26.6
-
- struct FixedPoint
- {
- Fixed x;
- Fixed y;
- };
-
- struct GlyphMetrics
- {
- inline GlyphMetrics()
- : x(0), y(0), width(0), height(0),
- advance(0) {}
- Fixed x;
- Fixed y;
- Fixed width;
- Fixed height;
- Fixed advance;
- };
-
- enum FontProperty {
- Ascent,
- Descent,
- Leading,
- XHeight,
- AverageCharWidth,
- LineThickness,
- UnderlinePosition,
- MaxCharWidth,
- MinLeftBearing,
- MinRightBearing,
- GlyphCount,
-
- // hints
- CacheGlyphsHint,
- OutlineGlyphsHint
- };
-
- // keep in sync with QTextEngine::ShaperFlag!!
- enum TextShapingFlag {
- RightToLeft = 0x0001,
- ReturnDesignMetrics = 0x0002
- };
- Q_DECLARE_FLAGS(TextShapingFlags, TextShapingFlag)
-
- virtual Capabilities capabilities() const = 0;
- virtual QVariant fontProperty(FontProperty property) const = 0;
-
- virtual bool convertStringToGlyphIndices(const QChar *string, int length, uint *glyphs, int *numGlyphs, TextShapingFlags flags) const = 0;
-
- virtual void getGlyphAdvances(const uint *glyphs, int numGlyphs, Fixed *advances, TextShapingFlags flags) const = 0;
-
- virtual GlyphMetrics glyphMetrics(uint glyph) const = 0;
-
- virtual bool renderGlyph(uint glyph, int depth, int bytesPerLine, int height, uchar *buffer);
-
- virtual void addGlyphOutlinesToPath(uint *glyphs, int numGlyphs, FixedPoint *positions, QPainterPath *path);
-
- /*
- enum Extension {
- GetTrueTypeTable
- };
-
- virtual bool supportsExtension(Extension extension) const;
- virtual QVariant extension(Extension extension, const QVariant &argument = QVariant());
- */
-
-private:
- Q_DECLARE_PRIVATE(QAbstractFontEngine)
- Q_DISABLE_COPY(QAbstractFontEngine)
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractFontEngine::Capabilities)
-Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractFontEngine::TextShapingFlags)
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
diff --git a/src/gui/text/qabstracttextdocumentlayout.h b/src/gui/text/qabstracttextdocumentlayout.h
index 12f3ed1217..8e792e9b80 100644
--- a/src/gui/text/qabstracttextdocumentlayout.h
+++ b/src/gui/text/qabstracttextdocumentlayout.h
@@ -122,6 +122,7 @@ protected:
QTextCharFormat format(int pos);
private:
+ friend class QWidgetTextControl;
friend class QTextControl;
friend class QTextDocument;
friend class QTextDocumentPrivate;
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp
index 028011bfe8..6a28ff2d74 100644
--- a/src/gui/text/qcssparser.cpp
+++ b/src/gui/text/qcssparser.cpp
@@ -1275,6 +1275,8 @@ void ValueExtractor::extractFont()
bool ValueExtractor::extractImage(QIcon *icon, Qt::Alignment *a, QSize *size)
{
bool hit = false;
+#if 0
+ // ### Qt5
for (int i = 0; i < declarations.count(); ++i) {
const Declaration &decl = declarations.at(i);
switch (decl.d->propertyId) {
@@ -1295,6 +1297,7 @@ bool ValueExtractor::extractImage(QIcon *icon, Qt::Alignment *a, QSize *size)
}
hit = true;
}
+#endif
return hit;
}
@@ -1643,6 +1646,8 @@ void Declaration::borderImageValue(QString *image, int *cuts,
*h = *v;
}
+#if 0
+// ### Qt 5
QIcon Declaration::iconValue() const
{
if (d->parsed.isValid())
@@ -1689,6 +1694,7 @@ QIcon Declaration::iconValue() const
d->parsed = QVariant::fromValue<QIcon>(icon);
return icon;
}
+#endif
///////////////////////////////////////////////////////////////////////////////
// Selector
diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h
index 9c974f773a..4fa8bb0540 100644
--- a/src/gui/text/qcssparser_p.h
+++ b/src/gui/text/qcssparser_p.h
@@ -61,9 +61,9 @@
#include <QtCore/QMultiHash>
#include <QtGui/QFont>
#include <QtGui/QPalette>
-#include <QtGui/QIcon>
#include <QtCore/QSharedData>
+class QIcon;
#ifndef QT_NO_CSSPARSER
@@ -416,7 +416,7 @@ struct BorderData {
// 4. QVector<Declaration> - { prop1: value1; prop2: value2; }
// 5. Declaration - prop1: value1;
-struct Q_AUTOTEST_EXPORT Declaration
+struct Q_GUI_EXPORT Declaration
{
struct DeclarationData : public QSharedData
{
@@ -453,7 +453,7 @@ struct Q_AUTOTEST_EXPORT Declaration
QSize sizeValue() const;
QRect rectValue() const;
QString uriValue() const;
- QIcon iconValue() const;
+// QIcon iconValue() const;
void borderImageValue(QString *image, int *cuts, TileMode *h, TileMode *v) const;
};
@@ -552,7 +552,7 @@ struct BasicSelector
Relation relationToNext;
};
-struct Q_AUTOTEST_EXPORT Selector
+struct Q_GUI_EXPORT Selector
{
QVector<BasicSelector> basicSelectors;
int specificity() const;
@@ -565,7 +565,7 @@ struct MediaRule;
struct PageRule;
struct ImportRule;
-struct Q_AUTOTEST_EXPORT ValueExtractor
+struct Q_GUI_EXPORT ValueExtractor
{
ValueExtractor(const QVector<Declaration> &declarations, const QPalette & = QPalette());
@@ -633,7 +633,7 @@ enum StyleSheetOrigin {
StyleSheetOrigin_Inline
};
-struct StyleSheet
+struct Q_GUI_EXPORT StyleSheet
{
StyleSheet() : origin(StyleSheetOrigin_Unspecified), depth(0) { }
QVector<StyleRule> styleRules; //only contains rules that are not indexed
@@ -739,7 +739,7 @@ struct Q_GUI_EXPORT Symbol
QString lexem() const;
};
-class Q_AUTOTEST_EXPORT Scanner
+class Q_GUI_EXPORT Scanner
{
public:
static QString preprocess(const QString &input, bool *hasEscapeSequences = 0);
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index cf97310ea3..e8308dba06 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -48,8 +48,9 @@
#include "qpainter.h"
#include "qhash.h"
#include "qdatastream.h"
-#include "qapplication.h"
+#include "qguiapplication.h"
#include "qstringlist.h"
+#include "qscreen.h"
#include "qthread.h"
#include "qthreadstorage.h"
@@ -65,19 +66,12 @@
#include "qx11info_x11.h"
#include <private/qt_x11_p.h>
#endif
-#ifdef Q_WS_QWS
-#include "qscreen_qws.h"
-#if !defined(QT_NO_QWS_QPF2)
-#include <qfile.h>
-#include "qfontengine_qpf_p.h"
-#endif
-#endif
#ifdef Q_OS_SYMBIAN
#include <private/qt_s60_p.h>
#endif
#ifdef Q_WS_QPA
#include <QtGui/qplatformscreen_qpa.h>
-#include <QtGui/private/qapplication_p.h>
+#include <QtGui/private/qguiapplication_p.h>
#endif
#include <QtCore/QMutexLocker>
@@ -173,20 +167,11 @@ Q_GUI_EXPORT int qt_defaultDpiX()
#elif defined(Q_WS_MAC)
extern float qt_mac_defaultDpi_x(); //qpaintdevice_mac.cpp
dpi = qt_mac_defaultDpi_x();
-#elif defined(Q_WS_QWS)
- if (!qt_screen)
- return 72;
- QScreen *screen = qt_screen;
- const QList<QScreen*> subScreens = qt_screen->subScreens();
- if (!subScreens.isEmpty())
- screen = subScreens.at(0);
- dpi = qRound(screen->width() / (screen->physicalWidth() / qreal(25.4)));
#elif defined(Q_WS_QPA)
- QPlatformIntegration *pi = QApplicationPrivate::platformIntegration();
- if (pi) {
- QPlatformScreen *screen = QApplicationPrivate::platformIntegration()->screens().at(0);
+ QScreen *screen = QGuiApplication::primaryScreen();
+ if (screen) {
const QSize screenSize = screen->geometry().size();
- const QSize physicalSize = screen->physicalSize();
+ const QSize physicalSize = screen->handle()->physicalSize();
dpi = qRound(screenSize.width() / (physicalSize.width() / qreal(25.4)));
} else {
//PI has not been initialised, or it is being initialised. Give a default dpi
@@ -212,20 +197,11 @@ Q_GUI_EXPORT int qt_defaultDpiY()
#elif defined(Q_WS_MAC)
extern float qt_mac_defaultDpi_y(); //qpaintdevice_mac.cpp
dpi = qt_mac_defaultDpi_y();
-#elif defined(Q_WS_QWS)
- if (!qt_screen)
- return 72;
- QScreen *screen = qt_screen;
- const QList<QScreen*> subScreens = qt_screen->subScreens();
- if (!subScreens.isEmpty())
- screen = subScreens.at(0);
- dpi = qRound(screen->height() / (screen->physicalHeight() / qreal(25.4)));
#elif defined(Q_WS_QPA)
- QPlatformIntegration *pi = QApplicationPrivate::platformIntegration();
- if (pi) {
- QPlatformScreen *screen = QApplicationPrivate::platformIntegration()->screens().at(0);
+ QScreen *screen = QGuiApplication::primaryScreen();
+ if (screen) {
const QSize screenSize = screen->geometry().size();
- const QSize physicalSize = screen->physicalSize();
+ const QSize physicalSize = screen->handle()->physicalSize();
dpi = qRound(screenSize.height() / (physicalSize.height() / qreal(25.4)));
} else {
//PI has not been initialised, or it is being initialised. Give a default dpi
@@ -453,9 +429,9 @@ QFontEngineData::~QFontEngineData()
Use QFontMetrics to get measurements, e.g. the pixel length of a
string using QFontMetrics::width().
- Note that a QApplication instance must exist before a QFont can be
+ Note that a QGuiApplication instance must exist before a QFont can be
used. You can set the application's default font with
- QApplication::setFont().
+ QGuiApplication::setFont().
If a chosen font does not include all the characters that
need to be displayed, QFont will try to find the characters in the
@@ -786,10 +762,10 @@ void QFont::detach()
/*!
Constructs a font object that uses the application's default font.
- \sa QApplication::setFont(), QApplication::font()
+ \sa QGuiApplication::setFont(), QGuiApplication::font()
*/
QFont::QFont()
- : d(QApplication::font().d.data()), resolve_mask(0)
+ : d(QGuiApplication::font().d.data()), resolve_mask(0)
{
}
@@ -809,7 +785,7 @@ QFont::QFont()
algorithm.
\sa Weight, setFamily(), setPointSize(), setWeight(), setItalic(),
- setStyleHint() QApplication::font()
+ setStyleHint() QGuiApplication::font()
*/
QFont::QFont(const QString &family, int pointSize, int weight, bool italic)
: d(new QFontPrivate()), resolve_mask(QFont::FamilyResolved)
@@ -1133,18 +1109,6 @@ int QFont::pixelSize() const
return d->request.pixelSize;
}
-#ifdef QT3_SUPPORT
-/*! \obsolete
-
- Sets the logical pixel height of font characters when shown on
- the screen to \a pixelSize.
-*/
-void QFont::setPixelSizeFloat(qreal pixelSize)
-{
- setPixelSize((int)pixelSize);
-}
-#endif
-
/*!
\fn bool QFont::italic() const
@@ -1912,43 +1876,6 @@ QFont QFont::resolve(const QFont &other) const
\internal
*/
-#ifdef QT3_SUPPORT
-
-/*! \obsolete
-
- Please use QApplication::font() instead.
-*/
-QFont QFont::defaultFont()
-{
- return QApplication::font();
-}
-
-/*! \obsolete
-
- Please use QApplication::setFont() instead.
-*/
-void QFont::setDefaultFont(const QFont &f)
-{
- QApplication::setFont(f);
-}
-
-/*!
- \fn qreal QFont::pointSizeFloat() const
- \compat
-
- Use pointSizeF() instead.
-*/
-
-/*!
- \fn void QFont::setPointSizeFloat(qreal size)
- \compat
-
- Use setPointSizeF() instead.
-*/
-#endif
-
-
-
/*****************************************************************************
QFont substitution management
diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h
index 14f290ceb3..1035b665a3 100644
--- a/src/gui/text/qfont.h
+++ b/src/gui/text/qfont.h
@@ -287,14 +287,6 @@ public:
inline uint resolve() const { return resolve_mask; }
inline void resolve(uint mask) { resolve_mask = mask; }
-#ifdef QT3_SUPPORT
- static QT3_SUPPORT QFont defaultFont();
- static QT3_SUPPORT void setDefaultFont(const QFont &);
- QT3_SUPPORT void setPixelSizeFloat(qreal);
- QT3_SUPPORT qreal pointSizeFloat() const { return pointSizeF(); }
- QT3_SUPPORT void setPointSizeFloat(qreal size) { setPointSizeF(size); }
-#endif
-
private:
QFont(QFontPrivate *);
diff --git a/src/gui/text/qfont_mac.cpp b/src/gui/text/qfont_mac.cpp
deleted file mode 100644
index 3bbff7f4bb..0000000000
--- a/src/gui/text/qfont_mac.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qfont.h"
-#include "qfont_p.h"
-#include "qfontengine_p.h"
-#include "qfontengine_mac_p.h"
-#include "qfontengine_coretext_p.h"
-#include "qfontinfo.h"
-#include "qfontmetrics.h"
-#include "qpaintdevice.h"
-#include "qstring.h"
-#include <private/qt_mac_p.h>
-#include <private/qtextengine_p.h>
-#include <private/qunicodetables_p.h>
-#include <qapplication.h>
-#include "qfontdatabase.h"
-#include <qpainter.h>
-#include "qtextengine_p.h"
-#include <stdlib.h>
-
-QT_BEGIN_NAMESPACE
-
-extern float qt_mac_defaultDpi_x(); //qpaintdevice_mac.cpp
-
-int qt_mac_pixelsize(const QFontDef &def, int dpi)
-{
- float ret;
- if(def.pixelSize == -1)
- ret = def.pointSize * dpi / qt_mac_defaultDpi_x();
- else
- ret = def.pixelSize;
- return qRound(ret);
-}
-int qt_mac_pointsize(const QFontDef &def, int dpi)
-{
- float ret;
- if(def.pointSize < 0)
- ret = def.pixelSize * qt_mac_defaultDpi_x() / float(dpi);
- else
- ret = def.pointSize;
- return qRound(ret);
-}
-
-QString QFont::rawName() const
-{
- return family();
-}
-
-void QFont::setRawName(const QString &name)
-{
- setFamily(name);
-}
-
-void QFont::cleanup()
-{
- QFontCache::cleanup();
-}
-
-/*!
- Returns an ATSUFontID
-*/
-quint32 QFont::macFontID() const // ### need 64-bit version
-{
-#ifdef QT_MAC_USE_COCOA
- return 0;
-#elif 1
- QFontEngine *fe = d->engineForScript(QUnicodeTables::Common);
- if (fe && fe->type() == QFontEngine::Multi)
- return static_cast<QFontEngineMacMulti*>(fe)->macFontID();
-#else
- Str255 name;
- if(FMGetFontFamilyName((FMFontFamily)((UInt32)handle()), name) == noErr) {
- short fnum;
- GetFNum(name, &fnum);
- return fnum;
- }
-#endif
- return 0;
-}
-
-// Returns an ATSUFonFamilyRef
-Qt::HANDLE QFont::handle() const
-{
-#ifdef QT_MAC_USE_COCOA
- QFontEngine *fe = d->engineForScript(QUnicodeTables::Common);
- if (fe && fe->type() == QFontEngine::Multi)
- return (Qt::HANDLE)static_cast<QCoreTextFontEngineMulti*>(fe)->macFontID();
-#endif
- return 0;
-}
-
-void QFont::initialize()
-{ }
-
-QString QFont::defaultFamily() const
-{
- switch(d->request.styleHint) {
- case QFont::Times:
- return QString::fromLatin1("Times New Roman");
- case QFont::Courier:
- return QString::fromLatin1("Courier New");
- case QFont::Monospace:
- return QString::fromLatin1("Courier");
- case QFont::Decorative:
- return QString::fromLatin1("Bookman Old Style");
- case QFont::Cursive:
- return QString::fromLatin1("Apple Chancery");
- case QFont::Fantasy:
- return QString::fromLatin1("Papyrus");
- case QFont::Helvetica:
- case QFont::System:
- default:
- return QString::fromLatin1("Helvetica");
- }
-}
-
-QString QFont::lastResortFamily() const
-{
- return QString::fromLatin1("Helvetica");
-}
-
-QString QFont::lastResortFont() const
-{
- return QString::fromLatin1("Geneva");
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfont_qpa.cpp b/src/gui/text/qfont_qpa.cpp
index 3e0a24636c..e151a389cd 100644
--- a/src/gui/text/qfont_qpa.cpp
+++ b/src/gui/text/qfont_qpa.cpp
@@ -39,14 +39,14 @@
**
****************************************************************************/
-#include <QtGui/private/qapplication_p.h>
+#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/QPlatformFontDatabase>
QT_BEGIN_NAMESPACE
void QFont::initialize()
{
- QApplicationPrivate::platformIntegration()->fontDatabase()->populateFontDatabase();
+ QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFontDatabase();
}
void QFont::cleanup()
@@ -90,7 +90,7 @@ QString QFont::defaultFamily() const
familyName = QString::fromLatin1("helvetica");
}
- QStringList list = QApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(familyName,QFont::StyleNormal,QFont::StyleHint(d->request.styleHint),QUnicodeTables::Common);
+ QStringList list = QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(familyName,QFont::StyleNormal,QFont::StyleHint(d->request.styleHint),QUnicodeTables::Common);
if (list.size()) {
familyName = list.at(0);
}
diff --git a/src/gui/text/qfont_qws.cpp b/src/gui/text/qfont_qws.cpp
deleted file mode 100644
index 3674e178ea..0000000000
--- a/src/gui/text/qfont_qws.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwidget.h"
-#include "qpainter.h"
-#include "qfont_p.h"
-#include <private/qunicodetables_p.h>
-#include "qfontdatabase.h"
-#include "qtextcodec.h"
-#include "qapplication.h"
-#include "qfile.h"
-#include "qtextstream.h"
-#include "qmap.h"
-//#include "qmemorymanager_qws.h"
-#include "qtextengine_p.h"
-#include "qfontengine_p.h"
-#if !defined(QT_NO_FREETYPE)
-#include "qfontengine_ft_p.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-void QFont::initialize()
-{ }
-
-void QFont::cleanup()
-{
- QFontCache::cleanup();
-}
-
-
-/*****************************************************************************
- QFont member functions
- *****************************************************************************/
-
-Qt::HANDLE QFont::handle() const
-{
-#ifndef QT_NO_FREETYPE
- return freetypeFace();
-#endif
- return 0;
-}
-
-FT_Face QFont::freetypeFace() const
-{
-#ifndef QT_NO_FREETYPE
- QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
- if (engine->type() == QFontEngine::Multi)
- engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
- if (engine->type() == QFontEngine::Freetype) {
- const QFontEngineFT *ft = static_cast<const QFontEngineFT *>(engine);
- return ft->non_locked_face();
- }
-#endif
- return 0;
-}
-
-QString QFont::rawName() const
-{
- return QLatin1String("unknown");
-}
-
-void QFont::setRawName(const QString &)
-{
-}
-
-QString QFont::defaultFamily() const
-{
- switch(d->request.styleHint) {
- case QFont::Times:
- return QString::fromLatin1("times");
- case QFont::Courier:
- case QFont::Monospace:
- return QString::fromLatin1("courier");
- case QFont::Decorative:
- return QString::fromLatin1("old english");
- case QFont::Helvetica:
- case QFont::System:
- default:
- return QString::fromLatin1("helvetica");
- }
-}
-
-QString QFont::lastResortFamily() const
-{
- return QString::fromLatin1("helvetica");
-}
-
-QString QFont::lastResortFont() const
-{
- qFatal("QFont::lastResortFont: Cannot find any reasonable font");
- // Shut compiler up
- return QString();
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfont_s60.cpp b/src/gui/text/qfont_s60.cpp
deleted file mode 100644
index e0f4bad527..0000000000
--- a/src/gui/text/qfont_s60.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qfont.h"
-#include "qfont_p.h"
-#include <private/qt_s60_p.h>
-#include <private/qpixmap_s60_p.h>
-#include "qmutex.h"
-
-QT_BEGIN_NAMESPACE
-
-#ifdef QT_NO_FREETYPE
-Q_GLOBAL_STATIC(QMutex, lastResortFamilyMutex);
-#endif // QT_NO_FREETYPE
-
-extern QStringList qt_symbian_fontFamiliesOnFontServer(); // qfontdatabase_s60.cpp
-Q_GLOBAL_STATIC_WITH_INITIALIZER(QStringList, fontFamiliesOnFontServer, {
- // We are only interested in the initial font families. No Application fonts.
- // Therefore, we are allowed to cache the list.
- x->append(qt_symbian_fontFamiliesOnFontServer());
-});
-
-QString QFont::lastResortFont() const
-{
- // Symbian's font Api does not distinguish between font and family.
- // Therefore we try to get a "Family" first, then fall back to "Sans".
- static QString font = lastResortFamily();
- if (font.isEmpty())
- font = QLatin1String("Sans");
- return font;
-}
-
-QString QFont::lastResortFamily() const
-{
-#ifdef QT_NO_FREETYPE
- QMutexLocker locker(lastResortFamilyMutex());
- static QString family;
- if (family.isEmpty()) {
-
- QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
-
- CFont *font;
- const TInt err = S60->screenDevice()->GetNearestFontInTwips(font, TFontSpec());
- Q_ASSERT(err == KErrNone);
- const TFontSpec spec = font->FontSpecInTwips();
- family = QString((const QChar *)spec.iTypeface.iName.Ptr(), spec.iTypeface.iName.Length());
- S60->screenDevice()->ReleaseFont(font);
-
- lock.relock();
- }
- return family;
-#else // QT_NO_FREETYPE
- // For the FreeType case we just hard code the face name, since otherwise on
- // East Asian systems we may get a name for a stroke based (non-ttf) font.
-
- // TODO: Get the type face name in a proper way
-
- const bool isJapaneseOrChineseSystem =
- User::Language() == ELangJapanese || User::Language() == ELangPrcChinese;
-
- static QString family;
- if (family.isEmpty()) {
- QStringList families = qt_symbian_fontFamiliesOnFontServer();
- const char* const preferredFamilies[] = {"Nokia Sans S60", "Series 60 Sans"};
- for (int i = 0; i < sizeof preferredFamilies / sizeof preferredFamilies[0]; ++i) {
- const QString preferredFamily = QLatin1String(preferredFamilies[i]);
- if (families.contains(preferredFamily)) {
- family = preferredFamily;
- break;
- }
- }
- }
-
- return QLatin1String(isJapaneseOrChineseSystem?"Heisei Kaku Gothic S60":family.toLatin1());
-#endif // QT_NO_FREETYPE
-}
-
-QString QFont::defaultFamily() const
-{
-#ifdef QT_NO_FREETYPE
- switch(d->request.styleHint) {
- case QFont::SansSerif: {
- static const char* const preferredSansSerif[] = {"Nokia Sans S60", "Series 60 Sans"};
- for (int i = 0; i < sizeof preferredSansSerif / sizeof preferredSansSerif[0]; ++i) {
- const QString sansSerif = QLatin1String(preferredSansSerif[i]);
- if (fontFamiliesOnFontServer()->contains(sansSerif))
- return sansSerif;
- }
- }
- // No break. Intentional fall through.
- default:
- return lastResortFamily();
- }
-#endif // QT_NO_FREETYPE
- return lastResortFamily();
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfont_win.cpp b/src/gui/text/qfont_win.cpp
deleted file mode 100644
index 7a0f234ca6..0000000000
--- a/src/gui/text/qfont_win.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qfont.h"
-#include "qfont_p.h"
-#include "qfontengine_p.h"
-#include "qtextengine_p.h"
-#include "qfontmetrics.h"
-#include "qfontinfo.h"
-
-#include "qwidget.h"
-#include "qpainter.h"
-#include <limits.h>
-#include "qt_windows.h"
-#include <private/qapplication_p.h>
-#include "qapplication.h"
-#include <private/qunicodetables_p.h>
-#include <qfontdatabase.h>
-
-QT_BEGIN_NAMESPACE
-
-extern HDC shared_dc(); // common dc for all fonts
-extern QFont::Weight weightFromInteger(int weight); // qfontdatabase.cpp
-
-// ### maybe move to qapplication_win
-QFont qt_LOGFONTtoQFont(LOGFONT& lf, bool /*scale*/)
-{
- QString family = QString::fromWCharArray(lf.lfFaceName);
- QFont qf(family);
- qf.setItalic(lf.lfItalic);
- if (lf.lfWeight != FW_DONTCARE)
- qf.setWeight(weightFromInteger(lf.lfWeight));
- int lfh = qAbs(lf.lfHeight);
- qf.setPointSizeF(lfh * 72.0 / GetDeviceCaps(shared_dc(),LOGPIXELSY));
- qf.setUnderline(false);
- qf.setOverline(false);
- qf.setStrikeOut(false);
- return qf;
-}
-
-
-static inline float pixelSize(const QFontDef &request, int dpi)
-{
- float pSize;
- if (request.pointSize != -1)
- pSize = request.pointSize * dpi/ 72.;
- else
- pSize = request.pixelSize;
- return pSize;
-}
-
-static inline float pointSize(const QFontDef &fd, int dpi)
-{
- float pSize;
- if (fd.pointSize < 0)
- pSize = fd.pixelSize * 72. / ((float)dpi);
- else
- pSize = fd.pointSize;
- return pSize;
-}
-
-/*****************************************************************************
- QFont member functions
- *****************************************************************************/
-
-void QFont::initialize()
-{
-}
-
-void QFont::cleanup()
-{
- QFontCache::cleanup();
-}
-
-HFONT QFont::handle() const
-{
- QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
- Q_ASSERT(engine != 0);
- if (engine->type() == QFontEngine::Multi)
- engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
- if (engine->type() == QFontEngine::Win)
- return static_cast<QFontEngineWin *>(engine)->hfont;
- return 0;
-}
-
-QString QFont::rawName() const
-{
- return family();
-}
-
-void QFont::setRawName(const QString &name)
-{
- setFamily(name);
-}
-
-QString QFont::defaultFamily() const
-{
- switch(d->request.styleHint) {
- case QFont::Times:
- return QString::fromLatin1("Times New Roman");
- case QFont::Courier:
- case QFont::Monospace:
- return QString::fromLatin1("Courier New");
- case QFont::Decorative:
- return QString::fromLatin1("Bookman Old Style");
- case QFont::Cursive:
- return QString::fromLatin1("Comic Sans MS");
- case QFont::Fantasy:
- return QString::fromLatin1("Impact");
- case QFont::Helvetica:
- return QString::fromLatin1("Arial");
- case QFont::System:
- default:
- return QString::fromLatin1("MS Sans Serif");
- }
-}
-
-QString QFont::lastResortFamily() const
-{
- return QString::fromLatin1("helvetica");
-}
-
-QString QFont::lastResortFont() const
-{
- return QString::fromLatin1("arial");
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfont_x11.cpp b/src/gui/text/qfont_x11.cpp
deleted file mode 100644
index e89e0d9dc2..0000000000
--- a/src/gui/text/qfont_x11.cpp
+++ /dev/null
@@ -1,368 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#define QT_FATAL_ASSERT
-
-#include "qplatformdefs.h"
-
-#include "qfont.h"
-#include "qapplication.h"
-#include "qfontinfo.h"
-#include "qfontdatabase.h"
-#include "qfontmetrics.h"
-#include "qpaintdevice.h"
-#include "qtextcodec.h"
-#include "qiodevice.h"
-#include "qhash.h"
-
-#include <private/qunicodetables_p.h>
-#include "qfont_p.h"
-#include "qfontengine_p.h"
-#include "qfontengine_x11_p.h"
-#include "qtextengine_p.h"
-
-#include <private/qt_x11_p.h>
-#include "qx11info_x11.h"
-
-#include <time.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#define QFONTLOADER_DEBUG
-#define QFONTLOADER_DEBUG_VERBOSE
-
-QT_BEGIN_NAMESPACE
-
-double qt_pixelSize(double pointSize, int dpi)
-{
- if (pointSize < 0)
- return -1.;
- if (dpi == 75) // the stupid 75 dpi setting on X11
- dpi = 72;
- return (pointSize * dpi) /72.;
-}
-
-double qt_pointSize(double pixelSize, int dpi)
-{
- if (pixelSize < 0)
- return -1.;
- if (dpi == 75) // the stupid 75 dpi setting on X11
- dpi = 72;
- return pixelSize * 72. / ((double) dpi);
-}
-
-/*
- Removes wildcards from an XLFD.
-
- Returns \a xlfd with all wildcards removed if a match for \a xlfd is
- found, otherwise it returns \a xlfd.
-*/
-static QByteArray qt_fixXLFD(const QByteArray &xlfd)
-{
- QByteArray ret = xlfd;
- int count = 0;
- char **fontNames =
- XListFonts(QX11Info::display(), xlfd, 32768, &count);
- if (count > 0)
- ret = fontNames[0];
- XFreeFontNames(fontNames);
- return ret ;
-}
-
-typedef QHash<int, QString> FallBackHash;
-Q_GLOBAL_STATIC(FallBackHash, fallBackHash)
-
-// Returns the user-configured fallback family for the specified script.
-QString qt_fallback_font_family(int script)
-{
- FallBackHash *hash = fallBackHash();
- return hash->value(script);
-}
-
-// Sets the fallback family for the specified script.
-Q_GUI_EXPORT void qt_x11_set_fallback_font_family(int script, const QString &family)
-{
- FallBackHash *hash = fallBackHash();
- if (!family.isEmpty())
- hash->insert(script, family);
- else
- hash->remove(script);
-}
-
-int QFontPrivate::defaultEncodingID = -1;
-
-void QFont::initialize()
-{
- extern int qt_encoding_id_for_mib(int mib); // from qfontdatabase_x11.cpp
- QTextCodec *codec = QTextCodec::codecForLocale();
- // determine the default encoding id using the locale, otherwise
- // fallback to latin1 (mib == 4)
- int mib = codec ? codec->mibEnum() : 4;
-
- // for asian locales, use the mib for the font codec instead of the locale codec
- switch (mib) {
- case 38: // eucKR
- mib = 36;
- break;
-
- case 2025: // GB2312
- mib = 57;
- break;
-
- case 113: // GBK
- mib = -113;
- break;
-
- case 114: // GB18030
- mib = -114;
- break;
-
- case 2026: // Big5
- mib = -2026;
- break;
-
- case 2101: // Big5-HKSCS
- mib = -2101;
- break;
-
- case 16: // JIS7
- mib = 15;
- break;
-
- case 17: // SJIS
- case 18: // eucJP
- mib = 63;
- break;
- }
-
- // get the default encoding id for the locale encoding...
- QFontPrivate::defaultEncodingID = qt_encoding_id_for_mib(mib);
-}
-
-void QFont::cleanup()
-{
- QFontCache::cleanup();
-}
-
-/*!
- \internal
- X11 Only: Returns the screen with which this font is associated.
-*/
-int QFont::x11Screen() const
-{
- return d->screen;
-}
-
-/*! \internal
- X11 Only: Associate the font with the specified \a screen.
-*/
-void QFont::x11SetScreen(int screen)
-{
- if (screen < 0) // assume default
- screen = QX11Info::appScreen();
-
- if (screen == d->screen)
- return; // nothing to do
-
- detach();
- d->screen = screen;
-}
-
-Qt::HANDLE QFont::handle() const
-{
- QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
- Q_ASSERT(engine != 0);
- if (engine->type() == QFontEngine::Multi)
- engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
- if (engine->type() == QFontEngine::XLFD)
- return static_cast<QFontEngineXLFD *>(engine)->fontStruct()->fid;
- return 0;
-}
-
-
-FT_Face QFont::freetypeFace() const
-{
-#ifndef QT_NO_FREETYPE
- QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
- if (engine->type() == QFontEngine::Multi)
- engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
-#ifndef QT_NO_FONTCONFIG
- if (engine->type() == QFontEngine::Freetype) {
- const QFontEngineFT *ft = static_cast<const QFontEngineFT *>(engine);
- return ft->non_locked_face();
- } else
-#endif
- if (engine->type() == QFontEngine::XLFD) {
- const QFontEngineXLFD *xlfd = static_cast<const QFontEngineXLFD *>(engine);
- return xlfd->non_locked_face();
- }
-#endif
- return 0;
-}
-
-QString QFont::rawName() const
-{
- QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
- Q_ASSERT(engine != 0);
- if (engine->type() == QFontEngine::Multi)
- engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
- if (engine->type() == QFontEngine::XLFD)
- return QString::fromLatin1(engine->name());
- return QString();
-}
-struct QtFontDesc;
-
-void QFont::setRawName(const QString &name)
-{
- detach();
-
- // from qfontdatabase_x11.cpp
- extern bool qt_fillFontDef(const QByteArray &xlfd, QFontDef *fd, int dpi, QtFontDesc *desc);
-
- if (!qt_fillFontDef(qt_fixXLFD(name.toLatin1()), &d->request, d->dpi, 0)) {
- qWarning("QFont::setRawName: Invalid XLFD: \"%s\"", name.toLatin1().constData());
-
- setFamily(name);
- setRawMode(true);
- } else {
- resolve_mask = QFont::AllPropertiesResolved;
- }
-}
-
-QString QFont::lastResortFamily() const
-{
- return QString::fromLatin1("Helvetica");
-}
-
-QString QFont::defaultFamily() const
-{
- switch (d->request.styleHint) {
- case QFont::Times:
- return QString::fromLatin1("Times");
-
- case QFont::Courier:
- return QString::fromLatin1("Courier");
-
- case QFont::Monospace:
- return QString::fromLatin1("Courier New");
-
- case QFont::Cursive:
- return QString::fromLatin1("Comic Sans MS");
-
- case QFont::Fantasy:
- return QString::fromLatin1("Impact");
-
- case QFont::Decorative:
- return QString::fromLatin1("Old English");
-
- case QFont::Helvetica:
- case QFont::System:
- default:
- return QString::fromLatin1("Helvetica");
- }
-}
-
-/*
- Returns a last resort raw font name for the font matching algorithm.
- This is used if even the last resort family is not available. It
- returns \e something, almost no matter what. The current
- implementation tries a wide variety of common fonts, returning the
- first one it finds. The implementation may change at any time.
-*/
-static const char * const tryFonts[] = {
- "-*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-*",
- "-*-courier-medium-r-*-*-*-120-*-*-*-*-*-*",
- "-*-times-medium-r-*-*-*-120-*-*-*-*-*-*",
- "-*-lucida-medium-r-*-*-*-120-*-*-*-*-*-*",
- "-*-helvetica-*-*-*-*-*-120-*-*-*-*-*-*",
- "-*-courier-*-*-*-*-*-120-*-*-*-*-*-*",
- "-*-times-*-*-*-*-*-120-*-*-*-*-*-*",
- "-*-lucida-*-*-*-*-*-120-*-*-*-*-*-*",
- "-*-helvetica-*-*-*-*-*-*-*-*-*-*-*-*",
- "-*-courier-*-*-*-*-*-*-*-*-*-*-*-*",
- "-*-times-*-*-*-*-*-*-*-*-*-*-*-*",
- "-*-lucida-*-*-*-*-*-*-*-*-*-*-*-*",
- "-*-fixed-*-*-*-*-*-*-*-*-*-*-*-*",
- "6x13",
- "7x13",
- "8x13",
- "9x15",
- "fixed",
- 0
-};
-
-// Returns true if the font exists, false otherwise
-static bool fontExists(const QString &fontName)
-{
- int count;
- char **fontNames = XListFonts(QX11Info::display(), (char*)fontName.toLatin1().constData(), 32768, &count);
- if (fontNames) XFreeFontNames(fontNames);
-
- return count != 0;
-}
-
-QString QFont::lastResortFont() const
-{
- static QString last;
-
- // already found
- if (! last.isNull())
- return last;
-
- int i = 0;
- const char* f;
-
- while ((f = tryFonts[i])) {
- last = QString::fromLatin1(f);
-
- if (fontExists(last))
- return last;
-
- i++;
- }
-
-#if defined(CHECK_NULL)
- qFatal("QFontPrivate::lastResortFont: Cannot find any reasonable font");
-#endif
- return last;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 6202fbac52..fa67dc1a8a 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -43,7 +43,7 @@
#include "qfontdatabase.h"
#include "qdebug.h"
#include "qalgorithms.h"
-#include "qapplication.h"
+#include "qguiapplication.h"
#include "qvarlengtharray.h" // here or earlier - workaround for VC++6
#include "qthread.h"
#include "qmutex.h"
@@ -51,7 +51,7 @@
#include "qfontengine_p.h"
#ifdef Q_WS_QPA
-#include <QtGui/private/qapplication_p.h>
+#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qplatformfontdatabase_qpa.h>
#include "qabstractfileengine.h"
#endif
@@ -103,34 +103,34 @@ static int getFontWeight(const QString &weightString)
// Test in decreasing order of commonness
if (s == QLatin1String("medium") ||
s == QLatin1String("normal")
- || s.compare(QApplication::translate("QFontDatabase", "Normal"), Qt::CaseInsensitive) == 0)
+ || s.compare(QCoreApplication::translate("QFontDatabase", "Normal"), Qt::CaseInsensitive) == 0)
return QFont::Normal;
if (s == QLatin1String("bold")
- || s.compare(QApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive) == 0)
+ || s.compare(QCoreApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive) == 0)
return QFont::Bold;
if (s == QLatin1String("demibold") || s == QLatin1String("demi bold")
- || s.compare(QApplication::translate("QFontDatabase", "Demi Bold"), Qt::CaseInsensitive) == 0)
+ || s.compare(QCoreApplication::translate("QFontDatabase", "Demi Bold"), Qt::CaseInsensitive) == 0)
return QFont::DemiBold;
if (s == QLatin1String("black")
- || s.compare(QApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0)
+ || s.compare(QCoreApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0)
return QFont::Black;
if (s == QLatin1String("light"))
return QFont::Light;
if (s.contains(QLatin1String("bold"))
- || s.contains(QApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive)) {
+ || s.contains(QCoreApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive)) {
if (s.contains(QLatin1String("demi"))
- || s.compare(QApplication::translate("QFontDatabase", "Demi"), Qt::CaseInsensitive) == 0)
+ || s.compare(QCoreApplication::translate("QFontDatabase", "Demi"), Qt::CaseInsensitive) == 0)
return (int) QFont::DemiBold;
return (int) QFont::Bold;
}
if (s.contains(QLatin1String("light"))
- || s.compare(QApplication::translate("QFontDatabase", "Light"), Qt::CaseInsensitive) == 0)
+ || s.compare(QCoreApplication::translate("QFontDatabase", "Light"), Qt::CaseInsensitive) == 0)
return (int) QFont::Light;
if (s.contains(QLatin1String("black"))
- || s.compare(QApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0)
+ || s.compare(QCoreApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0)
return (int) QFont::Black;
return (int) QFont::Normal;
@@ -262,7 +262,7 @@ struct QtFontStyle
pixelSizes[count].fileName.~QByteArray();
#endif
#if defined (Q_WS_QPA)
- QPlatformIntegration *integration = QApplicationPrivate::platformIntegration();
+ QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
if (integration) { //on shut down there will be some that we don't release.
integration->fontDatabase()->releaseHandle(pixelSizes[count].handle);
}
@@ -296,10 +296,10 @@ QtFontStyle::Key::Key(const QString &styleString)
weight = getFontWeight(styleString);
if (styleString.contains(QLatin1String("Italic"))
- || styleString.contains(QApplication::translate("QFontDatabase", "Italic")))
+ || styleString.contains(QCoreApplication::translate("QFontDatabase", "Italic")))
style = QFont::StyleItalic;
else if (styleString.contains(QLatin1String("Oblique"))
- || styleString.contains(QApplication::translate("QFontDatabase", "Oblique")))
+ || styleString.contains(QCoreApplication::translate("QFontDatabase", "Oblique")))
style = QFont::StyleOblique;
}
@@ -755,7 +755,7 @@ void QFontDatabasePrivate::invalidate()
{
QFontCache::instance()->clear();
free();
- emit static_cast<QApplication *>(QApplication::instance())->fontDatabaseChanged();
+ emit static_cast<QGuiApplication *>(QCoreApplication::instance())->fontDatabaseChanged();
}
QtFontFamily *QFontDatabasePrivate::family(const QString &f, bool create)
@@ -1520,21 +1520,21 @@ static QString styleStringHelper(int weight, QFont::Style style)
{
QString result;
if (weight >= QFont::Black)
- result = QApplication::translate("QFontDatabase", "Black");
+ result = QCoreApplication::translate("QFontDatabase", "Black");
else if (weight >= QFont::Bold)
- result = QApplication::translate("QFontDatabase", "Bold");
+ result = QCoreApplication::translate("QFontDatabase", "Bold");
else if (weight >= QFont::DemiBold)
- result = QApplication::translate("QFontDatabase", "Demi Bold");
+ result = QCoreApplication::translate("QFontDatabase", "Demi Bold");
else if (weight < QFont::Normal)
- result = QApplication::translate("QFontDatabase", "Light");
+ result = QCoreApplication::translate("QFontDatabase", "Light");
if (style == QFont::StyleItalic)
- result += QLatin1Char(' ') + QApplication::translate("QFontDatabase", "Italic");
+ result += QLatin1Char(' ') + QCoreApplication::translate("QFontDatabase", "Italic");
else if (style == QFont::StyleOblique)
- result += QLatin1Char(' ') + QApplication::translate("QFontDatabase", "Oblique");
+ result += QLatin1Char(' ') + QCoreApplication::translate("QFontDatabase", "Oblique");
if (result.isEmpty())
- result = QApplication::translate("QFontDatabase", "Normal");
+ result = QCoreApplication::translate("QFontDatabase", "Normal");
return result.simplified();
}
@@ -2026,7 +2026,7 @@ QFont QFontDatabase::font(const QString &family, const QString &style,
QtFontFoundry allStyles(foundryName);
QtFontFamily *f = d->family(familyName);
- if (!f) return QApplication::font();
+ if (!f) return QGuiApplication::font();
for (int j = 0; j < f->count; j++) {
QtFontFoundry *foundry = f->foundries[j];
@@ -2040,7 +2040,7 @@ QFont QFontDatabase::font(const QString &family, const QString &style,
QtFontStyle *s = bestStyle(&allStyles, styleKey, style);
if (!s) // no styles found?
- return QApplication::font();
+ return QGuiApplication::font();
QFont fnt(family, pointSize, s->key.weight);
fnt.setStyle((QFont::Style)s->key.style);
@@ -2363,7 +2363,7 @@ QString QFontDatabase::writingSystemName(WritingSystem writingSystem)
Q_ASSERT_X(false, "QFontDatabase::writingSystemName", "invalid 'writingSystem' parameter");
break;
}
- return QApplication::translate("QFontDatabase", name);
+ return QCoreApplication::translate("QFontDatabase", name);
}
diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h
index b1f370e6d1..994a7a4a7d 100644
--- a/src/gui/text/qfontdatabase.h
+++ b/src/gui/text/qfontdatabase.h
@@ -45,10 +45,6 @@
#include <QtGui/qwindowdefs.h>
#include <QtCore/qstring.h>
#include <QtGui/qfont.h>
-#ifdef QT3_SUPPORT
-#include <QtCore/qstringlist.h>
-#include <QtCore/qlist.h>
-#endif
QT_BEGIN_HEADER
diff --git a/src/gui/text/qfontdatabase_mac.cpp b/src/gui/text/qfontdatabase_mac.cpp
deleted file mode 100644
index 6876fae630..0000000000
--- a/src/gui/text/qfontdatabase_mac.cpp
+++ /dev/null
@@ -1,494 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/qt_mac_p.h>
-#include "qfontengine_p.h"
-#include <qfile.h>
-#include <qabstractfileengine.h>
-#include <stdlib.h>
-#include <qendian.h>
-#include <private/qfontengine_coretext_p.h>
-#include <private/qfontengine_mac_p.h>
-
-QT_BEGIN_NAMESPACE
-
-int qt_mac_pixelsize(const QFontDef &def, int dpi); //qfont_mac.cpp
-int qt_mac_pointsize(const QFontDef &def, int dpi); //qfont_mac.cpp
-
-#ifndef QT_MAC_USE_COCOA
-static void initWritingSystems(QtFontFamily *family, ATSFontRef atsFont)
-{
- ByteCount length = 0;
- if (ATSFontGetTable(atsFont, MAKE_TAG('O', 'S', '/', '2'), 0, 0, 0, &length) != noErr)
- return;
- QVarLengthArray<uchar> os2Table(length);
- if (length < 86
- || ATSFontGetTable(atsFont, MAKE_TAG('O', 'S', '/', '2'), 0, length, os2Table.data(), &length) != noErr)
- return;
-
- // See also qfontdatabase_win.cpp, offsets taken from OS/2 table in the TrueType spec
- quint32 unicodeRange[4] = {
- qFromBigEndian<quint32>(os2Table.data() + 42),
- qFromBigEndian<quint32>(os2Table.data() + 46),
- qFromBigEndian<quint32>(os2Table.data() + 50),
- qFromBigEndian<quint32>(os2Table.data() + 54)
- };
- quint32 codePageRange[2] = { qFromBigEndian<quint32>(os2Table.data() + 78), qFromBigEndian<quint32>(os2Table.data() + 82) };
- QList<QFontDatabase::WritingSystem> systems = qt_determine_writing_systems_from_truetype_bits(unicodeRange, codePageRange);
-#if 0
- QCFString name;
- ATSFontGetName(atsFont, kATSOptionFlagsDefault, &name);
- qDebug() << systems.count() << "writing systems for" << QString(name);
-qDebug() << "first char" << hex << unicodeRange[0];
- for (int i = 0; i < systems.count(); ++i)
- qDebug() << QFontDatabase::writingSystemName(systems.at(i));
-#endif
- for (int i = 0; i < systems.count(); ++i)
- family->writingSystems[systems.at(i)] = QtFontFamily::Supported;
-}
-#endif
-
-static void initializeDb()
-{
- QFontDatabasePrivate *db = privateDb();
- if(!db || db->count)
- return;
-
-#if defined(QT_MAC_USE_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
- QCFType<CTFontCollectionRef> collection = CTFontCollectionCreateFromAvailableFonts(0);
- if(!collection)
- return;
- QCFType<CFArrayRef> fonts = CTFontCollectionCreateMatchingFontDescriptors(collection);
- if(!fonts)
- return;
- QString foundry_name = "CoreText";
- const int numFonts = CFArrayGetCount(fonts);
- for(int i = 0; i < numFonts; ++i) {
- CTFontDescriptorRef font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fonts, i);
-
- QCFString family_name = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute);
- QCFString style_name = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontStyleNameAttribute);
- QtFontFamily *family = db->family(family_name, true);
- for(int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws)
- family->writingSystems[ws] = QtFontFamily::Supported;
- QtFontFoundry *foundry = family->foundry(foundry_name, true);
-
- QtFontStyle::Key styleKey;
- QString styleName = style_name;
- if(QCFType<CFDictionaryRef> styles = (CFDictionaryRef)CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute)) {
- if(CFNumberRef weight = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontWeightTrait)) {
- Q_ASSERT(CFNumberIsFloatType(weight));
- double d;
- if(CFNumberGetValue(weight, kCFNumberDoubleType, &d)) {
- //qDebug() << "BOLD" << (QString)family_name << d;
- styleKey.weight = (d > 0.0) ? QFont::Bold : QFont::Normal;
- }
- }
- if(CFNumberRef italic = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontSlantTrait)) {
- Q_ASSERT(CFNumberIsFloatType(italic));
- double d;
- if(CFNumberGetValue(italic, kCFNumberDoubleType, &d)) {
- //qDebug() << "ITALIC" << (QString)family_name << d;
- if (d > 0.0)
- styleKey.style = QFont::StyleItalic;
- }
- }
- }
-
- QtFontStyle *style = foundry->style(styleKey, styleName, true);
- style->smoothScalable = true;
- if(QCFType<CFNumberRef> size = (CFNumberRef)CTFontDescriptorCopyAttribute(font, kCTFontSizeAttribute)) {
- //qDebug() << "WHEE";
- int pixel_size=0;
- if(CFNumberIsFloatType(size)) {
- double d;
- CFNumberGetValue(size, kCFNumberDoubleType, &d);
- pixel_size = d;
- } else {
- CFNumberGetValue(size, kCFNumberIntType, &pixel_size);
- }
- //qDebug() << "SIZE" << (QString)family_name << pixel_size;
- if(pixel_size)
- style->pixelSize(pixel_size, true);
- } else {
- //qDebug() << "WTF?";
- }
- }
-} else
-#endif
- {
-#ifndef QT_MAC_USE_COCOA
- FMFontIterator it;
- if (!FMCreateFontIterator(0, 0, kFMUseGlobalScopeOption, &it)) {
- while (true) {
- FMFont fmFont;
- if (FMGetNextFont(&it, &fmFont) != noErr)
- break;
-
- FMFontFamily fmFamily;
- FMFontStyle fmStyle;
- QString familyName;
-
- QtFontStyle::Key styleKey;
-
- ATSFontRef atsFont = FMGetATSFontRefFromFont(fmFont);
-
- if (!FMGetFontFamilyInstanceFromFont(fmFont, &fmFamily, &fmStyle)) {
- { //sanity check the font, and see if we can use it at all! --Sam
- ATSUFontID fontID;
- if(ATSUFONDtoFontID(fmFamily, 0, &fontID) != noErr)
- continue;
- }
-
- if (fmStyle & ::italic)
- styleKey.style = QFont::StyleItalic;
- if (fmStyle & ::bold)
- styleKey.weight = QFont::Bold;
-
- ATSFontFamilyRef familyRef = FMGetATSFontFamilyRefFromFontFamily(fmFamily);
- QCFString cfFamilyName;;
- ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &cfFamilyName);
- familyName = cfFamilyName;
- } else {
- QCFString cfFontName;
- ATSFontGetName(atsFont, kATSOptionFlagsDefault, &cfFontName);
- familyName = cfFontName;
- quint16 macStyle = 0;
- {
- uchar data[4];
- ByteCount len = 4;
- if (ATSFontGetTable(atsFont, MAKE_TAG('h', 'e', 'a', 'd'), 44, 4, &data, &len) == noErr)
- macStyle = qFromBigEndian<quint16>(data);
- }
- if (macStyle & 1)
- styleKey.weight = QFont::Bold;
- if (macStyle & 2)
- styleKey.style = QFont::StyleItalic;
- }
-
- QtFontFamily *family = db->family(familyName, true);
- QtFontFoundry *foundry = family->foundry(QString(), true);
- QtFontStyle *style = foundry->style(styleKey, QString(), true);
- style->pixelSize(0, true);
- style->smoothScalable = true;
-
- initWritingSystems(family, atsFont);
- }
- FMDisposeFontIterator(&it);
- }
-#endif
- }
-
-}
-
-static inline void load(const QString & = QString(), int = -1)
-{
- initializeDb();
-}
-
-static const char *styleHint(const QFontDef &request)
-{
- const char *stylehint = 0;
- switch (request.styleHint) {
- case QFont::SansSerif:
- stylehint = "Arial";
- break;
- case QFont::Serif:
- stylehint = "Times New Roman";
- break;
- case QFont::TypeWriter:
- stylehint = "Courier New";
- break;
- default:
- if (request.fixedPitch)
- stylehint = "Courier New";
- break;
- }
- return stylehint;
-}
-
-static inline float weightToFloat(unsigned int weight)
-{
- return (weight - 50) / 100.0;
-}
-
-static QFontEngine *loadFromDatabase(const QFontDef &req, const QFontPrivate *d)
-{
-#if defined(QT_MAC_USE_COCOA)
- QCFString fontName = NULL;
-#else
- ATSFontFamilyRef familyRef = 0;
- ATSFontRef fontRef = 0;
-#endif
-
- QStringList family_list = familyList(req);
-
- const char *stylehint = styleHint(req);
- if (stylehint)
- family_list << QLatin1String(stylehint);
-
- // add QFont::defaultFamily() to the list, for compatibility with previous versions
- family_list << QApplication::font().defaultFamily();
-
- QMutexLocker locker(fontDatabaseMutex());
- QFontDatabasePrivate *db = privateDb();
- if (!db->count)
- initializeDb();
- for (int i = 0; i < family_list.size(); ++i) {
- for (int k = 0; k < db->count; ++k) {
- if (db->families[k]->name.compare(family_list.at(i), Qt::CaseInsensitive) == 0) {
- QByteArray family_name = db->families[k]->name.toUtf8();
-#if defined(QT_MAC_USE_COCOA)
- QCFType<CTFontRef> ctFont = CTFontCreateWithName(QCFString(db->families[k]->name), 12, NULL);
- if (ctFont) {
- fontName = CTFontCopyFullName(ctFont);
- goto found;
- }
-#else
- familyRef = ATSFontFamilyFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
- if (familyRef) {
- fontRef = ATSFontFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
- goto found;
- }
-#endif
- }
- }
- }
-found:
-#ifdef QT_MAC_USE_COCOA
- if (fontName)
- return new QCoreTextFontEngineMulti(fontName, req, d->kerning);
-#else
- if (familyRef) {
- QCFString actualName;
- if (ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr)
- req.family = actualName;
- return new QFontEngineMacMulti(familyRef, req, fontDef, d->kerning);
- }
-#endif
- return NULL;
-}
-
-void QFontDatabase::load(const QFontPrivate *d, int script)
-{
- // sanity checks
- if(!qApp)
- qWarning("QFont: Must construct a QApplication before a QFont");
-
- Q_ASSERT(script >= 0 && script < QUnicodeTables::ScriptCount);
- Q_UNUSED(script);
-
- QFontDef req = d->request;
- req.pixelSize = qt_mac_pixelsize(req, d->dpi);
-
- // set the point size to 0 to get better caching
- req.pointSize = 0;
- QFontCache::Key key = QFontCache::Key(req, QUnicodeTables::Common, d->screen);
-
- if(!(d->engineData = QFontCache::instance()->findEngineData(key))) {
- d->engineData = new QFontEngineData;
- QFontCache::instance()->insertEngineData(key, d->engineData);
- } else {
- d->engineData->ref.ref();
- }
- if(d->engineData->engine) // already loaded
- return;
-
- // set it to the actual pointsize, so QFontInfo will do the right thing
- req.pointSize = qt_mac_pointsize(d->request, d->dpi);
-
- QFontEngine *e = QFontCache::instance()->findEngine(key);
- if(!e && qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) {
- e = new QTestFontEngine(req.pixelSize);
- e->fontDef = req;
- }
-
- if(e) {
- e->ref.ref();
- d->engineData->engine = e;
- return; // the font info and fontdef should already be filled
- }
-
- QFontEngine *engine = NULL;
-#if defined(QT_MAC_USE_COCOA)
- // Shortcut to get the font directly without going through the font database
- if (!req.family.isEmpty() && !req.styleName.isEmpty()) {
- QCFString expectedFamily = QCFString(req.family);
- QCFString expectedStyle = QCFString(req.styleName);
-
- QCFType<CFMutableDictionaryRef> attributes = CFDictionaryCreateMutable(NULL, 0,
- &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, expectedFamily);
- CFDictionaryAddValue(attributes, kCTFontStyleNameAttribute, expectedStyle);
-
- QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithAttributes(attributes);
- CGAffineTransform transform = qt_transform_from_fontdef(req);
- QCFType<CTFontRef> ctFont = CTFontCreateWithFontDescriptor(descriptor, req.pixelSize, &transform);
- if (ctFont) {
- QCFString familyName = CTFontCopyFamilyName(ctFont);
- // Only accept the font if the family name is exactly the same as we specified
- if (CFEqual(expectedFamily, familyName)) {
- engine = new QCoreTextFontEngineMulti(ctFont, req, d->kerning);
- }
- }
- }
-#endif
- if (!engine)
- engine = loadFromDatabase(req, d);
-
- if (engine) {
- d->engineData->engine = engine;
- engine->ref.ref();
- QFontCache::instance()->insertEngine(key, engine);
- }
-}
-
-static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
-{
- ATSFontContainerRef handle;
- OSStatus e = noErr;
-
- if(fnt->data.isEmpty()) {
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
- extern OSErr qt_mac_create_fsref(const QString &, FSRef *); // qglobal.cpp
- FSRef ref;
- if(qt_mac_create_fsref(fnt->fileName, &ref) != noErr)
- return;
-
- ATSFontActivateFromFileReference(&ref, kATSFontContextLocal, kATSFontFormatUnspecified, 0, kATSOptionFlagsDefault, &handle);
- } else
-#endif
- {
-#ifndef Q_WS_MAC64
- extern Q_CORE_EXPORT OSErr qt_mac_create_fsspec(const QString &, FSSpec *); // global.cpp
- FSSpec spec;
- if(qt_mac_create_fsspec(fnt->fileName, &spec) != noErr)
- return;
-
- e = ATSFontActivateFromFileSpecification(&spec, kATSFontContextLocal, kATSFontFormatUnspecified,
- 0, kATSOptionFlagsDefault, &handle);
-#endif
- }
- } else {
- e = ATSFontActivateFromMemory((void *)fnt->data.constData(), fnt->data.size(), kATSFontContextLocal,
- kATSFontFormatUnspecified, 0, kATSOptionFlagsDefault, &handle);
-
- fnt->data = QByteArray();
- }
-
- if(e != noErr)
- return;
-
- ItemCount fontCount = 0;
- e = ATSFontFindFromContainer(handle, kATSOptionFlagsDefault, 0, 0, &fontCount);
- if(e != noErr)
- return;
-
- QVarLengthArray<ATSFontRef> containedFonts(fontCount);
- e = ATSFontFindFromContainer(handle, kATSOptionFlagsDefault, fontCount, containedFonts.data(), &fontCount);
- if(e != noErr)
- return;
-
- fnt->families.clear();
-#if defined(QT_MAC_USE_COCOA)
- // Make sure that the family name set on the font matches what
- // kCTFontFamilyNameAttribute returns in initializeDb().
- // So far the best solution seems find the installed font
- // using CoreText and get the family name from it.
- // (ATSFontFamilyGetName appears to be the correct API, but also
- // returns the font display name.)
- for(int i = 0; i < containedFonts.size(); ++i) {
- QCFString fontPostScriptName;
- ATSFontGetPostScriptName(containedFonts[i], kATSOptionFlagsDefault, &fontPostScriptName);
- QCFType<CTFontDescriptorRef> font = CTFontDescriptorCreateWithNameAndSize(fontPostScriptName, 14);
- QCFString familyName = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute);
- fnt->families.append(familyName);
- }
-#else
- for(int i = 0; i < containedFonts.size(); ++i) {
- QCFString family;
- ATSFontGetName(containedFonts[i], kATSOptionFlagsDefault, &family);
- fnt->families.append(family);
- }
-#endif
-
- fnt->handle = handle;
-}
-
-bool QFontDatabase::removeApplicationFont(int handle)
-{
- QMutexLocker locker(fontDatabaseMutex());
-
- QFontDatabasePrivate *db = privateDb();
- if(handle < 0 || handle >= db->applicationFonts.count())
- return false;
-
- OSStatus e = ATSFontDeactivate(db->applicationFonts.at(handle).handle,
- /*iRefCon=*/0, kATSOptionFlagsDefault);
- if(e != noErr)
- return false;
-
- db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont();
-
- db->invalidate();
- return true;
-}
-
-bool QFontDatabase::removeAllApplicationFonts()
-{
- QMutexLocker locker(fontDatabaseMutex());
-
- QFontDatabasePrivate *db = privateDb();
- for(int i = 0; i < db->applicationFonts.count(); ++i) {
- if(!removeApplicationFont(i))
- return false;
- }
- return true;
-}
-
-bool QFontDatabase::supportsThreadedFontRendering()
-{
- return true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp
index 032a42b9b1..c0edce1009 100644
--- a/src/gui/text/qfontdatabase_qpa.cpp
+++ b/src/gui/text/qfontdatabase_qpa.cpp
@@ -45,7 +45,7 @@
#include "qfontengine_qpa_p.h"
#include "qplatformdefs.h"
-#include <QtGui/private/qapplication_p.h>
+#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qplatformfontdatabase_qpa.h>
#include <QtCore/qmath.h>
@@ -82,7 +82,7 @@ Q_GUI_EXPORT void qt_registerFont(const QString &familyName, const QString &fou
static QStringList fallbackFamilies(const QString &family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script)
{
- QStringList retList = QApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(family,style,styleHint,script);
+ QStringList retList = QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(family,style,styleHint,script);
QFontDatabasePrivate *db = privateDb();
QStringList::iterator i;
@@ -109,28 +109,11 @@ static void initializeDb()
if (!initialized) {
//init by asking for the platformfontdb for the first time :)
- QApplicationPrivate::platformIntegration()->fontDatabase()->populateFontDatabase();
+ QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFontDatabase();
initialized = true;
}
}
-#ifndef QT_NO_SETTINGS
-// called from qapplication_qws.cpp
-void qt_applyFontDatabaseSettings(const QSettings &settings)
-{
- initializeDb();
- QFontDatabasePrivate *db = privateDb();
- for (int i = 0; i < db->count; ++i) {
- QtFontFamily *family = db->families[i];
- if (settings.contains(family->name))
- family->fallbackFamilies = settings.value(family->name).toStringList();
- }
-
- if (settings.contains(QLatin1String("Global Fallbacks")))
- db->fallbackFamilies = settings.value(QLatin1String("Global Fallbacks")).toStringList();
-}
-#endif // QT_NO_SETTINGS
-
static inline void load(const QString & = QString(), int = -1)
{
initializeDb();
@@ -155,7 +138,7 @@ QFontEngine *loadSingleEngine(int script,
QFontCache::Key key(def,script);
QFontEngine *engine = QFontCache::instance()->findEngine(key);
if (!engine) {
- QPlatformFontDatabase *pfdb = QApplicationPrivate::platformIntegration()->fontDatabase();
+ QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
engine = pfdb->fontEngine(def,QUnicodeTables::Script(script),size->handle);
if (engine) {
QFontCache::Key key(def,script);
@@ -173,7 +156,7 @@ QFontEngine *loadEngine(int script, const QFontDef &request,
QFontEngine *engine = loadSingleEngine(script, request, foundry, style, size);
//make sure that the db has all fallback families
- if (engine
+ if (engine && engine->type() != QFontEngine::Multi
&& !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol ) {
if (family && !family->askedForFallback) {
@@ -200,7 +183,7 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
{
QFontDatabasePrivate *db = privateDb();
- fnt->families = QApplicationPrivate::platformIntegration()->fontDatabase()->addApplicationFont(fnt->data,fnt->fileName);
+ fnt->families = QGuiApplicationPrivate::platformIntegration()->fontDatabase()->addApplicationFont(fnt->data,fnt->fileName);
db->reregisterAppFonts = true;
}
@@ -359,7 +342,7 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
family_list = familyList(req);
// add the default family
- QString defaultFamily = QApplication::font().family();
+ QString defaultFamily = QGuiApplication::font().family();
if (! family_list.contains(defaultFamily))
family_list << defaultFamily;
diff --git a/src/gui/text/qfontdatabase_qws.cpp b/src/gui/text/qfontdatabase_qws.cpp
deleted file mode 100644
index c83e9297d9..0000000000
--- a/src/gui/text/qfontdatabase_qws.cpp
+++ /dev/null
@@ -1,972 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdir.h"
-#if defined(Q_WS_QWS)
-#include "qscreen_qws.h" //so we can check for rotation
-#include "qwindowsystem_qws.h"
-#endif
-#include "qlibraryinfo.h"
-#include "qabstractfileengine.h"
-#include <QtCore/qsettings.h>
-#if !defined(QT_NO_FREETYPE)
-#include "qfontengine_ft_p.h"
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-
-#endif
-#include "qfontengine_qpf_p.h"
-#include "private/qfactoryloader_p.h"
-#include "private/qcore_unix_p.h" // overrides QT_OPEN
-#include "qabstractfontengine_qws.h"
-#include "qabstractfontengine_p.h"
-#include <qdatetime.h>
-#include "qplatformdefs.h"
-
-// for mmap
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#ifdef QT_FONTS_ARE_RESOURCES
-#include <qresource.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_LIBRARY
-Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
- (QFontEngineFactoryInterface_iid, QLatin1String("/fontengines"), Qt::CaseInsensitive))
-#endif
-
-const quint8 DatabaseVersion = 4;
-
-// QFontDatabasePrivate::addFont() went into qfontdatabase.cpp
-
-#ifndef QT_NO_QWS_QPF2
-void QFontDatabasePrivate::addQPF2File(const QByteArray &file)
-{
-#ifndef QT_FONTS_ARE_RESOURCES
- struct stat st;
- if (stat(file.constData(), &st))
- return;
- int f = QT_OPEN(file, O_RDONLY, 0);
- if (f < 0)
- return;
- const uchar *data = (const uchar *)mmap(0, st.st_size, PROT_READ, MAP_SHARED, f, 0);
- const int dataSize = st.st_size;
-#else
- QResource res(QLatin1String(file.constData()));
- const uchar *data = res.data();
- const int dataSize = res.size();
- //qDebug() << "addQPF2File" << file << data;
-#endif
- if (data && data != (const uchar *)MAP_FAILED) {
- if (QFontEngineQPF::verifyHeader(data, dataSize)) {
- QString fontName = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_FontName).toString();
- int pixelSize = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_PixelSize).toInt();
- QVariant weight = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_Weight);
- QVariant style = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_Style);
- QByteArray writingSystemBits = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_WritingSystems).toByteArray();
-
- if (!fontName.isEmpty() && pixelSize) {
- int fontWeight = 50;
- if (weight.type() == QVariant::Int || weight.type() == QVariant::UInt)
- fontWeight = weight.toInt();
-
- bool italic = static_cast<QFont::Style>(style.toInt()) & QFont::StyleItalic;
-
- QList<QFontDatabase::WritingSystem> writingSystems;
- for (int i = 0; i < writingSystemBits.count(); ++i) {
- uchar currentByte = writingSystemBits.at(i);
- for (int j = 0; j < 8; ++j) {
- if (currentByte & 1)
- writingSystems << QFontDatabase::WritingSystem(i * 8 + j);
- currentByte >>= 1;
- }
- }
-
- addFont(fontName, /*foundry*/ "prerendered", fontWeight, italic,
- pixelSize, file, /*fileIndex*/ 0,
- /*antialiased*/ true, writingSystems);
- }
- } else {
- qDebug() << "header verification of QPF2 font" << file << "failed. maybe it is corrupt?";
- }
-#ifndef QT_FONTS_ARE_RESOURCES
- munmap((void *)data, st.st_size);
-#endif
- }
-#ifndef QT_FONTS_ARE_RESOURCES
- QT_CLOSE(f);
-#endif
-}
-#endif // QT_NO_QWS_QPF2
-
-// QFontDatabasePrivate::addTTFile() went into qfontdatabase.cpp
-
-static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt);
-
-extern QString qws_fontCacheDir();
-
-#ifndef QT_FONTS_ARE_RESOURCES
-bool QFontDatabasePrivate::loadFromCache(const QString &fontPath)
-{
-#ifdef Q_WS_QWS
- const bool weAreTheServer = QWSServer::instance();
-#else
- const bool weAreTheServer = true; // assume single-process
-#endif
-
- QString fontDirFile = fontPath + QLatin1String("/fontdir");
-
- QFile binaryDb(qws_fontCacheDir() + QLatin1String("/fontdb"));
-
- if (weAreTheServer) {
- QDateTime dbTimeStamp = QFileInfo(binaryDb.fileName()).lastModified();
-
- QDateTime fontPathTimeStamp = QFileInfo(fontPath).lastModified();
- if (dbTimeStamp < fontPathTimeStamp)
- return false; // let the caller create the cache
-
- if (QFile::exists(fontDirFile)) {
- QDateTime fontDirTimeStamp = QFileInfo(fontDirFile).lastModified();
- if (dbTimeStamp < fontDirTimeStamp)
- return false;
- }
- }
-
- if (!binaryDb.open(QIODevice::ReadOnly)) {
- if (weAreTheServer)
- return false; // let the caller create the cache
- qFatal("QFontDatabase::loadFromCache: Could not open font database cache!");
- }
-
- QDataStream stream(&binaryDb);
- quint8 version = 0;
- quint8 dataStreamVersion = 0;
- stream >> version >> dataStreamVersion;
- if (version != DatabaseVersion || dataStreamVersion != stream.version()) {
- if (weAreTheServer)
- return false; // let the caller create the cache
- qFatal("QFontDatabase::loadFromCache: Wrong version of the font database cache detected. Found %d/%d expected %d/%d",
- version, dataStreamVersion, DatabaseVersion, stream.version());
- }
-
- QString originalFontPath;
- stream >> originalFontPath;
- if (originalFontPath != fontPath) {
- if (weAreTheServer)
- return false; // let the caller create the cache
- qFatal("QFontDatabase::loadFromCache: Font path doesn't match. Found %s in database, expected %s", qPrintable(originalFontPath), qPrintable(fontPath));
- }
-
- QString familyname;
- stream >> familyname;
- //qDebug() << "populating database from" << binaryDb.fileName();
- while (!familyname.isEmpty() && !stream.atEnd()) {
- QString foundryname;
- int weight;
- quint8 italic;
- int pixelSize;
- QByteArray file;
- int fileIndex;
- quint8 antialiased;
- quint8 writingSystemCount;
-
- QList<QFontDatabase::WritingSystem> writingSystems;
-
- stream >> foundryname >> weight >> italic >> pixelSize
- >> file >> fileIndex >> antialiased >> writingSystemCount;
-
- for (quint8 i = 0; i < writingSystemCount; ++i) {
- quint8 ws;
- stream >> ws;
- writingSystems.append(QFontDatabase::WritingSystem(ws));
- }
-
- addFont(familyname, foundryname.toLatin1().constData(), weight, italic, pixelSize, file, fileIndex, antialiased,
- writingSystems);
-
- stream >> familyname;
- }
-
- stream >> fallbackFamilies;
- //qDebug() << "fallback families from cache:" << fallbackFamilies;
- return true;
-}
-#endif // QT_FONTS_ARE_RESOURCES
-
-/*!
- \internal
-*/
-
-static QString qwsFontPath()
-{
- QString fontpath = QString::fromLocal8Bit(qgetenv("QT_QWS_FONTDIR"));
- if (fontpath.isEmpty()) {
-#ifdef QT_FONTS_ARE_RESOURCES
- fontpath = QLatin1String(":/qt/fonts");
-#else
-#ifndef QT_NO_SETTINGS
- fontpath = QLibraryInfo::location(QLibraryInfo::LibrariesPath);
- fontpath += QLatin1String("/fonts");
-#else
- fontpath = QLatin1String("/lib/fonts");
-#endif
-#endif //QT_FONTS_ARE_RESOURCES
- }
-
- return fontpath;
-}
-
-#if defined(QFONTDATABASE_DEBUG) && defined(QT_FONTS_ARE_RESOURCES)
-class FriendlyResource : public QResource
-{
-public:
- bool isDir () const { return QResource::isDir(); }
- bool isFile () const { return QResource::isFile(); }
- QStringList children () const { return QResource::children(); }
-};
-#endif
-/*!
- \internal
-*/
-static void initializeDb()
-{
- QFontDatabasePrivate *db = privateDb();
- if (!db || db->count)
- return;
-
- QString fontpath = qwsFontPath();
-#ifndef QT_FONTS_ARE_RESOURCES
- QString fontDirFile = fontpath + QLatin1String("/fontdir");
-
- if(!QFile::exists(fontpath)) {
- qFatal("QFontDatabase: Cannot find font directory %s - is Qt installed correctly?",
- fontpath.toLocal8Bit().constData());
- }
-
- const bool loaded = db->loadFromCache(fontpath);
-
- if (db->reregisterAppFonts) {
- db->reregisterAppFonts = false;
- for (int i = 0; i < db->applicationFonts.count(); ++i)
- if (!db->applicationFonts.at(i).families.isEmpty()) {
- registerFont(&db->applicationFonts[i]);
- }
- }
-
- if (loaded)
- return;
-
- QString dbFileName = qws_fontCacheDir() + QLatin1String("/fontdb");
-
- QFile binaryDb(dbFileName + QLatin1String(".tmp"));
- binaryDb.open(QIODevice::WriteOnly | QIODevice::Truncate);
- db->stream = new QDataStream(&binaryDb);
- *db->stream << DatabaseVersion << quint8(db->stream->version()) << fontpath;
-// qDebug() << "creating binary database at" << binaryDb.fileName();
-
- // Load in font definition file
- FILE* fontdef=fopen(fontDirFile.toLocal8Bit().constData(),"r");
- if (fontdef) {
- char buf[200]="";
- char name[200]="";
- char render[200]="";
- char file[200]="";
- char isitalic[10]="";
- char flags[10]="";
- do {
- fgets(buf,200,fontdef);
- if (buf[0] != '#') {
- int weight=50;
- int size=0;
- sscanf(buf,"%s %s %s %s %d %d %s",name,file,render,isitalic,&weight,&size,flags);
- QString filename;
- if (file[0] != '/')
- filename.append(fontpath).append(QLatin1Char('/'));
- filename += QLatin1String(file);
- bool italic = isitalic[0] == 'y';
- bool smooth = QByteArray(flags).contains('s');
- if (file[0] && QFile::exists(filename))
- db->addFont(QString::fromUtf8(name), /*foundry*/"", weight, italic, size/10, QFile::encodeName(filename), /*fileIndex*/ 0, smooth);
- }
- } while (!feof(fontdef));
- fclose(fontdef);
- }
-
-
- QDir dir(fontpath, QLatin1String("*.qpf"));
- for (int i=0; i<int(dir.count()); i++) {
- int u0 = dir[i].indexOf(QLatin1Char('_'));
- int u1 = dir[i].indexOf(QLatin1Char('_'), u0+1);
- int u2 = dir[i].indexOf(QLatin1Char('_'), u1+1);
- int u3 = dir[i].indexOf(QLatin1Char('.'), u1+1);
- if (u2 < 0) u2 = u3;
-
- QString familyname = dir[i].left(u0);
- int pixelSize = dir[i].mid(u0+1,u1-u0-1).toInt()/10;
- bool italic = dir[i].mid(u2-1,1) == QLatin1String("i");
- int weight = dir[i].mid(u1+1,u2-u1-1-(italic?1:0)).toInt();
-
- db->addFont(familyname, /*foundry*/ "qt", weight, italic, pixelSize, QFile::encodeName(dir.absoluteFilePath(dir[i])),
- /*fileIndex*/ 0, /*antialiased*/ true);
- }
-
-#ifndef QT_NO_FREETYPE
- dir.setNameFilters(QStringList() << QLatin1String("*.ttf")
- << QLatin1String("*.ttc") << QLatin1String("*.pfa")
- << QLatin1String("*.pfb"));
- dir.refresh();
- for (int i = 0; i < int(dir.count()); ++i) {
- const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
-// qDebug() << "looking at" << file;
- db->addTTFile(file);
- }
-#endif
-
-#ifndef QT_NO_QWS_QPF2
- dir.setNameFilters(QStringList() << QLatin1String("*.qpf2"));
- dir.refresh();
- for (int i = 0; i < int(dir.count()); ++i) {
- const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
-// qDebug() << "looking at" << file;
- db->addQPF2File(file);
- }
-#endif
-
-#else //QT_FONTS_ARE_RESOURCES
-#ifdef QFONTDATABASE_DEBUG
- {
- QResource fontdir(fontpath);
- FriendlyResource *fr = static_cast<FriendlyResource*>(&fontdir);
- qDebug() << "fontdir" << fr->isValid() << fr->isDir() << fr->children();
-
- }
-#endif
-#ifndef QT_NO_QWS_QPF2
- QDir dir(fontpath, QLatin1String("*.qpf2"));
- for (int i = 0; i < int(dir.count()); ++i) {
- const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
- //qDebug() << "looking at" << file;
- db->addQPF2File(file);
- }
-#endif
-#endif //QT_FONTS_ARE_RESOURCES
-
-
-#ifdef QFONTDATABASE_DEBUG
- // print the database
- for (int f = 0; f < db->count; f++) {
- QtFontFamily *family = db->families[f];
- FD_DEBUG("'%s' %s", qPrintable(family->name), (family->fixedPitch ? "fixed" : ""));
-#if 0
- for (int i = 0; i < QFont::LastPrivateScript; ++i) {
- FD_DEBUG("\t%s: %s", qPrintable(QFontDatabase::scriptName((QFont::Script) i)),
- ((family->scripts[i] & QtFontFamily::Supported) ? "Supported" :
- (family->scripts[i] & QtFontFamily::UnSupported) == QtFontFamily::UnSupported ?
- "UnSupported" : "Unknown"));
- }
-#endif
-
- for (int fd = 0; fd < family->count; fd++) {
- QtFontFoundry *foundry = family->foundries[fd];
- FD_DEBUG("\t\t'%s'", qPrintable(foundry->name));
- for (int s = 0; s < foundry->count; s++) {
- QtFontStyle *style = foundry->styles[s];
- FD_DEBUG("\t\t\tstyle: style=%d weight=%d\n"
- "\t\t\tstretch=%d",
- style->key.style, style->key.weight,
- style->key.stretch);
- if (style->smoothScalable)
- FD_DEBUG("\t\t\t\tsmooth scalable");
- else if (style->bitmapScalable)
- FD_DEBUG("\t\t\t\tbitmap scalable");
- if (style->pixelSizes) {
- FD_DEBUG("\t\t\t\t%d pixel sizes", style->count);
- for (int z = 0; z < style->count; ++z) {
- QtFontSize *size = style->pixelSizes + z;
- FD_DEBUG("\t\t\t\t size %5d",
- size->pixelSize);
- }
- }
- }
- }
- }
-#endif // QFONTDATABASE_DEBUG
-
-#ifndef QT_NO_LIBRARY
- QStringList pluginFoundries = loader()->keys();
-// qDebug() << "plugin foundries:" << pluginFoundries;
- for (int i = 0; i < pluginFoundries.count(); ++i) {
- const QString foundry(pluginFoundries.at(i));
-
- QFontEngineFactoryInterface *factory = qobject_cast<QFontEngineFactoryInterface *>(loader()->instance(foundry));
- if (!factory) {
- qDebug() << "Could not load plugin for foundry" << foundry;
- continue;
- }
-
- QList<QFontEngineInfo> fonts = factory->availableFontEngines();
- for (int i = 0; i < fonts.count(); ++i) {
- QFontEngineInfo info = fonts.at(i);
-
- int weight = info.weight();
- if (weight <= 0)
- weight = QFont::Normal;
-
- db->addFont(info.family(), foundry.toLatin1().constData(),
- weight, info.style() != QFont::StyleNormal,
- qRound(info.pixelSize()), /*file*/QByteArray(),
- /*fileIndex*/0, /*antiAliased*/true,
- info.writingSystems());
- }
- }
-#endif
-
-#ifndef QT_FONTS_ARE_RESOURCES
- // the empty string/familyname signifies the end of the font list.
- *db->stream << QString();
-#endif
- {
- bool coveredWritingSystems[QFontDatabase::WritingSystemsCount] = { 0 };
-
- db->fallbackFamilies.clear();
-
- for (int i = 0; i < db->count; ++i) {
- QtFontFamily *family = db->families[i];
- bool add = false;
- if (family->count == 0)
- continue;
- if (family->bogusWritingSystems)
- continue;
- for (int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws) {
- if (coveredWritingSystems[ws])
- continue;
- if (family->writingSystems[ws] & QtFontFamily::Supported) {
- coveredWritingSystems[ws] = true;
- add = true;
- }
- }
- if (add)
- db->fallbackFamilies << family->name;
- }
- //qDebug() << "fallbacks on the server:" << db->fallbackFamilies;
-#ifndef QT_FONTS_ARE_RESOURCES
- *db->stream << db->fallbackFamilies;
-#endif
- }
-#ifndef QT_FONTS_ARE_RESOURCES
- delete db->stream;
- db->stream = 0;
- QFile::remove(dbFileName);
- binaryDb.rename(dbFileName);
-#endif
-}
-
-// called from qwindowsystem_qws.cpp
-void qt_qws_init_fontdb()
-{
- initializeDb();
-}
-
-#ifndef QT_NO_SETTINGS
-// called from qapplication_qws.cpp
-void qt_applyFontDatabaseSettings(const QSettings &settings)
-{
- initializeDb();
- QFontDatabasePrivate *db = privateDb();
- for (int i = 0; i < db->count; ++i) {
- QtFontFamily *family = db->families[i];
- if (settings.contains(family->name))
- family->fallbackFamilies = settings.value(family->name).toStringList();
- }
-
- if (settings.contains(QLatin1String("Global Fallbacks")))
- db->fallbackFamilies = settings.value(QLatin1String("Global Fallbacks")).toStringList();
-}
-#endif // QT_NO_SETTINGS
-
-static inline void load(const QString & = QString(), int = -1)
-{
- initializeDb();
-}
-
-#ifndef QT_NO_FREETYPE
-
-#if (FREETYPE_MAJOR*10000+FREETYPE_MINOR*100+FREETYPE_PATCH) >= 20105
-#define X_SIZE(face,i) ((face)->available_sizes[i].x_ppem)
-#define Y_SIZE(face,i) ((face)->available_sizes[i].y_ppem)
-#else
-#define X_SIZE(face,i) ((face)->available_sizes[i].width << 6)
-#define Y_SIZE(face,i) ((face)->available_sizes[i].height << 6)
-#endif
-
-#endif // QT_NO_FREETYPE
-
-static
-QFontEngine *loadSingleEngine(int script, const QFontPrivate *fp,
- const QFontDef &request,
- QtFontFamily *family, QtFontFoundry *foundry,
- QtFontStyle *style, QtFontSize *size)
-{
- Q_UNUSED(script);
- Q_UNUSED(fp);
-#ifdef QT_NO_FREETYPE
- Q_UNUSED(foundry);
-#endif
-#ifdef QT_NO_QWS_QPF
- Q_UNUSED(family);
-#endif
- Q_ASSERT(size);
-
- int pixelSize = size->pixelSize;
- if (!pixelSize || (style->smoothScalable && pixelSize == SMOOTH_SCALABLE))
- pixelSize = request.pixelSize;
-
-#ifndef QT_NO_QWS_QPF2
- if (foundry->name == QLatin1String("prerendered")) {
-#ifdef QT_FONTS_ARE_RESOURCES
- QResource res(QLatin1String(size->fileName.constData()));
- if (res.isValid()) {
- QFontEngineQPF *fe = new QFontEngineQPF(request, res.data(), res.size());
- if (fe->isValid())
- return fe;
- delete fe;
- qDebug() << "fontengine is not valid! " << size->fileName;
- } else {
- qDebug() << "Resource not valid" << size->fileName;
- }
-#else
- int f = ::open(size->fileName, O_RDONLY, 0);
- if (f >= 0) {
- QFontEngineQPF *fe = new QFontEngineQPF(request, f);
- if (fe->isValid())
- return fe;
- delete fe; // will close f
- qDebug() << "fontengine is not valid!";
- }
-#endif
- } else
-#endif
- if ( foundry->name != QLatin1String("qt") ) { ///#### is this the best way????
- QString file = QFile::decodeName(size->fileName);
-
- QFontDef def = request;
- def.pixelSize = pixelSize;
-
-#ifdef QT_NO_QWS_SHARE_FONTS
- bool shareFonts = false;
-#else
- static bool dontShareFonts = !qgetenv("QWS_NO_SHARE_FONTS").isEmpty();
- bool shareFonts = !dontShareFonts;
-#endif
-
- QScopedPointer<QFontEngine> engine;
-
-#ifndef QT_NO_LIBRARY
- QFontEngineFactoryInterface *factory = qobject_cast<QFontEngineFactoryInterface *>(loader()->instance(foundry->name));
- if (factory) {
- QFontEngineInfo info;
- info.setFamily(request.family);
- info.setPixelSize(request.pixelSize);
- info.setStyle(QFont::Style(request.style));
- info.setWeight(request.weight);
- // #### antialiased
-
- QAbstractFontEngine *customEngine = factory->create(info);
- if (customEngine) {
- engine.reset(new QProxyFontEngine(customEngine, def));
-
- if (shareFonts) {
- QVariant hint = customEngine->fontProperty(QAbstractFontEngine::CacheGlyphsHint);
- if (hint.isValid())
- shareFonts = hint.toBool();
- else
- shareFonts = (pixelSize < 64);
- }
- }
- }
-#endif // QT_NO_LIBRARY
- if ((engine.isNull() && !file.isEmpty() && QFile::exists(file)) || privateDb()->isApplicationFont(file)) {
- QFontEngine::FaceId faceId;
- faceId.filename = file.toLocal8Bit();
- faceId.index = size->fileIndex;
-
-#ifndef QT_NO_FREETYPE
-
- QScopedPointer<QFontEngineFT> fte(new QFontEngineFT(def));
- bool antialias = style->antialiased && !(request.styleStrategy & QFont::NoAntialias);
- if (fte->init(faceId, antialias,
- antialias ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono)) {
-#ifdef QT_NO_QWS_QPF2
- return fte.take();
-#else
- // try to distinguish between bdf and ttf fonts we can pre-render
- // and don't try to share outline fonts
- shareFonts = shareFonts
- && !fte->defaultGlyphs()->outline_drawing
- && !fte->getSfntTable(MAKE_TAG('h', 'e', 'a', 'd')).isEmpty();
- engine.reset(fte.take());
-#endif
- }
-#endif // QT_NO_FREETYPE
- }
- if (!engine.isNull()) {
-#if !defined(QT_NO_QWS_QPF2) && !defined(QT_FONTS_ARE_RESOURCES)
- if (shareFonts) {
- QScopedPointer<QFontEngineQPF> fe(new QFontEngineQPF(def, -1, engine.data()));
- engine.take();
- if (fe->isValid())
- return fe.take();
- qWarning("Initializing QFontEngineQPF failed for %s", qPrintable(file));
- engine.reset(fe->takeRenderingEngine());
- }
-#endif
- return engine.take();
- }
- } else
- {
-#ifndef QT_NO_QWS_QPF
- QString fn = qwsFontPath();
- fn += QLatin1Char('/');
- fn += family->name.toLower()
- + QLatin1Char('_') + QString::number(pixelSize*10)
- + QLatin1Char('_') + QString::number(style->key.weight)
- + (style->key.style == QFont::StyleItalic ?
- QLatin1String("i.qpf") : QLatin1String(".qpf"));
- //###rotation ###
-
- QFontEngine *fe = new QFontEngineQPF1(request, fn);
- return fe;
-#endif // QT_NO_QWS_QPF
- }
- return new QFontEngineBox(pixelSize);
-}
-
-static
-QFontEngine *loadEngine(int script, const QFontPrivate *fp,
- const QFontDef &request,
- QtFontFamily *family, QtFontFoundry *foundry,
- QtFontStyle *style, QtFontSize *size)
-{
- QScopedPointer<QFontEngine> engine(loadSingleEngine(script, fp, request, family, foundry,
- style, size));
-#ifndef QT_NO_QWS_QPF
- if (!engine.isNull()
- && script == QUnicodeTables::Common
- && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol) {
-
- QStringList fallbacks = privateDb()->fallbackFamilies;
-
- if (family && !family->fallbackFamilies.isEmpty())
- fallbacks = family->fallbackFamilies;
-
- QFontEngine *fe = new QFontEngineMultiQWS(engine.data(), script, fallbacks);
- engine.take();
- engine.reset(fe);
- }
-#endif
- return engine.take();
-}
-
-static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
-{
- QFontDatabasePrivate *db = privateDb();
-#ifdef QT_NO_FREETYPE
- Q_UNUSED(fnt);
-#else
- fnt->families = db->addTTFile(QFile::encodeName(fnt->fileName), fnt->data);
- db->fallbackFamilies += fnt->families;
-#endif
- db->reregisterAppFonts = true;
-}
-
-bool QFontDatabase::removeApplicationFont(int handle)
-{
- QMutexLocker locker(fontDatabaseMutex());
-
- QFontDatabasePrivate *db = privateDb();
- if (handle < 0 || handle >= db->applicationFonts.count())
- return false;
-
- db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont();
-
- db->reregisterAppFonts = true;
- db->invalidate();
- return true;
-}
-
-bool QFontDatabase::removeAllApplicationFonts()
-{
- QMutexLocker locker(fontDatabaseMutex());
-
- QFontDatabasePrivate *db = privateDb();
- if (db->applicationFonts.isEmpty())
- return false;
-
- db->applicationFonts.clear();
- db->invalidate();
- return true;
-}
-
-bool QFontDatabase::supportsThreadedFontRendering()
-{
- return true;
-}
-
-QFontEngine *
-QFontDatabase::findFont(int script, const QFontPrivate *fp,
- const QFontDef &request)
-{
- QMutexLocker locker(fontDatabaseMutex());
-
- const int force_encoding_id = -1;
-
- if (!privateDb()->count)
- initializeDb();
-
- QScopedPointer<QFontEngine> fe;
- if (fp) {
- if (fp->rawMode) {
- fe.reset(loadEngine(script, fp, request, 0, 0, 0, 0));
-
- // if we fail to load the rawmode font, use a 12pixel box engine instead
- if (fe.isNull())
- fe.reset(new QFontEngineBox(12));
- return fe.take();
- }
-
- QFontCache::Key key(request, script);
- fe.reset(QFontCache::instance()->findEngine(key));
- if (! fe.isNull())
- return fe.take();
- }
-
- QString family_name, foundry_name;
- QtFontStyle::Key styleKey;
- styleKey.style = request.style;
- styleKey.weight = request.weight;
- styleKey.stretch = request.stretch;
- char pitch = request.ignorePitch ? '*' : request.fixedPitch ? 'm' : 'p';
-
- parseFontName(request.family, foundry_name, family_name);
-
- FM_DEBUG("QFontDatabase::findFont\n"
- " request:\n"
- " family: %s [%s], script: %d\n"
- " weight: %d, style: %d\n"
- " stretch: %d\n"
- " pixelSize: %g\n"
- " pitch: %c",
- family_name.isEmpty() ? "-- first in script --" : family_name.toLatin1().constData(),
- foundry_name.isEmpty() ? "-- any --" : foundry_name.toLatin1().constData(),
- script, request.weight, request.style, request.stretch, request.pixelSize, pitch);
-
- if (qt_enable_test_font && request.family == QLatin1String("__Qt__Box__Engine__")) {
- fe.reset(new QTestFontEngine(request.pixelSize));
- fe->fontDef = request;
- }
-
- if (fe.isNull())
- {
- QtFontDesc desc;
- match(script, request, family_name, foundry_name, force_encoding_id, &desc);
-
- if (desc.family != 0 && desc.foundry != 0 && desc.style != 0
- ) {
- FM_DEBUG(" BEST:\n"
- " family: %s [%s]\n"
- " weight: %d, style: %d\n"
- " stretch: %d\n"
- " pixelSize: %d\n"
- " pitch: %c\n"
- " encoding: %d\n",
- desc.family->name.toLatin1().constData(),
- desc.foundry->name.isEmpty() ? "-- none --" : desc.foundry->name.toLatin1().constData(),
- desc.style->key.weight, desc.style->key.style,
- desc.style->key.stretch, desc.size ? desc.size->pixelSize : 0xffff,
- 'p', 0
- );
-
- fe.reset(loadEngine(script, fp, request, desc.family, desc.foundry, desc.style, desc.size
- ));
- } else {
- FM_DEBUG(" NO MATCH FOUND\n");
- }
- if (! fe.isNull())
- initFontDef(desc, request, &fe->fontDef);
- }
-
-#ifndef QT_NO_FREETYPE
- if (! fe.isNull()) {
- if (scriptRequiresOpenType(script) && fe->type() == QFontEngine::Freetype) {
- HB_Face hbFace = static_cast<QFontEngineFT *>(fe.data())->harfbuzzFace();
- if (!hbFace || !hbFace->supported_scripts[script]) {
- FM_DEBUG(" OpenType support missing for script\n");
- fe.reset(0);
- }
- }
- }
-#endif
-
- if (! fe.isNull()) {
- if (fp) {
- QFontDef def = request;
- if (def.family.isEmpty()) {
- def.family = fp->request.family;
- def.family = def.family.left(def.family.indexOf(QLatin1Char(',')));
- }
- QFontCache::Key key(def, script);
- QFontCache::instance()->insertEngine(key, fe.data());
- }
- }
-
- if (fe.isNull()) {
- if (!request.family.isEmpty())
- return 0;
-
- FM_DEBUG("returning box engine");
-
- fe.reset(new QFontEngineBox(request.pixelSize));
-
- if (fp) {
- QFontCache::Key key(request, script);
- QFontCache::instance()->insertEngine(key, fe.data());
- }
- }
-
- if (fp && fp->dpi > 0) {
- fe->fontDef.pointSize = qreal(double((fe->fontDef.pixelSize * 72) / fp->dpi));
- } else {
- fe->fontDef.pointSize = request.pointSize;
- }
-
- return fe.take();
-}
-
-void QFontDatabase::load(const QFontPrivate *d, int script)
-{
- QFontDef req = d->request;
-
- if (req.pixelSize == -1)
- req.pixelSize = qRound(req.pointSize*d->dpi/72);
- if (req.pointSize < 0)
- req.pointSize = req.pixelSize*72.0/d->dpi;
-
- if (!d->engineData) {
- QFontCache::Key key(req, script);
-
- // look for the requested font in the engine data cache
- d->engineData = QFontCache::instance()->findEngineData(key);
-
- if (!d->engineData) {
- // create a new one
- d->engineData = new QFontEngineData;
- QT_TRY {
- QFontCache::instance()->insertEngineData(key, d->engineData);
- } QT_CATCH(...) {
- delete d->engineData;
- d->engineData = 0;
- QT_RETHROW;
- }
- } else {
- d->engineData->ref.ref();
- }
- }
-
- // the cached engineData could have already loaded the engine we want
- if (d->engineData->engines[script]) return;
-
- // double scale = 1.0; // ### TODO: fix the scale calculations
-
- // list of families to try
- QStringList family_list;
-
- if (!req.family.isEmpty()) {
- family_list = req.family.split(QLatin1Char(','));
-
- // append the substitute list for each family in family_list
- QStringList subs_list;
- QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd();
- for (; it != end; ++it)
- subs_list += QFont::substitutes(*it);
- family_list += subs_list;
-
- // append the default fallback font for the specified script
- // family_list << ... ; ###########
-
- // add the default family
- QString defaultFamily = QApplication::font().family();
- if (! family_list.contains(defaultFamily))
- family_list << defaultFamily;
-
- // add QFont::defaultFamily() to the list, for compatibility with
- // previous versions
- family_list << QApplication::font().defaultFamily();
- }
-
- // null family means find the first font matching the specified script
- family_list << QString();
-
- // load the font
- QFontEngine *engine = 0;
- QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd();
- for (; !engine && it != end; ++it) {
- req.family = *it;
-
- engine = QFontDatabase::findFont(script, d, req);
- if (engine && (engine->type()==QFontEngine::Box) && !req.family.isEmpty())
- engine = 0;
- }
-
- engine->ref.ref();
- d->engineData->engines[script] = engine;
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp
deleted file mode 100644
index cfa405dbc1..0000000000
--- a/src/gui/text/qfontdatabase_s60.cpp
+++ /dev/null
@@ -1,1099 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/qapplication_p.h>
-#include "qdir.h"
-#include "qfont_p.h"
-#include "qfontengine_s60_p.h"
-#include "qabstractfileengine.h"
-#include "qdesktopservices.h"
-#include "qtemporaryfile.h"
-#include "qtextcodec.h"
-#include <private/qpixmap_s60_p.h>
-#include <private/qt_s60_p.h>
-#include "qendian.h"
-#include <private/qcore_symbian_p.h>
-#ifdef QT_NO_FREETYPE
-#include <openfont.h>
-#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
-#include <graphics/openfontrasterizer.h> // COpenFontRasterizer has moved to a new header file
-#endif // SYMBIAN_ENABLE_SPLIT_HEADERS
-#endif // QT_NO_FREETYPE
-
-QT_BEGIN_NAMESPACE
-
-QStringList qt_symbian_fontFamiliesOnFontServer() // Also used in qfont_s60.cpp
-{
- QStringList result;
- QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
- const int numTypeFaces = S60->screenDevice()->NumTypefaces();
- for (int i = 0; i < numTypeFaces; i++) {
- TTypefaceSupport typefaceSupport;
- S60->screenDevice()->TypefaceSupport(typefaceSupport, i);
- const QString familyName((const QChar *)typefaceSupport.iTypeface.iName.Ptr(), typefaceSupport.iTypeface.iName.Length());
- result.append(familyName);
- }
- lock.relock();
- return result;
-}
-
-QFileInfoList alternativeFilePaths(const QString &path, const QStringList &nameFilters,
- QDir::Filters filters = QDir::NoFilter, QDir::SortFlags sort = QDir::NoSort,
- bool uniqueFileNames = true)
-{
- QFileInfoList result;
-
- // Prepare a 'soft to hard' drive list: W:, X: ... A:, Z:
- QStringList driveStrings;
- foreach (const QFileInfo &drive, QDir::drives())
- driveStrings.append(drive.absolutePath());
- driveStrings.sort();
- const QString zDriveString(QLatin1String("Z:/"));
- driveStrings.removeAll(zDriveString);
- driveStrings.prepend(zDriveString);
-
- QStringList uniqueFileNameList;
- for (int i = driveStrings.count() - 1; i >= 0; --i) {
- const QDir dirOnDrive(driveStrings.at(i) + path);
- const QFileInfoList entriesOnDrive = dirOnDrive.entryInfoList(nameFilters, filters, sort);
- if (uniqueFileNames) {
- foreach(const QFileInfo &entry, entriesOnDrive) {
- if (!uniqueFileNameList.contains(entry.fileName())) {
- uniqueFileNameList.append(entry.fileName());
- result.append(entry);
- }
- }
- } else {
- result.append(entriesOnDrive);
- }
- }
- return result;
-}
-
-#ifdef QT_NO_FREETYPE
-class QSymbianFontDatabaseExtrasImplementation : public QSymbianFontDatabaseExtras
-{
-public:
- QSymbianFontDatabaseExtrasImplementation();
- ~QSymbianFontDatabaseExtrasImplementation();
-
- const QSymbianTypeFaceExtras *extras(const QString &typeface, bool bold, bool italic) const;
- void removeAppFontData(QFontDatabasePrivate::ApplicationFont *fnt);
- static inline bool appFontLimitReached();
- TUid addFontFileToFontStore(const QFileInfo &fontFileInfo);
- static void clear();
-
- static inline QString tempAppFontFolder();
- static const QString appFontMarkerPrefix;
- static QString appFontMarker(); // 'qaf<shortUid[+shortPid]>'
-
- struct CFontFromFontStoreReleaser {
- static inline void cleanup(CFont *font)
- {
- if (!font)
- return;
- const QSymbianFontDatabaseExtrasImplementation *dbExtras =
- static_cast<const QSymbianFontDatabaseExtrasImplementation*>(privateDb()->symbianExtras);
- dbExtras->m_store->ReleaseFont(font);
- }
- };
-
- struct CFontFromScreenDeviceReleaser {
- static inline void cleanup(CFont *font)
- {
- if (!font)
- return;
- S60->screenDevice()->ReleaseFont(font);
- }
- };
-
-// m_heap, m_store, m_rasterizer and m_extras are used if Symbian
-// does not provide the Font Table API
- RHeap* m_heap;
- CFontStore *m_store;
- COpenFontRasterizer *m_rasterizer;
- mutable QList<const QSymbianTypeFaceExtras *> m_extras;
-
- mutable QSet<QString> m_applicationFontFamilies;
-};
-
-const QString QSymbianFontDatabaseExtrasImplementation::appFontMarkerPrefix =
- QLatin1String("Q");
-
-inline QString QSymbianFontDatabaseExtrasImplementation::tempAppFontFolder()
-{
- return QDir::toNativeSeparators(QDir::tempPath()) + QLatin1Char('\\');
-}
-
-QString QSymbianFontDatabaseExtrasImplementation::appFontMarker()
-{
- static QString result;
- if (result.isEmpty()) {
- quint16 id = 0;
- if (QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) {
- // We are allowed to load app fonts even from previous, crashed runs
- // of this application, since we can access the font tables.
- const quint32 uid = RProcess().Type().MostDerived().iUid;
- id = static_cast<quint16>(uid + (uid >> 16));
- } else {
- // If no font table Api is available, we must not even load a font
- // from a previous (crashed) run of this application. Reason: we
- // won't get the font tables, they are not in the CFontStore.
- // So, we use the pid, for more uniqueness.
- id = static_cast<quint16>(RProcess().Id().Id());
- }
- result = appFontMarkerPrefix + QString::fromLatin1("%1").arg(id & 0x7fff, 3, 32, QLatin1Char('0'));
- Q_ASSERT(appFontMarkerPrefix.length() == 1 && result.length() == 4);
- }
- return result;
-}
-
-static inline bool qt_symbian_fontNameHasAppFontMarker(const QString &fontName)
-{
- const int idLength = 3; // Keep in sync with id length in appFontMarker().
- const QString &prefix = QSymbianFontDatabaseExtrasImplementation::appFontMarkerPrefix;
- if (fontName.length() < prefix.length() + idLength
- || fontName.mid(fontName.length() - idLength - prefix.length(), prefix.length()) != prefix)
- return false;
- // Testing if the the id is base32 data
- for (int i = fontName.length() - idLength; i < fontName.length(); ++i) {
- const QChar &c = fontName.at(i);
- if (!(c >= QLatin1Char('0') && c <= QLatin1Char('9')
- || c >= QLatin1Char('a') && c <= QLatin1Char('v')))
- return false;
- }
- return true;
-}
-
-// If fontName is an application font of this app, prepend the app font marker
-QString qt_symbian_fontNameWithAppFontMarker(const QString &fontName)
-{
- QFontDatabasePrivate *db = privateDb();
- Q_ASSERT(db);
- const QSymbianFontDatabaseExtrasImplementation *dbExtras =
- static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
- return dbExtras->m_applicationFontFamilies.contains(fontName) ?
- fontName + QSymbianFontDatabaseExtrasImplementation::appFontMarker()
- : fontName;
-}
-
-static inline QString qt_symbian_appFontNameWithoutMarker(const QString &markedFontName)
-{
- return markedFontName.left(markedFontName.length()
- - QSymbianFontDatabaseExtrasImplementation::appFontMarker().length());
-}
-
-QSymbianFontDatabaseExtrasImplementation::QSymbianFontDatabaseExtrasImplementation()
-{
- if (!QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) {
- QStringList filters;
- filters.append(QLatin1String("*.ttf"));
- filters.append(QLatin1String("*.ccc"));
- filters.append(QLatin1String("*.ltt"));
- const QFileInfoList fontFiles = alternativeFilePaths(QLatin1String("resource\\Fonts"), filters);
-
- const TInt heapMinLength = 0x1000;
- const TInt heapMaxLength = qMax(0x20000 * fontFiles.count(), heapMinLength);
- m_heap = User::ChunkHeap(NULL, heapMinLength, heapMaxLength);
- QT_TRAP_THROWING(
- m_store = CFontStore::NewL(m_heap);
- m_rasterizer = COpenFontRasterizer::NewL(TUid::Uid(0x101F7F5E));
- CleanupStack::PushL(m_rasterizer);
- m_store->InstallRasterizerL(m_rasterizer);
- CleanupStack::Pop(m_rasterizer););
-
- foreach (const QFileInfo &fontFileInfo, fontFiles)
- addFontFileToFontStore(fontFileInfo);
- }
-}
-
-void QSymbianFontDatabaseExtrasImplementation::clear()
-{
- QFontDatabasePrivate *db = privateDb();
- if (!db)
- return;
- const QSymbianFontDatabaseExtrasImplementation *dbExtras =
- static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
- if (!dbExtras)
- return; // initializeDb() has never been called
- QSymbianTypeFaceExtrasHash &extrasHash = S60->fontData();
- if (QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) {
- qDeleteAll(extrasHash);
- } else {
- typedef QList<const QSymbianTypeFaceExtras *>::iterator iterator;
- for (iterator p = dbExtras->m_extras.begin(); p != dbExtras->m_extras.end(); ++p) {
- dbExtras->m_store->ReleaseFont((*p)->fontOwner());
- delete *p;
- }
- dbExtras->m_extras.clear();
- }
- extrasHash.clear();
-}
-
-void qt_cleanup_symbianFontDatabase()
-{
- static bool cleanupDone = false;
- if (cleanupDone)
- return;
- cleanupDone = true;
-
- QFontDatabasePrivate *db = privateDb();
- if (!db)
- return;
-
- QSymbianFontDatabaseExtrasImplementation::clear();
-
- if (!db->applicationFonts.isEmpty()) {
- QFontDatabase::removeAllApplicationFonts();
- // We remove the left over temporary font files of Qt application.
- // Active fonts are undeletable since the font server holds a handle
- // on them, so we do not need to worry to delete other running
- // applications' fonts.
- const QDir dir(QSymbianFontDatabaseExtrasImplementation::tempAppFontFolder());
- const QStringList filter(
- QSymbianFontDatabaseExtrasImplementation::appFontMarkerPrefix + QLatin1String("*.ttf"));
- foreach (const QFileInfo &ttfFile, dir.entryInfoList(filter))
- QFile(ttfFile.absoluteFilePath()).remove();
- db->applicationFonts.clear();
- }
-}
-
-QSymbianFontDatabaseExtrasImplementation::~QSymbianFontDatabaseExtrasImplementation()
-{
- qt_cleanup_symbianFontDatabase();
- if (!QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) {
- delete m_store;
- m_heap->Close();
- }
-}
-
-#ifndef FNTSTORE_H_INLINES_SUPPORT_FMM
-/*
- Workaround: fntstore.h has an inlined function 'COpenFont* CBitmapFont::OpenFont()'
- that returns a private data member. The header will change between SDKs. But Qt has
- to build on any SDK version and run on other versions of Symbian OS.
- This function performs the needed pointer arithmetic to get the right COpenFont*
-*/
-COpenFont* OpenFontFromBitmapFont(const CBitmapFont* aBitmapFont)
-{
- const TInt offsetIOpenFont = 92; // '_FOFF(CBitmapFont, iOpenFont)' ..if iOpenFont weren't private
- const TUint valueIOpenFont = *(TUint*)PtrAdd(aBitmapFont, offsetIOpenFont);
- return (valueIOpenFont & 1) ?
- (COpenFont*)PtrAdd(aBitmapFont, valueIOpenFont & ~1) : // New behavior: iOpenFont is offset
- (COpenFont*)valueIOpenFont; // Old behavior: iOpenFont is pointer
-}
-#endif // FNTSTORE_H_INLINES_SUPPORT_FMM
-
-const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(const QString &aTypeface,
- bool bold, bool italic) const
-{
- QSymbianTypeFaceExtrasHash &extrasHash = S60->fontData();
- if (extrasHash.isEmpty() && QThread::currentThread() != QApplication::instance()->thread())
- S60->addThreadLocalReleaseFunc(clear);
- const QString typeface = qt_symbian_fontNameWithAppFontMarker(aTypeface);
- const QString searchKey = typeface + QString::number(int(bold)) + QString::number(int(italic));
- if (!extrasHash.contains(searchKey)) {
- TFontSpec searchSpec(qt_QString2TPtrC(typeface), 1);
- if (bold)
- searchSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
- if (italic)
- searchSpec.iFontStyle.SetPosture(EPostureItalic);
-
- CFont* font = NULL;
- if (QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) {
- const TInt err = S60->screenDevice()->GetNearestFontToDesignHeightInPixels(font, searchSpec);
- Q_ASSERT(err == KErrNone && font);
- QScopedPointer<CFont, CFontFromScreenDeviceReleaser> sFont(font);
- QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font);
- sFont.take();
- extrasHash.insert(searchKey, extras);
- } else {
- const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, searchSpec);
- Q_ASSERT(err == KErrNone && font);
- const CBitmapFont *bitmapFont = static_cast<CBitmapFont*>(font);
- COpenFont *openFont =
-#ifdef FNTSTORE_H_INLINES_SUPPORT_FMM
- bitmapFont->OpenFont();
-#else // FNTSTORE_H_INLINES_SUPPORT_FMM
- OpenFontFromBitmapFont(bitmapFont);
-#endif // FNTSTORE_H_INLINES_SUPPORT_FMM
- const TOpenFontFaceAttrib* const attrib = openFont->FaceAttrib();
- const QString foundKey =
- QString((const QChar*)attrib->FullName().Ptr(), attrib->FullName().Length());
- if (!extrasHash.contains(foundKey)) {
- QScopedPointer<CFont, CFontFromFontStoreReleaser> sFont(font);
- QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font, openFont);
- sFont.take();
- m_extras.append(extras);
- extrasHash.insert(searchKey, extras);
- extrasHash.insert(foundKey, extras);
- } else {
- m_store->ReleaseFont(font);
- extrasHash.insert(searchKey, extrasHash.value(foundKey));
- }
- }
- }
- return extrasHash.value(searchKey);
-}
-
-void QSymbianFontDatabaseExtrasImplementation::removeAppFontData(
- QFontDatabasePrivate::ApplicationFont *fnt)
-{
- clear();
- if (!QSymbianTypeFaceExtras::symbianFontTableApiAvailable()
- && fnt->fontStoreFontFileUid.iUid != 0)
- m_store->RemoveFile(fnt->fontStoreFontFileUid);
- if (!fnt->families.isEmpty())
- m_applicationFontFamilies.remove(fnt->families.first());
- if (fnt->screenDeviceFontFileId != 0)
- S60->screenDevice()->RemoveFile(fnt->screenDeviceFontFileId);
- QFile::remove(fnt->temporaryFileName);
- *fnt = QFontDatabasePrivate::ApplicationFont();
-}
-
-bool QSymbianFontDatabaseExtrasImplementation::appFontLimitReached()
-{
- QFontDatabasePrivate *db = privateDb();
- if (!db)
- return false;
- const int maxAppFonts = 5;
- int registeredAppFonts = 0;
- foreach (const QFontDatabasePrivate::ApplicationFont &appFont, db->applicationFonts)
- if (!appFont.families.isEmpty() && ++registeredAppFonts == maxAppFonts)
- return true;
- return false;
-}
-
-TUid QSymbianFontDatabaseExtrasImplementation::addFontFileToFontStore(const QFileInfo &fontFileInfo)
-{
- Q_ASSERT(!QSymbianTypeFaceExtras::symbianFontTableApiAvailable());
- const QString fontFile = QDir::toNativeSeparators(fontFileInfo.absoluteFilePath());
- const TPtrC fontFilePtr(qt_QString2TPtrC(fontFile));
- TUid fontUid = {0};
- TRAP_IGNORE(fontUid = m_store->AddFileL(fontFilePtr));
- return fontUid;
-}
-
-#else // QT_NO_FREETYPE
-class QFontEngineFTS60 : public QFontEngineFT
-{
-public:
- QFontEngineFTS60(const QFontDef &fd);
-};
-
-QFontEngineFTS60::QFontEngineFTS60(const QFontDef &fd)
- : QFontEngineFT(fd)
-{
- default_hint_style = HintFull;
-}
-#endif // QT_NO_FREETYPE
-
-/*
- QFontEngineS60::pixelsToPoints, QFontEngineS60::pointsToPixels, QFontEngineMultiS60::QFontEngineMultiS60
- and QFontEngineMultiS60::QFontEngineMultiS60 should be in qfontengine_s60.cpp. But since also the
- Freetype based font rendering need them, they are here.
-*/
-qreal QFontEngineS60::pixelsToPoints(qreal pixels, Qt::Orientation orientation)
-{
- CWsScreenDevice* device = S60->screenDevice();
- return (orientation == Qt::Horizontal?
- device->HorizontalPixelsToTwips(pixels)
- :device->VerticalPixelsToTwips(pixels)) / KTwipsPerPoint;
-}
-
-qreal QFontEngineS60::pointsToPixels(qreal points, Qt::Orientation orientation)
-{
- CWsScreenDevice* device = S60->screenDevice();
- const int twips = points * KTwipsPerPoint;
- return orientation == Qt::Horizontal?
- device->HorizontalTwipsToPixels(twips)
- :device->VerticalTwipsToPixels(twips);
-}
-
-QFontEngineMultiS60::QFontEngineMultiS60(QFontEngine *first, int script, const QStringList &fallbackFamilies)
- : QFontEngineMulti(fallbackFamilies.size() + 1)
- , m_script(script)
- , m_fallbackFamilies(fallbackFamilies)
-{
- engines[0] = first;
- first->ref.ref();
- fontDef = engines[0]->fontDef;
-}
-
-void QFontEngineMultiS60::loadEngine(int at)
-{
- Q_ASSERT(at < engines.size());
- Q_ASSERT(engines.at(at) == 0);
-
- QFontDef request = fontDef;
- request.styleStrategy |= QFont::NoFontMerging;
- request.family = m_fallbackFamilies.at(at-1);
- engines[at] = QFontDatabase::findFont(m_script,
- /*fontprivate*/0,
- request);
- Q_ASSERT(engines[at]);
-}
-
-#ifdef QT_NO_FREETYPE
-static bool registerScreenDeviceFont(int screenDeviceFontIndex,
- const QSymbianFontDatabaseExtrasImplementation *dbExtras)
-{
- TTypefaceSupport typefaceSupport;
- S60->screenDevice()->TypefaceSupport(typefaceSupport, screenDeviceFontIndex);
-
- QString familyName((const QChar*)typefaceSupport.iTypeface.iName.Ptr(), typefaceSupport.iTypeface.iName.Length());
- if (qt_symbian_fontNameHasAppFontMarker(familyName)) {
- const QString &marker = QSymbianFontDatabaseExtrasImplementation::appFontMarker();
- if (familyName.endsWith(marker)) {
- familyName = qt_symbian_appFontNameWithoutMarker(familyName);
- dbExtras->m_applicationFontFamilies.insert(familyName);
- } else {
- return false; // This was somebody else's application font. Skip it.
- }
- }
-
- CFont *font; // We have to get a font instance in order to know all the details
- TFontSpec fontSpec(typefaceSupport.iTypeface.iName, 11);
- if (S60->screenDevice()->GetNearestFontInPixels(font, fontSpec) != KErrNone)
- return false;
- QScopedPointer<CFont, QSymbianFontDatabaseExtrasImplementation::CFontFromScreenDeviceReleaser> sFont(font);
- if (font->TypeUid() != KCFbsFontUid)
- return false;
- TOpenFontFaceAttrib faceAttrib;
- const CFbsFont *cfbsFont = static_cast<const CFbsFont *>(font);
- cfbsFont->GetFaceAttrib(faceAttrib);
-
- QtFontStyle::Key styleKey;
- styleKey.style = faceAttrib.IsItalic()?QFont::StyleItalic:QFont::StyleNormal;
- styleKey.weight = faceAttrib.IsBold()?QFont::Bold:QFont::Normal;
-
- QtFontFamily *family = privateDb()->family(familyName, true);
- family->fixedPitch = faceAttrib.IsMonoWidth();
- QtFontFoundry *foundry = family->foundry(QString(), true);
- QtFontStyle *style = foundry->style(styleKey, QString(), true);
- style->smoothScalable = typefaceSupport.iIsScalable;
- style->pixelSize(0, true);
-
- const QSymbianTypeFaceExtras *typeFaceExtras =
- dbExtras->extras(familyName, faceAttrib.IsBold(), faceAttrib.IsItalic());
- const QByteArray os2Table = typeFaceExtras->getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
- const unsigned char* data = reinterpret_cast<const unsigned char*>(os2Table.constData());
- const unsigned char* ulUnicodeRange = data + 42;
- quint32 unicodeRange[4] = {
- qFromBigEndian<quint32>(ulUnicodeRange),
- qFromBigEndian<quint32>(ulUnicodeRange + 4),
- qFromBigEndian<quint32>(ulUnicodeRange + 8),
- qFromBigEndian<quint32>(ulUnicodeRange + 12)
- };
- const unsigned char* ulCodePageRange = data + 78;
- quint32 codePageRange[2] = {
- qFromBigEndian<quint32>(ulCodePageRange),
- qFromBigEndian<quint32>(ulCodePageRange + 4)
- };
- const QList<QFontDatabase::WritingSystem> writingSystems =
- qt_determine_writing_systems_from_truetype_bits(unicodeRange, codePageRange);
- foreach (const QFontDatabase::WritingSystem system, writingSystems)
- family->writingSystems[system] = QtFontFamily::Supported;
- return true;
-}
-#endif
-
-static void initializeDb()
-{
- QFontDatabasePrivate *db = privateDb();
- if(!db || db->count)
- return;
-
-#ifdef QT_NO_FREETYPE
- if (!db->symbianExtras)
- db->symbianExtras = new QSymbianFontDatabaseExtrasImplementation;
-
- QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
-
- const int numTypeFaces = S60->screenDevice()->NumTypefaces();
- const QSymbianFontDatabaseExtrasImplementation *dbExtras =
- static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
- for (int i = 0; i < numTypeFaces; i++)
- registerScreenDeviceFont(i, dbExtras);
-
- // We have to clear/release all CFonts, here, in case one of the fonts is
- // an application font of another running Qt app. Otherwise the other Qt app
- // cannot remove it's application font, anymore -> "Zombie Font".
- QSymbianFontDatabaseExtrasImplementation::clear();
-
- lock.relock();
-
-#else // QT_NO_FREETYPE
- QDir dir(QDesktopServices::storageLocation(QDesktopServices::FontsLocation));
- dir.setNameFilters(QStringList() << QLatin1String("*.ttf")
- << QLatin1String("*.ttc") << QLatin1String("*.pfa")
- << QLatin1String("*.pfb"));
- for (int i = 0; i < int(dir.count()); ++i) {
- const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
- db->addTTFile(file);
- }
-#endif // QT_NO_FREETYPE
-}
-
-static inline void load(const QString &family = QString(), int script = -1)
-{
- Q_UNUSED(family)
- Q_UNUSED(script)
- initializeDb();
-}
-
-struct OffsetTable {
- quint32 sfntVersion;
- quint16 numTables, searchRange, entrySelector, rangeShift;
-};
-
-struct TableRecord {
- quint32 tag, checkSum, offset, length;
-};
-
-struct NameTableHead {
- quint16 format, count, stringOffset;
-};
-
-struct NameRecord {
- quint16 platformID, encodingID, languageID, nameID, length, offset;
-};
-
-static quint32 ttfCalcChecksum(const char *data, quint32 bytesCount)
-{
- quint32 result = 0;
- const quint32 *ptr = reinterpret_cast<const quint32*>(data);
- const quint32 *endPtr =
- ptr + (bytesCount + sizeof(quint32) - 1) / sizeof(quint32);
- while (ptr < endPtr) {
- const quint32 unit32Value = *ptr++;
- result += qFromBigEndian(unit32Value);
- }
- return result;
-}
-
-static inline quint32 toDWordBoundary(quint32 value)
-{
- return (value + 3) & ~3;
-}
-
-static inline quint32 dWordPadding(quint32 value)
-{
- return (4 - (value & 3)) & 3;
-}
-
-static inline bool ttfMarkNameTable(QByteArray &table, const QString &marker)
-{
- const quint32 tableLength = static_cast<quint32>(table.size());
-
- if (tableLength > 50000 // hard limit
- || tableLength < sizeof(NameTableHead)) // corrupt name table
- return false;
-
- const NameTableHead *head = reinterpret_cast<const NameTableHead*>(table.constData());
- const quint16 count = qFromBigEndian(head->count);
- const quint16 stringOffset = qFromBigEndian(head->stringOffset);
- if (count > 200 // hard limit
- || stringOffset >= tableLength // corrupt name table
- || sizeof(NameTableHead) + count * sizeof(NameRecord) >= tableLength) // corrupt name table
- return false;
-
- QTextEncoder encoder(QTextCodec::codecForName("UTF-16BE"), QTextCodec::IgnoreHeader);
- const QByteArray markerUtf16BE = encoder.fromUnicode(marker);
- const QByteArray markerAscii = marker.toAscii();
-
- QByteArray markedTable;
- markedTable.reserve(tableLength + marker.length() * 20); // Original size plus some extra
- markedTable.append(table, stringOffset);
- QByteArray markedStrings;
- quint32 stringDataCount = stringOffset;
- for (quint16 i = 0; i < count; ++i) {
- const quint32 nameRecordOffset = sizeof(NameTableHead) + sizeof(NameRecord) * i;
- NameRecord *nameRecord =
- reinterpret_cast<NameRecord*>(markedTable.data() + nameRecordOffset);
- const quint16 nameID = qFromBigEndian(nameRecord->nameID);
- const quint16 platformID = qFromBigEndian(nameRecord->platformID);
- const quint16 encodingID = qFromBigEndian(nameRecord->encodingID);
- const quint16 offset = qFromBigEndian(nameRecord->offset);
- const quint16 length = qFromBigEndian(nameRecord->length);
- stringDataCount += length;
- if (stringDataCount > 80000 // hard limit. String data may be > name table size. Multiple records can reference the same string.
- || static_cast<quint32>(stringOffset + offset + length) > tableLength) // String outside bounds
- return false;
- const bool needsMarker =
- nameID == 1 || nameID == 3 || nameID == 4 || nameID == 16 || nameID == 21;
- const bool isUnicode =
- platformID == 0 || platformID == 3 && encodingID == 1;
- const QByteArray originalString =
- QByteArray::fromRawData(table.constData() + stringOffset + offset, length);
- QByteArray markedString;
- if (needsMarker) {
- const int maxBytesLength = (KMaxTypefaceNameLength - marker.length()) * (isUnicode ? 2 : 1);
- markedString = originalString.left(maxBytesLength) + (isUnicode ? markerUtf16BE : markerAscii);
- } else {
- markedString = originalString;
- }
- nameRecord->offset = qToBigEndian(static_cast<quint16>(markedStrings.length()));
- nameRecord->length = qToBigEndian(static_cast<quint16>(markedString.length()));
- markedStrings.append(markedString);
- }
- markedTable.append(markedStrings);
- table = markedTable;
- return true;
-}
-
-const quint32 ttfMaxFileSize = 3500000;
-
-static inline bool ttfMarkAppFont(QByteArray &ttf, const QString &marker)
-{
- const quint32 ttfChecksumNumber = 0xb1b0afba;
- const quint32 alignment = 4;
- const quint32 ttfLength = static_cast<quint32>(ttf.size());
- if (ttfLength > ttfMaxFileSize // hard limit
- || ttfLength % alignment != 0 // ttf sizes are always factors of 4
- || ttfLength <= sizeof(OffsetTable) // ttf too short
- || ttfCalcChecksum(ttf.constData(), ttf.size()) != ttfChecksumNumber) // ttf checksum is invalid
- return false;
-
- const OffsetTable *offsetTable = reinterpret_cast<const OffsetTable*>(ttf.constData());
- const quint16 numTables = qFromBigEndian(offsetTable->numTables);
- const quint32 recordsLength =
- toDWordBoundary(sizeof(OffsetTable) + numTables * sizeof(TableRecord));
- if (numTables > 30 // hard limit
- || recordsLength + numTables * alignment > ttfLength) // Corrupt ttf. Tables would not fit, even if empty.
- return false;
-
- QByteArray markedTtf;
- markedTtf.reserve(ttfLength + marker.length() * 20); // Original size plus some extra
- markedTtf.append(ttf.constData(), recordsLength);
-
- const quint32 ttfCheckSumAdjustmentOffset = 8; // Offset from the start of 'head'
- int indexOfHeadTable = -1;
- quint32 ttfDataSize = recordsLength;
- typedef QPair<quint32, quint32> Range;
- QList<Range> memoryRanges;
- memoryRanges.reserve(numTables);
- for (int i = 0; i < numTables; ++i) {
- TableRecord *tableRecord =
- reinterpret_cast<TableRecord*>(markedTtf.data() + sizeof(OffsetTable) + i * sizeof(TableRecord));
- const quint32 offset = qFromBigEndian(tableRecord->offset);
- const quint32 length = qFromBigEndian(tableRecord->length);
- const quint32 lengthAligned = toDWordBoundary(length);
- ttfDataSize += lengthAligned;
- if (offset < recordsLength // must not intersect ttf header/records
- || offset % alignment != 0 // must be aligned
- || offset > ttfLength - alignment // table out of bounds
- || offset + lengthAligned > ttfLength // table out of bounds
- || ttfDataSize > ttfLength) // tables would not fit into the ttf
- return false;
-
- foreach (const Range &range, memoryRanges)
- if (offset < range.first + range.second && offset + lengthAligned > range.first)
- return false; // Overlaps with another table
- memoryRanges.append(Range(offset, lengthAligned));
-
- quint32 checkSum = qFromBigEndian(tableRecord->checkSum);
- if (tableRecord->tag == qToBigEndian(static_cast<quint32>('head'))) {
- if (length < ttfCheckSumAdjustmentOffset + sizeof(quint32))
- return false; // Invalid 'head' table
- const quint32 *checkSumAdjustmentTag =
- reinterpret_cast<const quint32*>(ttf.constData() + offset + ttfCheckSumAdjustmentOffset);
- const quint32 checkSumAdjustment = qFromBigEndian(*checkSumAdjustmentTag);
- checkSum += checkSumAdjustment;
- indexOfHeadTable = i; // For the ttf checksum re-calculation, later
- }
- if (checkSum != ttfCalcChecksum(ttf.constData() + offset, length))
- return false; // Table checksum is invalid
-
- bool updateTableChecksum = false;
- QByteArray table;
- if (tableRecord->tag == qToBigEndian(static_cast<quint32>('name'))) {
- table = QByteArray(ttf.constData() + offset, length);
- if (!ttfMarkNameTable(table, marker))
- return false; // Name table was not markable.
- updateTableChecksum = true;
- } else {
- table = QByteArray::fromRawData(ttf.constData() + offset, length);
- }
-
- tableRecord->offset = qToBigEndian(markedTtf.size());
- tableRecord->length = qToBigEndian(table.size());
- markedTtf.append(table);
- markedTtf.append(QByteArray(dWordPadding(table.size()), 0)); // 0-padding
- if (updateTableChecksum) {
- TableRecord *tableRecord = // Need to recalculate, since markedTtf changed
- reinterpret_cast<TableRecord*>(markedTtf.data() + sizeof(OffsetTable) + i * sizeof(TableRecord));
- const quint32 offset = qFromBigEndian(tableRecord->offset);
- const quint32 length = qFromBigEndian(tableRecord->length);
- tableRecord->checkSum = qToBigEndian(ttfCalcChecksum(markedTtf.constData() + offset, length));
- }
- }
- if (indexOfHeadTable == -1 // 'head' table is mandatory
- || ttfDataSize != ttfLength) // We do not allow ttf data "holes". Neither does Symbian.
- return false;
- TableRecord *headRecord =
- reinterpret_cast<TableRecord*>(markedTtf.data() + sizeof(OffsetTable) + indexOfHeadTable * sizeof(TableRecord));
- quint32 *checkSumAdjustmentTag =
- reinterpret_cast<quint32*>(markedTtf.data() + qFromBigEndian(headRecord->offset) + ttfCheckSumAdjustmentOffset);
- *checkSumAdjustmentTag = 0;
- const quint32 ttfChecksum = ttfCalcChecksum(markedTtf.constData(), markedTtf.count());
- *checkSumAdjustmentTag = qToBigEndian(ttfChecksumNumber - ttfChecksum);
- ttf = markedTtf;
- return true;
-}
-
-static inline bool ttfCanSymbianLoadFont(const QByteArray &data, const QString &fileName)
-{
- bool result = false;
- QString ttfFileName;
- QFile tempFileGuard;
- QFileInfo info(fileName);
- if (!data.isEmpty()) {
- QTemporaryFile tempfile(QSymbianFontDatabaseExtrasImplementation::tempAppFontFolder()
- + QSymbianFontDatabaseExtrasImplementation::appFontMarker()
- + QLatin1String("XXXXXX.ttf"));
- if (!tempfile.open() || tempfile.write(data) == -1)
- return false;
- ttfFileName = QDir::toNativeSeparators(QFileInfo(tempfile).canonicalFilePath());
- tempfile.setAutoRemove(false);
- tempfile.close();
- tempFileGuard.setFileName(ttfFileName);
- if (!tempFileGuard.open(QIODevice::ReadOnly))
- return false;
- } else if (info.isFile()) {
- ttfFileName = QDir::toNativeSeparators(info.canonicalFilePath());
- } else {
- return false;
- }
-
- CFontStore *store = 0;
- RHeap* heap = User::ChunkHeap(NULL, 0x1000, 0x20000);
- if (heap) {
- QT_TRAP_THROWING(
- CleanupClosePushL(*heap);
- store = CFontStore::NewL(heap);
- CleanupStack::PushL(store);
- COpenFontRasterizer *rasterizer = COpenFontRasterizer::NewL(TUid::Uid(0x101F7F5E));
- CleanupStack::PushL(rasterizer);
- store->InstallRasterizerL(rasterizer);
- CleanupStack::Pop(rasterizer);
- TUid fontUid = {-1};
- TRAP_IGNORE(fontUid = store->AddFileL(qt_QString2TPtrC(ttfFileName)));
- if (fontUid.iUid != -1)
- result = true;
- CleanupStack::PopAndDestroy(2, heap); // heap, store
- );
- }
-
- if (tempFileGuard.isOpen())
- tempFileGuard.remove();
-
- return result;
-}
-
-static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
-{
- if (QSymbianFontDatabaseExtrasImplementation::appFontLimitReached()
- || fnt->data.size() > ttfMaxFileSize // hard limit
- || fnt->data.isEmpty() && (!fnt->fileName.endsWith(QLatin1String(".ttf"), Qt::CaseInsensitive) // Only buffer or .ttf
- || QFileInfo(fnt->fileName).size() > ttfMaxFileSize)) // hard limit
- return;
-
-// Using ttfCanSymbianLoadFont() causes crashes on app destruction (Symbian^3|PR1 and lower).
-// Therefore, not using it for now, but eventually in a later version.
-// if (!ttfCanSymbianLoadFont(fnt->data, fnt->fileName))
-// return;
-
- QFontDatabasePrivate *db = privateDb();
- if (!db)
- return;
-
- if (!db->count)
- initializeDb();
-
- QSymbianFontDatabaseExtrasImplementation *dbExtras =
- static_cast<QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
- if (!dbExtras)
- return;
-
- const QString &marker = QSymbianFontDatabaseExtrasImplementation::appFontMarker();
-
- // The QTemporaryFile object being used in the following section must be
- // destructed before letting Symbian load the TTF file. Symbian would not
- // load it otherwise, because QTemporaryFile will still keep some handle
- // on it. The scope is used to reduce the life time of the QTemporaryFile.
- // In order to prevent other processes from modifying the file between the
- // moment where the QTemporaryFile is destructed and the file is loaded by
- // Symbian, we have a QFile "tempFileGuard" outside the scope which opens
- // the file in ReadOnly mode while the QTemporaryFile is still alive.
- QFile tempFileGuard;
- {
- QTemporaryFile tempfile(QSymbianFontDatabaseExtrasImplementation::tempAppFontFolder()
- + marker + QLatin1String("XXXXXX.ttf"));
- if (!tempfile.open())
- return;
- const QString tempFileName = QFileInfo(tempfile).canonicalFilePath();
- if (fnt->data.isEmpty()) {
- QFile sourceFile(fnt->fileName);
- if (!sourceFile.open(QIODevice::ReadOnly))
- return;
- fnt->data = sourceFile.readAll();
- }
- if (!ttfMarkAppFont(fnt->data, marker) || tempfile.write(fnt->data) == -1)
- return;
- tempfile.setAutoRemove(false);
- tempfile.close(); // Tempfile still keeps a file handle, forbidding write access
- fnt->data.clear(); // The TTF data was marked and saved. Not needed in memory, anymore.
- tempFileGuard.setFileName(tempFileName);
- if (!tempFileGuard.open(QIODevice::ReadOnly))
- return;
- fnt->temporaryFileName = tempFileName;
- }
-
- const QString fullFileName = QDir::toNativeSeparators(fnt->temporaryFileName);
- QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
- const QStringList fontsOnServerBefore = qt_symbian_fontFamiliesOnFontServer();
- const TInt err =
- S60->screenDevice()->AddFile(qt_QString2TPtrC(fullFileName), fnt->screenDeviceFontFileId);
- tempFileGuard.close(); // Did its job
- const QStringList fontsOnServerAfter = qt_symbian_fontFamiliesOnFontServer();
- if (err == KErrNone && fontsOnServerBefore.count() < fontsOnServerAfter.count()) { // Added to screen device?
- int fontOnServerIndex = fontsOnServerAfter.count() - 1;
- for (int i = 0; i < fontsOnServerBefore.count(); i++) {
- if (fontsOnServerBefore.at(i) != fontsOnServerAfter.at(i)) {
- fontOnServerIndex = i;
- break;
- }
- }
-
- // Must remove all font engines with their CFonts, first.
- QFontCache::instance()->clear();
- db->free();
- QSymbianFontDatabaseExtrasImplementation::clear();
-
- if (!QSymbianTypeFaceExtras::symbianFontTableApiAvailable())
- fnt->fontStoreFontFileUid = dbExtras->addFontFileToFontStore(QFileInfo(fullFileName));
-
- const QString &appFontName = fontsOnServerAfter.at(fontOnServerIndex);
- fnt->families.append(qt_symbian_appFontNameWithoutMarker(appFontName));
- if (!qt_symbian_fontNameHasAppFontMarker(appFontName)
- || !registerScreenDeviceFont(fontOnServerIndex, dbExtras))
- dbExtras->removeAppFontData(fnt);
- } else {
- if (fnt->screenDeviceFontFileId > 0)
- S60->screenDevice()->RemoveFile(fnt->screenDeviceFontFileId); // May still have the file open!
- QFile::remove(fnt->temporaryFileName);
- *fnt = QFontDatabasePrivate::ApplicationFont();
- }
- lock.relock();
-}
-
-bool QFontDatabase::removeApplicationFont(int handle)
-{
- QMutexLocker locker(fontDatabaseMutex());
-
- QFontDatabasePrivate *db = privateDb();
- if (!db || handle < 0 || handle >= db->applicationFonts.count())
- return false;
- QSymbianFontDatabaseExtrasImplementation *dbExtras =
- static_cast<QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
- if (!dbExtras)
- return false;
-
- QFontDatabasePrivate::ApplicationFont *fnt = &db->applicationFonts[handle];
- if (fnt->families.isEmpty())
- return true; // Nothing to remove. Return peacefully.
-
- // Must remove all font engines with their CFonts, first
- QFontCache::instance()->clear();
- db->free();
- dbExtras->removeAppFontData(fnt);
-
- db->invalidate(); // This will just emit 'fontDatabaseChanged()'
- return true;
-}
-
-bool QFontDatabase::removeAllApplicationFonts()
-{
- QMutexLocker locker(fontDatabaseMutex());
-
- const int applicationFontsCount = privateDb()->applicationFonts.count();
- for (int i = 0; i < applicationFontsCount; ++i)
- if (!removeApplicationFont(i))
- return false;
- return true;
-}
-
-bool QFontDatabase::supportsThreadedFontRendering()
-{
- return QSymbianTypeFaceExtras::symbianFontTableApiAvailable();
-}
-
-static
-QFontDef cleanedFontDef(const QFontDef &req)
-{
- QFontDef result = req;
- if (result.pixelSize <= 0) {
- result.pixelSize = QFontEngineS60::pointsToPixels(qMax(qreal(1.0), result.pointSize));
- result.pointSize = 0;
- }
- return result;
-}
-
-QFontEngine *QFontDatabase::findFont(int script, const QFontPrivate *d, const QFontDef &req)
-{
- const QFontCache::Key key(cleanedFontDef(req), script);
-
- if (!privateDb()->count)
- initializeDb();
-
- QFontEngine *fe = QFontCache::instance()->findEngine(key);
- if (!fe) {
- // Making sure that fe->fontDef.family will be an existing font.
- initializeDb();
- QFontDatabasePrivate *db = privateDb();
- QtFontDesc desc;
- QList<int> blacklistedFamilies;
- match(script, key.def, key.def.family, QString(), -1, &desc, blacklistedFamilies);
- if (!desc.family) // falling back to application font
- desc.family = db->family(QApplication::font().defaultFamily());
- Q_ASSERT(desc.family);
-
- // Making sure that desc.family supports the requested script
- QtFontDesc mappedDesc;
- bool supportsScript = false;
- do {
- match(script, req, QString(), QString(), -1, &mappedDesc, blacklistedFamilies);
- if (mappedDesc.family == desc.family) {
- supportsScript = true;
- break;
- }
- blacklistedFamilies.append(mappedDesc.familyIndex);
- } while (mappedDesc.family);
- if (!supportsScript) {
- blacklistedFamilies.clear();
- match(script, req, QString(), QString(), -1, &mappedDesc, blacklistedFamilies);
- if (mappedDesc.family)
- desc = mappedDesc;
- }
-
- const QString fontFamily = desc.family->name;
- QFontDef request = req;
- request.family = fontFamily;
-#ifdef QT_NO_FREETYPE
- const QSymbianFontDatabaseExtrasImplementation *dbExtras =
- static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
- const QSymbianTypeFaceExtras *typeFaceExtras =
- dbExtras->extras(fontFamily, request.weight > QFont::Normal, request.style != QFont::StyleNormal);
-
- // We need a valid pixelSize, e.g. for lineThickness()
- if (request.pixelSize < 0)
- request.pixelSize = request.pointSize * d->dpi / 72;
-
- fe = new QFontEngineS60(request, typeFaceExtras);
-#else // QT_NO_FREETYPE
- Q_UNUSED(d)
- QFontEngine::FaceId faceId;
- const QtFontFamily * const reqQtFontFamily = db->family(fontFamily);
- faceId.filename = reqQtFontFamily->fontFilename;
- faceId.index = reqQtFontFamily->fontFileIndex;
-
- QFontEngineFTS60 *fte = new QFontEngineFTS60(cleanedFontDef(request));
- if (fte->init(faceId, true, QFontEngineFT::Format_A8))
- fe = fte;
- else
- delete fte;
-#endif // QT_NO_FREETYPE
-
- Q_ASSERT(fe);
- if (script == QUnicodeTables::Common
- && !(req.styleStrategy & QFont::NoFontMerging)
- && !fe->symbol) {
-
- QStringList commonFonts;
- for (int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws) {
- if (scriptForWritingSystem[ws] != script)
- continue;
- for (int i = 0; i < db->count; ++i) {
- if (db->families[i]->writingSystems[ws] & QtFontFamily::Supported)
- commonFonts.append(db->families[i]->name);
- }
- }
-
- // Hack: Prioritize .ccc fonts
- const QString niceEastAsianFont(QLatin1String("Sans MT 936_S60"));
- if (commonFonts.removeAll(niceEastAsianFont) > 0)
- commonFonts.prepend(niceEastAsianFont);
-
- fe = new QFontEngineMultiS60(fe, script, commonFonts);
- }
- }
- fe->ref.ref();
- QFontCache::instance()->insertEngine(key, fe);
- return fe;
-}
-
-void QFontDatabase::load(const QFontPrivate *d, int script)
-{
- QFontEngine *fe = 0;
- QFontDef req = d->request;
-
- if (!d->engineData) {
- const QFontCache::Key key(cleanedFontDef(req), script);
- getEngineData(d, key);
- }
-
- // the cached engineData could have already loaded the engine we want
- if (d->engineData->engines[script])
- fe = d->engineData->engines[script];
-
- if (!fe) {
- if (qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) {
- fe = new QTestFontEngine(req.pixelSize);
- fe->fontDef = req;
- } else {
- fe = findFont(script, d, req);
- }
- d->engineData->engines[script] = fe;
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfontdatabase_win.cpp b/src/gui/text/qfontdatabase_win.cpp
deleted file mode 100644
index 788eb307c3..0000000000
--- a/src/gui/text/qfontdatabase_win.cpp
+++ /dev/null
@@ -1,1348 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qt_windows.h"
-#include <qmath.h>
-#include <private/qapplication_p.h>
-#include "qfont_p.h"
-#include "qfontengine_p.h"
-#include "qpaintdevice.h"
-#include <private/qsystemlibrary_p.h>
-#include "qabstractfileengine.h"
-#include "qendian.h"
-
-#if !defined(QT_NO_DIRECTWRITE)
-# include "qsettings.h"
-# include "qfontenginedirectwrite_p.h"
-#endif
-
-#ifdef Q_OS_WINCE
-# include <QTemporaryFile>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-extern HDC shared_dc(); // common dc for all fonts
-
-#ifdef MAKE_TAG
-#undef MAKE_TAG
-#endif
-// GetFontData expects the tags in little endian ;(
-#define MAKE_TAG(ch1, ch2, ch3, ch4) (\
- (((quint32)(ch4)) << 24) | \
- (((quint32)(ch3)) << 16) | \
- (((quint32)(ch2)) << 8) | \
- ((quint32)(ch1)) \
- )
-
-static HFONT stock_sysfont = 0;
-
-static bool localizedName(const QString &name)
-{
- const QChar *c = name.unicode();
- for(int i = 0; i < name.length(); ++i) {
- if(c[i].unicode() >= 0x100)
- return true;
- }
- return false;
-}
-
-static inline quint16 getUShort(const unsigned char *p)
-{
- quint16 val;
- val = *p++ << 8;
- val |= *p;
-
- return val;
-}
-
-static QString getEnglishName(const uchar *table, quint32 bytes)
-{
- QString i18n_name;
- enum {
- NameRecordSize = 12,
- FamilyId = 1,
- MS_LangIdEnglish = 0x009
- };
-
- // get the name table
- quint16 count;
- quint16 string_offset;
- const unsigned char *names;
-
- int microsoft_id = -1;
- int apple_id = -1;
- int unicode_id = -1;
-
- if(getUShort(table) != 0)
- goto error;
-
- count = getUShort(table+2);
- string_offset = getUShort(table+4);
- names = table + 6;
-
- if(string_offset >= bytes || 6 + count*NameRecordSize > string_offset)
- goto error;
-
- for(int i = 0; i < count; ++i) {
- // search for the correct name entry
-
- quint16 platform_id = getUShort(names + i*NameRecordSize);
- quint16 encoding_id = getUShort(names + 2 + i*NameRecordSize);
- quint16 language_id = getUShort(names + 4 + i*NameRecordSize);
- quint16 name_id = getUShort(names + 6 + i*NameRecordSize);
-
- if(name_id != FamilyId)
- continue;
-
- enum {
- PlatformId_Unicode = 0,
- PlatformId_Apple = 1,
- PlatformId_Microsoft = 3
- };
-
- quint16 length = getUShort(names + 8 + i*NameRecordSize);
- quint16 offset = getUShort(names + 10 + i*NameRecordSize);
- if(DWORD(string_offset + offset + length) >= bytes)
- continue;
-
- if ((platform_id == PlatformId_Microsoft
- && (encoding_id == 0 || encoding_id == 1))
- && (language_id & 0x3ff) == MS_LangIdEnglish
- && microsoft_id == -1)
- microsoft_id = i;
- // not sure if encoding id 4 for Unicode is utf16 or ucs4...
- else if(platform_id == PlatformId_Unicode && encoding_id < 4 && unicode_id == -1)
- unicode_id = i;
- else if(platform_id == PlatformId_Apple && encoding_id == 0 && language_id == 0)
- apple_id = i;
- }
- {
- bool unicode = false;
- int id = -1;
- if(microsoft_id != -1) {
- id = microsoft_id;
- unicode = true;
- } else if(apple_id != -1) {
- id = apple_id;
- unicode = false;
- } else if (unicode_id != -1) {
- id = unicode_id;
- unicode = true;
- }
- if(id != -1) {
- quint16 length = getUShort(names + 8 + id*NameRecordSize);
- quint16 offset = getUShort(names + 10 + id*NameRecordSize);
- if(unicode) {
- // utf16
-
- length /= 2;
- i18n_name.resize(length);
- QChar *uc = (QChar *) i18n_name.unicode();
- const unsigned char *string = table + string_offset + offset;
- for(int i = 0; i < length; ++i)
- uc[i] = getUShort(string + 2*i);
- } else {
- // Apple Roman
-
- i18n_name.resize(length);
- QChar *uc = (QChar *) i18n_name.unicode();
- const unsigned char *string = table + string_offset + offset;
- for(int i = 0; i < length; ++i)
- uc[i] = QLatin1Char(string[i]);
- }
- }
- }
- error:
- //qDebug("got i18n name of '%s' for font '%s'", i18n_name.latin1(), familyName.toLocal8Bit().data());
- return i18n_name;
-}
-
-static QString getEnglishName(const QString &familyName)
-{
- QString i18n_name;
-
- HDC hdc = GetDC( 0 );
- LOGFONT lf;
- memset(&lf, 0, sizeof(LOGFONT));
- memcpy(lf.lfFaceName, familyName.utf16(), qMin(LF_FACESIZE, familyName.length()) * sizeof(wchar_t));
- lf.lfCharSet = DEFAULT_CHARSET;
- HFONT hfont = CreateFontIndirect(&lf);
-
- if(!hfont) {
- ReleaseDC(0, hdc);
- return QString();
- }
-
- HGDIOBJ oldobj = SelectObject( hdc, hfont );
-
- const DWORD name_tag = MAKE_TAG( 'n', 'a', 'm', 'e' );
-
- // get the name table
- unsigned char *table = 0;
-
- DWORD bytes = GetFontData( hdc, name_tag, 0, 0, 0 );
- if ( bytes == GDI_ERROR ) {
- // ### Unused variable
- /* int err = GetLastError(); */
- goto error;
- }
-
- table = new unsigned char[bytes];
- GetFontData(hdc, name_tag, 0, table, bytes);
- if ( bytes == GDI_ERROR )
- goto error;
-
- i18n_name = getEnglishName(table, bytes);
-error:
- delete [] table;
- SelectObject( hdc, oldobj );
- DeleteObject( hfont );
- ReleaseDC( 0, hdc );
-
- //qDebug("got i18n name of '%s' for font '%s'", i18n_name.latin1(), familyName.toLocal8Bit().data());
- return i18n_name;
-}
-
-extern QFont::Weight weightFromInteger(int weight); // qfontdatabase.cpp
-
-static
-void addFontToDatabase(QString familyName, const QString &scriptName,
- TEXTMETRIC *textmetric,
- const FONTSIGNATURE *signature,
- int type)
-{
- const int script = -1;
- const QString foundryName;
- Q_UNUSED(script);
-
- bool italic = false;
- int weight;
- bool fixed;
- bool ttf;
- bool scalable;
- int size;
-
-// QString escript = QString::fromWCharArray(f->elfScript);
-// qDebug("script=%s", escript.latin1());
-
- NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric;
- fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH);
- ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE);
- scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE);
- size = scalable ? SMOOTH_SCALABLE : tm->tmHeight;
- italic = tm->tmItalic;
- weight = tm->tmWeight;
-
- // the "@family" fonts are just the same as "family". Ignore them.
- if (familyName[0] != QLatin1Char('@') && !familyName.startsWith(QLatin1String("WST_"))) {
- QtFontStyle::Key styleKey;
- styleKey.style = italic ? QFont::StyleItalic : QFont::StyleNormal;
- styleKey.weight = weightFromInteger(weight);
-
- QtFontFamily *family = privateDb()->family(familyName, true);
-
- if(ttf && localizedName(familyName) && family->english_name.isEmpty())
- family->english_name = getEnglishName(familyName);
-
- QtFontFoundry *foundry = family->foundry(foundryName, true);
- QtFontStyle *style = foundry->style(styleKey, QString(), true);
- style->smoothScalable = scalable;
- style->pixelSize( size, TRUE);
-
- // add fonts windows can generate for us:
- if (styleKey.weight <= QFont::DemiBold) {
- QtFontStyle::Key key(styleKey);
- key.weight = QFont::Bold;
- QtFontStyle *style = foundry->style(key, QString(), true);
- style->smoothScalable = scalable;
- style->pixelSize( size, TRUE);
- }
- if (styleKey.style != QFont::StyleItalic) {
- QtFontStyle::Key key(styleKey);
- key.style = QFont::StyleItalic;
- QtFontStyle *style = foundry->style(key, QString(), true);
- style->smoothScalable = scalable;
- style->pixelSize( size, TRUE);
- }
- if (styleKey.weight <= QFont::DemiBold && styleKey.style != QFont::StyleItalic) {
- QtFontStyle::Key key(styleKey);
- key.weight = QFont::Bold;
- key.style = QFont::StyleItalic;
- QtFontStyle *style = foundry->style(key, QString(), true);
- style->smoothScalable = scalable;
- style->pixelSize( size, TRUE);
- }
-
- family->fixedPitch = fixed;
-
- if (!family->writingSystemCheck && type & TRUETYPE_FONTTYPE) {
- quint32 unicodeRange[4] = {
- signature->fsUsb[0], signature->fsUsb[1],
- signature->fsUsb[2], signature->fsUsb[3]
- };
-#ifdef Q_WS_WINCE
- if (signature->fsUsb[0] == 0) {
- // If the unicode ranges bit mask is zero then
- // EnumFontFamiliesEx failed to determine it properly.
- // In this case we just pretend that the font supports all languages.
- unicodeRange[0] = 0xbfffffff; // second most significant bit must be zero
- unicodeRange[1] = 0xffffffff;
- unicodeRange[2] = 0xffffffff;
- unicodeRange[3] = 0xffffffff;
- }
-#endif
- quint32 codePageRange[2] = {
- signature->fsCsb[0], signature->fsCsb[1]
- };
- QList<QFontDatabase::WritingSystem> systems = qt_determine_writing_systems_from_truetype_bits(unicodeRange, codePageRange);
-
- for (int i = 0; i < systems.count(); ++i) {
- QFontDatabase::WritingSystem writingSystem = systems.at(i);
-
- // ### Hack to work around problem with Thai text on Windows 7. Segoe UI contains
- // the symbol for Baht, and Windows thus reports that it supports the Thai script.
- // Since it's the default UI font on this platform, most widgets will be unable to
- // display Thai text by default. As a temporary work around, we special case Segoe UI
- // and remove the Thai script from its list of supported writing systems.
- if (writingSystem != QFontDatabase::Thai || familyName != QLatin1String("Segoe UI"))
- family->writingSystems[writingSystem] = QtFontFamily::Supported;
- }
- } else if (!family->writingSystemCheck) {
- //qDebug("family='%s' script=%s", family->name.latin1(), script.latin1());
- if (scriptName == QLatin1String("Western")
- || scriptName == QLatin1String("Baltic")
- || scriptName == QLatin1String("Central European")
- || scriptName == QLatin1String("Turkish")
- || scriptName == QLatin1String("Vietnamese"))
- family->writingSystems[QFontDatabase::Latin] = QtFontFamily::Supported;
- else if (scriptName == QLatin1String("Thai"))
- family->writingSystems[QFontDatabase::Thai] = QtFontFamily::Supported;
- else if (scriptName == QLatin1String("Symbol")
- || scriptName == QLatin1String("Other"))
- family->writingSystems[QFontDatabase::Symbol] = QtFontFamily::Supported;
- else if (scriptName == QLatin1String("OEM/Dos"))
- family->writingSystems[QFontDatabase::Latin] = QtFontFamily::Supported;
- else if (scriptName == QLatin1String("CHINESE_GB2312"))
- family->writingSystems[QFontDatabase::SimplifiedChinese] = QtFontFamily::Supported;
- else if (scriptName == QLatin1String("CHINESE_BIG5"))
- family->writingSystems[QFontDatabase::TraditionalChinese] = QtFontFamily::Supported;
- else if (scriptName == QLatin1String("Cyrillic"))
- family->writingSystems[QFontDatabase::Cyrillic] = QtFontFamily::Supported;
- else if (scriptName == QLatin1String("Hangul"))
- family->writingSystems[QFontDatabase::Korean] = QtFontFamily::Supported;
- else if (scriptName == QLatin1String("Hebrew"))
- family->writingSystems[QFontDatabase::Hebrew] = QtFontFamily::Supported;
- else if (scriptName == QLatin1String("Greek"))
- family->writingSystems[QFontDatabase::Greek] = QtFontFamily::Supported;
- else if (scriptName == QLatin1String("Japanese"))
- family->writingSystems[QFontDatabase::Japanese] = QtFontFamily::Supported;
- else if (scriptName == QLatin1String("Arabic"))
- family->writingSystems[QFontDatabase::Arabic] = QtFontFamily::Supported;
- }
- }
-}
-
-static
-int CALLBACK
-storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric, int type, LPARAM /*p*/)
-{
- QString familyName = QString::fromWCharArray(f->elfLogFont.lfFaceName);
- QString script = QString::fromWCharArray(f->elfScript);
-
- FONTSIGNATURE signature = textmetric->ntmFontSig;
-
- // NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is
- // identical to a TEXTMETRIC except for the last four members, which we don't use
- // anyway
- addFontToDatabase(familyName, script, (TEXTMETRIC *)textmetric, &signature, type);
- // keep on enumerating
- return 1;
-}
-
-static
-void populate_database(const QString& fam)
-{
- QFontDatabasePrivate *d = privateDb();
- if (!d)
- return;
-
- QtFontFamily *family = 0;
- if(!fam.isEmpty()) {
- family = d->family(fam);
- if(family && family->loaded)
- return;
- } else if (d->count) {
- return;
- }
-
- HDC dummy = GetDC(0);
-
- LOGFONT lf;
- lf.lfCharSet = DEFAULT_CHARSET;
- if (fam.isNull()) {
- lf.lfFaceName[0] = 0;
- } else {
- memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded
- }
- lf.lfPitchAndFamily = 0;
-
- EnumFontFamiliesEx(dummy, &lf,
- (FONTENUMPROC)storeFont, (LPARAM)privateDb(), 0);
-
- ReleaseDC(0, dummy);
-
- for (int i = 0; i < d->applicationFonts.count(); ++i) {
- QFontDatabasePrivate::ApplicationFont fnt = d->applicationFonts.at(i);
- if (!fnt.memoryFont)
- continue;
- for (int j = 0; j < fnt.families.count(); ++j) {
- const QString familyName = fnt.families.at(j);
- HDC hdc = GetDC(0);
- LOGFONT lf;
- memset(&lf, 0, sizeof(LOGFONT));
- memcpy(lf.lfFaceName, familyName.utf16(), sizeof(wchar_t) * qMin(LF_FACESIZE, familyName.size()));
- lf.lfCharSet = DEFAULT_CHARSET;
- HFONT hfont = CreateFontIndirect(&lf);
- HGDIOBJ oldobj = SelectObject(hdc, hfont);
-
- TEXTMETRIC textMetrics;
- GetTextMetrics(hdc, &textMetrics);
-
- addFontToDatabase(familyName, QString(),
- &textMetrics,
- &fnt.signatures.at(j),
- TRUETYPE_FONTTYPE);
-
- SelectObject(hdc, oldobj);
- DeleteObject(hfont);
- ReleaseDC(0, hdc);
- }
- }
-
- if(!fam.isEmpty()) {
- family = d->family(fam);
- if(family) {
- if(!family->writingSystemCheck) {
- }
- family->loaded = true;
- }
- }
-}
-
-static void initializeDb()
-{
- QFontDatabasePrivate *db = privateDb();
- if (!db || db->count)
- return;
-
- populate_database(QString());
-
-#ifdef QFONTDATABASE_DEBUG
- // print the database
- for (int f = 0; f < db->count; f++) {
- QtFontFamily *family = db->families[f];
- qDebug(" %s: %p", qPrintable(family->name), family);
- populate_database(family->name);
-
-#if 0
- qDebug(" scripts supported:");
- for (int i = 0; i < QUnicodeTables::ScriptCount; i++)
- if(family->writingSystems[i] & QtFontFamily::Supported)
- qDebug(" %d", i);
- for (int fd = 0; fd < family->count; fd++) {
- QtFontFoundry *foundry = family->foundries[fd];
- qDebug(" %s", foundry->name.latin1());
- for (int s = 0; s < foundry->count; s++) {
- QtFontStyle *style = foundry->styles[s];
- qDebug(" style: style=%d weight=%d smooth=%d", style->key.style,
- style->key.weight, style->smoothScalable );
- if(!style->smoothScalable) {
- for(int i = 0; i < style->count; ++i) {
- qDebug(" %d", style->pixelSizes[i].pixelSize);
- }
- }
- }
- }
-#endif
- }
-#endif // QFONTDATABASE_DEBUG
-
-}
-
-static inline void load(const QString &family = QString(), int = -1)
-{
- populate_database(family);
-}
-
-
-
-
-
-// --------------------------------------------------------------------------------------
-// font loader
-// --------------------------------------------------------------------------------------
-
-
-
-static void initFontInfo(QFontEngineWin *fe, const QFontDef &request, HDC fontHdc, int dpi)
-{
- fe->fontDef = request; // most settings are equal
-
- HDC dc = ((request.styleStrategy & QFont::PreferDevice) && fontHdc) ? fontHdc : shared_dc();
- SelectObject(dc, fe->hfont);
- wchar_t n[64];
- GetTextFace(dc, 64, n);
- fe->fontDef.family = QString::fromWCharArray(n);
- fe->fontDef.fixedPitch = !(fe->tm.tmPitchAndFamily & TMPF_FIXED_PITCH);
- if (fe->fontDef.pointSize < 0) {
- fe->fontDef.pointSize = fe->fontDef.pixelSize * 72. / dpi;
- } else if (fe->fontDef.pixelSize == -1) {
- fe->fontDef.pixelSize = qRound(fe->fontDef.pointSize * dpi / 72.);
- }
-}
-
-#if !defined(QT_NO_DIRECTWRITE)
-static void initFontInfo(QFontEngineDirectWrite *fe, const QFontDef &request,
- int dpi, IDWriteFont *font)
-{
- fe->fontDef = request;
-
- IDWriteFontFamily *fontFamily = NULL;
- HRESULT hr = font->GetFontFamily(&fontFamily);
-
- IDWriteLocalizedStrings *familyNames = NULL;
- if (SUCCEEDED(hr))
- hr = fontFamily->GetFamilyNames(&familyNames);
-
- UINT32 index = 0;
- BOOL exists = false;
-
- wchar_t localeName[LOCALE_NAME_MAX_LENGTH];
-
- if (SUCCEEDED(hr)) {
- int defaultLocaleSuccess = GetUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH);
-
- if (defaultLocaleSuccess)
- hr = familyNames->FindLocaleName(localeName, &index, &exists);
-
- if (SUCCEEDED(hr) && !exists)
- hr = familyNames->FindLocaleName(L"en-us", &index, &exists);
- }
-
- if (!exists)
- index = 0;
-
- UINT32 length = 0;
- if (SUCCEEDED(hr))
- hr = familyNames->GetStringLength(index, &length);
-
- wchar_t *name = new (std::nothrow) wchar_t[length+1];
- if (name == NULL)
- hr = E_OUTOFMEMORY;
-
- // Get the family name.
- if (SUCCEEDED(hr))
- hr = familyNames->GetString(index, name, length + 1);
-
- if (SUCCEEDED(hr))
- fe->fontDef.family = QString::fromWCharArray(name);
-
- delete[] name;
- if (familyNames != NULL)
- familyNames->Release();
-
- if (FAILED(hr))
- qErrnoWarning(hr, "initFontInfo: Failed to get family name");
-
- if (fe->fontDef.pointSize < 0)
- fe->fontDef.pointSize = fe->fontDef.pixelSize * 72. / dpi;
- else if (fe->fontDef.pixelSize == -1)
- fe->fontDef.pixelSize = qRound(fe->fontDef.pointSize * dpi / 72.);
-}
-#endif
-
-static const char *other_tryFonts[] = {
- "Arial",
- "MS UI Gothic",
- "Gulim",
- "SimSun",
- "PMingLiU",
- "Arial Unicode MS",
- 0
-};
-
-static const char *jp_tryFonts [] = {
- "MS UI Gothic",
- "Arial",
- "Gulim",
- "SimSun",
- "PMingLiU",
- "Arial Unicode MS",
- 0
-};
-
-static const char *ch_CN_tryFonts [] = {
- "SimSun",
- "Arial",
- "PMingLiU",
- "Gulim",
- "MS UI Gothic",
- "Arial Unicode MS",
- 0
-};
-
-static const char *ch_TW_tryFonts [] = {
- "PMingLiU",
- "Arial",
- "SimSun",
- "Gulim",
- "MS UI Gothic",
- "Arial Unicode MS",
- 0
-};
-
-static const char *kr_tryFonts[] = {
- "Gulim",
- "Arial",
- "PMingLiU",
- "SimSun",
- "MS UI Gothic",
- "Arial Unicode MS",
- 0
-};
-
-static const char **tryFonts = 0;
-
-#if !defined(QT_NO_DIRECTWRITE)
-static QString fontNameSubstitute(const QString &familyName)
-{
- QLatin1String key("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\"
- "FontSubstitutes");
- return QSettings(key, QSettings::NativeFormat).value(familyName, familyName).toString();
-}
-#endif
-
-static inline HFONT systemFont()
-{
- if (stock_sysfont == 0)
- stock_sysfont = (HFONT)GetStockObject(SYSTEM_FONT);
- return stock_sysfont;
-}
-
-#if !defined(DEFAULT_GUI_FONT)
-#define DEFAULT_GUI_FONT 17
-#endif
-
-static QFontEngine *loadEngine(int script, const QFontDef &request,
- HDC fontHdc, int dpi, bool rawMode,
- const QtFontDesc *desc,
- const QStringList &family_list)
-{
- LOGFONT lf;
- memset(&lf, 0, sizeof(LOGFONT));
-
- bool useDevice = (request.styleStrategy & QFont::PreferDevice) && fontHdc;
-
- HDC hdc = shared_dc();
- QString font_name = desc != 0 ? desc->family->name : request.family;
-
- if (useDevice) {
- hdc = fontHdc;
- font_name = request.family;
- }
-
- bool stockFont = false;
- bool preferClearTypeAA = false;
-
- HFONT hfont = 0;
-
-
-#if !defined(QT_NO_DIRECTWRITE)
- bool useDirectWrite = (request.hintingPreference == QFont::PreferNoHinting)
- || (request.hintingPreference == QFont::PreferVerticalHinting);
- IDWriteFont *directWriteFont = 0;
-#else
- bool useDirectWrite = false;
-#endif
-
- if (rawMode) { // will choose a stock font
- int f, deffnt = SYSTEM_FONT;
- QString fam = desc != 0 ? desc->family->name.toLower() : request.family.toLower();
- if (fam == QLatin1String("default"))
- f = deffnt;
- else if (fam == QLatin1String("system"))
- f = SYSTEM_FONT;
-#ifndef Q_WS_WINCE
- else if (fam == QLatin1String("system_fixed"))
- f = SYSTEM_FIXED_FONT;
- else if (fam == QLatin1String("ansi_fixed"))
- f = ANSI_FIXED_FONT;
- else if (fam == QLatin1String("ansi_var"))
- f = ANSI_VAR_FONT;
- else if (fam == QLatin1String("device_default"))
- f = DEVICE_DEFAULT_FONT;
- else if (fam == QLatin1String("oem_fixed"))
- f = OEM_FIXED_FONT;
-#endif
- else if (fam[0] == QLatin1Char('#'))
- f = fam.right(fam.length()-1).toInt();
- else
- f = deffnt;
- hfont = (HFONT)GetStockObject(f);
- if (!hfont) {
- qErrnoWarning("QFontEngine::loadEngine: GetStockObject failed");
- hfont = systemFont();
- }
- stockFont = true;
- } else {
-
- int hint = FF_DONTCARE;
- switch (request.styleHint) {
- case QFont::Helvetica:
- hint = FF_SWISS;
- break;
- case QFont::Times:
- hint = FF_ROMAN;
- break;
- case QFont::Courier:
- hint = FF_MODERN;
- break;
- case QFont::OldEnglish:
- hint = FF_DECORATIVE;
- break;
- case QFont::System:
- hint = FF_MODERN;
- break;
- default:
- break;
- }
-
- lf.lfHeight = -qRound(request.pixelSize);
- lf.lfWidth = 0;
- lf.lfEscapement = 0;
- lf.lfOrientation = 0;
- if (desc == 0 || desc->style->key.weight == 50)
- lf.lfWeight = FW_DONTCARE;
- else
- lf.lfWeight = (desc->style->key.weight*900)/99;
- lf.lfItalic = (desc != 0 && desc->style->key.style != QFont::StyleNormal);
- lf.lfCharSet = DEFAULT_CHARSET;
-
- int strat = OUT_DEFAULT_PRECIS;
- if (request.styleStrategy & QFont::PreferBitmap) {
- strat = OUT_RASTER_PRECIS;
-#ifndef Q_WS_WINCE
- } else if (request.styleStrategy & QFont::PreferDevice) {
- strat = OUT_DEVICE_PRECIS;
- } else if (request.styleStrategy & QFont::PreferOutline) {
- strat = OUT_OUTLINE_PRECIS;
- } else if (request.styleStrategy & QFont::ForceOutline) {
- strat = OUT_TT_ONLY_PRECIS;
-#endif
- }
-
- lf.lfOutPrecision = strat;
-
- int qual = DEFAULT_QUALITY;
-
- if (request.styleStrategy & QFont::PreferMatch)
- qual = DRAFT_QUALITY;
-#ifndef Q_WS_WINCE
- else if (request.styleStrategy & QFont::PreferQuality)
- qual = PROOF_QUALITY;
-#endif
-
- if (request.styleStrategy & QFont::PreferAntialias) {
- if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP) {
- qual = CLEARTYPE_QUALITY;
- preferClearTypeAA = true;
- } else {
- qual = ANTIALIASED_QUALITY;
- }
- } else if (request.styleStrategy & QFont::NoAntialias) {
- qual = NONANTIALIASED_QUALITY;
- }
-
- lf.lfQuality = qual;
-
- lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
- lf.lfPitchAndFamily = DEFAULT_PITCH | hint;
-
- QString fam = font_name;
-
- if(fam.isEmpty())
- fam = QLatin1String("MS Sans Serif");
-
- if ((fam == QLatin1String("MS Sans Serif"))
- && (request.style == QFont::StyleItalic || (-lf.lfHeight > 18 && -lf.lfHeight != 24))) {
- fam = QLatin1String("Arial"); // MS Sans Serif has bearing problems in italic, and does not scale
- }
- if (fam == QLatin1String("Courier") && !(request.styleStrategy & QFont::PreferBitmap))
- fam = QLatin1String("Courier New");
-
- memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded
-
- hfont = CreateFontIndirect(&lf);
- if (!hfont)
- qErrnoWarning("QFontEngine::loadEngine: CreateFontIndirect failed");
-
- stockFont = (hfont == 0);
- bool ttf = false;
- int avWidth = 0;
- BOOL res;
- HGDIOBJ oldObj = SelectObject(hdc, hfont);
-
- TEXTMETRIC tm;
- res = GetTextMetrics(hdc, &tm);
- avWidth = tm.tmAveCharWidth;
- ttf = tm.tmPitchAndFamily & TMPF_TRUETYPE;
- SelectObject(hdc, oldObj);
-
- if (!ttf || !useDirectWrite) {
- useDirectWrite = false;
-
- if (hfont && (!ttf || request.stretch != 100)) {
- DeleteObject(hfont);
- if (!res)
- qErrnoWarning("QFontEngine::loadEngine: GetTextMetrics failed");
- lf.lfWidth = avWidth * request.stretch/100;
- hfont = CreateFontIndirect(&lf);
- if (!hfont)
- qErrnoWarning("QFontEngine::loadEngine: CreateFontIndirect with stretch failed");
- }
-
-#ifndef Q_WS_WINCE
- if (hfont == 0) {
- hfont = (HFONT)GetStockObject(ANSI_VAR_FONT);
- stockFont = true;
- }
-#else
- if (hfont == 0) {
- hfont = (HFONT)GetStockObject(SYSTEM_FONT);
- stockFont = true;
- }
-#endif
-
- }
-
-#if !defined(QT_NO_DIRECTWRITE)
- else {
- // Default to false for DirectWrite (and re-enable once/if everything
- // turns out okay)
- useDirectWrite = false;
-
- QFontDatabasePrivate *db = privateDb();
- if (db->directWriteFactory == 0) {
- HRESULT hr = DWriteCreateFactory(
- DWRITE_FACTORY_TYPE_SHARED,
- __uuidof(IDWriteFactory),
- reinterpret_cast<IUnknown **>(&db->directWriteFactory)
- );
- if (FAILED(hr)) {
- qErrnoWarning("QFontEngine::loadEngine: DWriteCreateFactory failed");
- } else {
- hr = db->directWriteFactory->GetGdiInterop(&db->directWriteGdiInterop);
- if (FAILED(hr))
- qErrnoWarning("QFontEngine::loadEngine: GetGdiInterop failed");
- }
- }
-
- if (db->directWriteGdiInterop != 0) {
- QString nameSubstitute = fontNameSubstitute(QString::fromWCharArray(lf.lfFaceName));
- memcpy(lf.lfFaceName, nameSubstitute.utf16(),
- sizeof(wchar_t) * qMin(nameSubstitute.length() + 1, LF_FACESIZE));
-
- HRESULT hr = db->directWriteGdiInterop->CreateFontFromLOGFONT(
- &lf,
- &directWriteFont);
- if (FAILED(hr)) {
-#ifndef QT_NO_DEBUG
- qErrnoWarning("QFontEngine::loadEngine: CreateFontFromLOGFONT failed "
- "for %ls (0x%lx)",
- lf.lfFaceName, hr);
-#endif
- } else {
- DeleteObject(hfont);
- useDirectWrite = true;
- }
- }
- }
-#endif
-
- }
-
- QFontEngine *fe = 0;
- if (!useDirectWrite) {
- QFontEngineWin *few = new QFontEngineWin(font_name, hfont, stockFont, lf);
- if (preferClearTypeAA)
- few->glyphFormat = QFontEngineGlyphCache::Raster_RGBMask;
-
- // Also check for OpenType tables when using complex scripts
- // ### TODO: This only works for scripts that require OpenType. More generally
- // for scripts that do not require OpenType we should just look at the list of
- // supported writing systems in the font's OS/2 table.
- if (scriptRequiresOpenType(script)) {
- HB_Face hbFace = few->harfbuzzFace();
- if (!hbFace || !hbFace->supported_scripts[script]) {
- FM_DEBUG(" OpenType support missing for script\n");
- delete few;
- return 0;
- }
- }
-
- initFontInfo(few, request, fontHdc, dpi);
- fe = few;
- }
-
-#if !defined(QT_NO_DIRECTWRITE)
- else {
- QFontDatabasePrivate *db = privateDb();
-
- IDWriteFontFace *directWriteFontFace = NULL;
- HRESULT hr = directWriteFont->CreateFontFace(&directWriteFontFace);
- if (SUCCEEDED(hr)) {
- QFontEngineDirectWrite *fedw = new QFontEngineDirectWrite(db->directWriteFactory,
- directWriteFontFace,
- request.pixelSize);
-
- initFontInfo(fedw, request, dpi, directWriteFont);
-
- fe = fedw;
- } else {
- qErrnoWarning(hr, "QFontEngine::loadEngine: CreateFontFace failed");
- }
- }
-
- if (directWriteFont != 0)
- directWriteFont->Release();
-#endif
-
- if(script == QUnicodeTables::Common
- && !(request.styleStrategy & QFont::NoFontMerging)
- && desc != 0
- && !(desc->family->writingSystems[QFontDatabase::Symbol] & QtFontFamily::Supported)) {
- if(!tryFonts) {
- LANGID lid = GetUserDefaultLangID();
- switch( lid&0xff ) {
- case LANG_CHINESE: // Chinese (Taiwan)
- if ( lid == 0x0804 ) // Taiwan
- tryFonts = ch_TW_tryFonts;
- else
- tryFonts = ch_CN_tryFonts;
- break;
- case LANG_JAPANESE:
- tryFonts = jp_tryFonts;
- break;
- case LANG_KOREAN:
- tryFonts = kr_tryFonts;
- break;
- default:
- tryFonts = other_tryFonts;
- break;
- }
- }
- QStringList fm = QFontDatabase().families();
- QStringList list = family_list;
- const char **tf = tryFonts;
- while(tf && *tf) {
- if(fm.contains(QLatin1String(*tf)))
- list << QLatin1String(*tf);
- ++tf;
- }
- QFontEngine *mfe = new QFontEngineMultiWin(fe, list);
- mfe->fontDef = fe->fontDef;
- fe = mfe;
- }
- return fe;
-}
-
-QFontEngine *qt_load_font_engine_win(const QFontDef &request)
-{
- // From qfont.cpp
- extern int qt_defaultDpi();
-
- QFontCache::Key key(request, QUnicodeTables::Common);
- QFontEngine *fe = QFontCache::instance()->findEngine(key);
- if (fe != 0)
- return fe;
- else
- return loadEngine(QUnicodeTables::Common, request, 0, qt_defaultDpi(), false, 0,
- QStringList());
-}
-
-const char *styleHint(const QFontDef &request)
-{
- const char *stylehint = 0;
- switch (request.styleHint) {
- case QFont::SansSerif:
- stylehint = "Arial";
- break;
- case QFont::Serif:
- stylehint = "Times New Roman";
- break;
- case QFont::TypeWriter:
- stylehint = "Courier New";
- break;
- default:
- if (request.fixedPitch)
- stylehint = "Courier New";
- break;
- }
- return stylehint;
-}
-
-static QFontEngine *loadWin(const QFontPrivate *d, int script, const QFontDef &req)
-{
- // list of families to try
- QStringList family_list = familyList(req);
-
- const char *stylehint = styleHint(d->request);
- if (stylehint)
- family_list << QLatin1String(stylehint);
-
- // append the default fallback font for the specified script
- // family_list << ... ; ###########
-
- // add the default family
- QString defaultFamily = QApplication::font().family();
- if (! family_list.contains(defaultFamily))
- family_list << defaultFamily;
-
- // add QFont::defaultFamily() to the list, for compatibility with
- // previous versions
- family_list << QApplication::font().defaultFamily();
-
- // null family means find the first font matching the specified script
- family_list << QString();
-
- QtFontDesc desc;
- QFontEngine *fe = 0;
- QList<int> blacklistedFamilies;
-
- while (!fe) {
- for (int i = 0; i < family_list.size(); ++i) {
- QString family, foundry;
- parseFontName(family_list.at(i), foundry, family);
- FM_DEBUG("loadWin: >>>>>>>>>>>>>>trying to match '%s'", family.toLatin1().data());
- QT_PREPEND_NAMESPACE(match)(script, req, family, foundry, -1, &desc, blacklistedFamilies);
- if (desc.family)
- break;
- }
- if (!desc.family)
- break;
- fe = loadEngine(script, req, d->hdc, d->dpi, d->rawMode, &desc, family_list);
- if (!fe)
- blacklistedFamilies.append(desc.familyIndex);
- }
- return fe;
-}
-
-void QFontDatabase::load(const QFontPrivate *d, int script)
-{
- // sanity checks
- if (!qApp)
- qWarning("QFontDatabase::load: Must construct QApplication first");
- Q_ASSERT(script >= 0 && script < QUnicodeTables::ScriptCount);
-
- // normalize the request to get better caching
- QFontDef req = d->request;
- if (req.pixelSize <= 0)
- req.pixelSize = floor((100.0 * req.pointSize * d->dpi) / 72. + 0.5) / 100;
- if (req.pixelSize < 1)
- req.pixelSize = 1;
- if (req.weight == 0)
- req.weight = QFont::Normal;
- if (req.stretch == 0)
- req.stretch = 100;
-
- QFontCache::Key key(req, d->rawMode ? QUnicodeTables::Common : script, d->screen);
- if (!d->engineData)
- getEngineData(d, key);
-
- // the cached engineData could have already loaded the engine we want
- if (d->engineData->engines[script])
- return;
-
- QFontEngine *fe = QFontCache::instance()->findEngine(key);
-
- // set it to the actual pointsize, so QFontInfo will do the right thing
- if (req.pointSize < 0)
- req.pointSize = req.pixelSize*72./d->dpi;
-
- if (!fe) {
- if (qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) {
- fe = new QTestFontEngine(req.pixelSize);
- fe->fontDef = req;
- } else {
- QMutexLocker locker(fontDatabaseMutex());
- if (!privateDb()->count)
- initializeDb();
- fe = loadWin(d, script, req);
- }
- if (!fe) {
- fe = new QFontEngineBox(req.pixelSize);
- fe->fontDef = QFontDef();
- }
- }
- d->engineData->engines[script] = fe;
- fe->ref.ref();
- QFontCache::instance()->insertEngine(key, fe);
-}
-
-#if !defined(FR_PRIVATE)
-#define FR_PRIVATE 0x10
-#endif
-
-typedef int (WINAPI *PtrAddFontResourceExW)(LPCWSTR, DWORD, PVOID);
-typedef HANDLE (WINAPI *PtrAddFontMemResourceEx)(PVOID, DWORD, PVOID, DWORD *);
-typedef BOOL (WINAPI *PtrRemoveFontResourceExW)(LPCWSTR, DWORD, PVOID);
-typedef BOOL (WINAPI *PtrRemoveFontMemResourceEx)(HANDLE);
-
-static QList<quint32> getTrueTypeFontOffsets(const uchar *fontData)
-{
- QList<quint32> offsets;
- const quint32 headerTag = *reinterpret_cast<const quint32 *>(fontData);
- if (headerTag != MAKE_TAG('t', 't', 'c', 'f')) {
- if (headerTag != MAKE_TAG(0, 1, 0, 0)
- && headerTag != MAKE_TAG('O', 'T', 'T', 'O')
- && headerTag != MAKE_TAG('t', 'r', 'u', 'e')
- && headerTag != MAKE_TAG('t', 'y', 'p', '1'))
- return offsets;
- offsets << 0;
- return offsets;
- }
- const quint32 numFonts = qFromBigEndian<quint32>(fontData + 8);
- for (uint i = 0; i < numFonts; ++i) {
- offsets << qFromBigEndian<quint32>(fontData + 12 + i * 4);
- }
- return offsets;
-}
-
-static void getFontTable(const uchar *fileBegin, const uchar *data, quint32 tag, const uchar **table, quint32 *length)
-{
- const quint16 numTables = qFromBigEndian<quint16>(data + 4);
- for (uint i = 0; i < numTables; ++i) {
- const quint32 offset = 12 + 16 * i;
- if (*reinterpret_cast<const quint32 *>(data + offset) == tag) {
- *table = fileBegin + qFromBigEndian<quint32>(data + offset + 8);
- *length = qFromBigEndian<quint32>(data + offset + 12);
- return;
- }
- }
- *table = 0;
- *length = 0;
- return;
-}
-
-static void getFamiliesAndSignatures(const QByteArray &fontData, QFontDatabasePrivate::ApplicationFont *appFont)
-{
- const uchar *data = reinterpret_cast<const uchar *>(fontData.constData());
-
- QList<quint32> offsets = getTrueTypeFontOffsets(data);
- if (offsets.isEmpty())
- return;
-
- for (int i = 0; i < offsets.count(); ++i) {
- const uchar *font = data + offsets.at(i);
- const uchar *table;
- quint32 length;
- getFontTable(data, font, MAKE_TAG('n', 'a', 'm', 'e'), &table, &length);
- if (!table)
- continue;
- QString name = getEnglishName(table, length);
- if (name.isEmpty())
- continue;
-
- appFont->families << name;
- FONTSIGNATURE signature;
- getFontTable(data, font, MAKE_TAG('O', 'S', '/', '2'), &table, &length);
- if (table && length >= 86) {
- // See also qfontdatabase_mac.cpp, offsets taken from OS/2 table in the TrueType spec
- signature.fsUsb[0] = qFromBigEndian<quint32>(table + 42);
- signature.fsUsb[1] = qFromBigEndian<quint32>(table + 46);
- signature.fsUsb[2] = qFromBigEndian<quint32>(table + 50);
- signature.fsUsb[3] = qFromBigEndian<quint32>(table + 54);
-
- signature.fsCsb[0] = qFromBigEndian<quint32>(table + 78);
- signature.fsCsb[1] = qFromBigEndian<quint32>(table + 82);
- } else {
- memset(&signature, 0, sizeof(signature));
- }
- appFont->signatures << signature;
- }
-}
-
-static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
-{
- if(!fnt->data.isEmpty()) {
-#ifndef Q_OS_WINCE
- PtrAddFontMemResourceEx ptrAddFontMemResourceEx = (PtrAddFontMemResourceEx)QSystemLibrary::resolve(QLatin1String("gdi32"),
- "AddFontMemResourceEx");
- if (!ptrAddFontMemResourceEx)
- return;
-#endif
- getFamiliesAndSignatures(fnt->data, fnt);
- if (fnt->families.isEmpty())
- return;
-
-#ifdef Q_OS_WINCE
- HANDLE handle = 0;
-
- {
-#ifdef QT_NO_TEMPORARYFILE
- wchar_t lpBuffer[MAX_PATH];
- GetTempPath(MAX_PATH, lpBuffer);
- QString s = QString::fromWCharArray(lpBuffer);
- QFile tempfile(s + QLatin1String("/font") + QString::number(GetTickCount()) + QLatin1String(".ttf"));
- if (!tempfile.open(QIODevice::ReadWrite))
-#else
- QTemporaryFile tempfile(QLatin1String("XXXXXXXX.ttf"));
- if (!tempfile.open())
-#endif // QT_NO_TEMPORARYFILE
- return;
- if (tempfile.write(fnt->data) == -1)
- return;
-
-#ifndef QT_NO_TEMPORARYFILE
- tempfile.setAutoRemove(false);
-#endif
- fnt->fileName = QFileInfo(tempfile.fileName()).absoluteFilePath();
- }
-
- if (AddFontResource((LPCWSTR)fnt->fileName.utf16()) == 0) {
- QFile(fnt->fileName).remove();
- return;
- }
-#else
- DWORD dummy = 0;
- HANDLE handle = ptrAddFontMemResourceEx((void *)fnt->data.constData(), fnt->data.size(), 0,
- &dummy);
- if (handle == 0)
- return;
-#endif // Q_OS_WINCE
-
- fnt->handle = handle;
- fnt->data = QByteArray();
- fnt->memoryFont = true;
- } else {
- QFile f(fnt->fileName);
- if (!f.open(QIODevice::ReadOnly))
- return;
- QByteArray data = f.readAll();
- f.close();
- getFamiliesAndSignatures(data, fnt);
-
-#ifdef Q_OS_WINCE
- QFileInfo fileinfo(fnt->fileName);
- fnt->fileName = fileinfo.absoluteFilePath();
- if (AddFontResource((LPCWSTR)fnt->fileName.utf16()) == 0)
- return;
-#else
- PtrAddFontResourceExW ptrAddFontResourceExW = (PtrAddFontResourceExW)QSystemLibrary::resolve(QLatin1String("gdi32"),
- "AddFontResourceExW");
- if (!ptrAddFontResourceExW
- || ptrAddFontResourceExW((wchar_t*)fnt->fileName.utf16(), FR_PRIVATE, 0) == 0)
- return;
-#endif // Q_OS_WINCE
-
- fnt->memoryFont = false;
- }
-}
-
-bool QFontDatabase::removeApplicationFont(int handle)
-{
- QMutexLocker locker(fontDatabaseMutex());
-
- QFontDatabasePrivate *db = privateDb();
- if (handle < 0 || handle >= db->applicationFonts.count())
- return false;
-
- const QFontDatabasePrivate::ApplicationFont font = db->applicationFonts.at(handle);
- db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont();
- if (font.memoryFont) {
-#ifdef Q_OS_WINCE
- bool removeSucceeded = RemoveFontResource((LPCWSTR)font.fileName.utf16());
- QFile tempfile(font.fileName);
- tempfile.remove();
- if (!removeSucceeded)
- return false;
-#else
- PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx = (PtrRemoveFontMemResourceEx)QSystemLibrary::resolve(QLatin1String("gdi32"),
- "RemoveFontMemResourceEx");
- if (!ptrRemoveFontMemResourceEx
- || !ptrRemoveFontMemResourceEx(font.handle))
- return false;
-#endif // Q_OS_WINCE
- } else {
-#ifdef Q_OS_WINCE
- if (!RemoveFontResource((LPCWSTR)font.fileName.utf16()))
- return false;
-#else
- PtrRemoveFontResourceExW ptrRemoveFontResourceExW = (PtrRemoveFontResourceExW)QSystemLibrary::resolve(QLatin1String("gdi32"),
- "RemoveFontResourceExW");
- if (!ptrRemoveFontResourceExW
- || !ptrRemoveFontResourceExW((LPCWSTR)font.fileName.utf16(), FR_PRIVATE, 0))
- return false;
-#endif // Q_OS_WINCE
- }
-
- db->invalidate();
- return true;
-}
-
-bool QFontDatabase::removeAllApplicationFonts()
-{
- QMutexLocker locker(fontDatabaseMutex());
-
- QFontDatabasePrivate *db = privateDb();
- for (int i = 0; i < db->applicationFonts.count(); ++i)
- if (!removeApplicationFont(i))
- return false;
- return true;
-}
-
-bool QFontDatabase::supportsThreadedFontRendering()
-{
- return true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfontdatabase_x11.cpp b/src/gui/text/qfontdatabase_x11.cpp
deleted file mode 100644
index 922a97f3aa..0000000000
--- a/src/gui/text/qfontdatabase_x11.cpp
+++ /dev/null
@@ -1,2154 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qplatformdefs.h>
-
-#include <qdebug.h>
-#include <qpaintdevice.h>
-#include <qelapsedtimer.h>
-
-#include <private/qt_x11_p.h>
-#include "qx11info_x11.h"
-#include <qdebug.h>
-#include <qfile.h>
-#include <qtemporaryfile.h>
-#include <qabstractfileengine.h>
-#include <qmath.h>
-
-#include <ctype.h>
-#include <stdlib.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-
-#include <private/qfontengine_x11_p.h>
-
-#ifndef QT_NO_FONTCONFIG
-#include <ft2build.h>
-#include FT_FREETYPE_H
-
-#if FC_VERSION >= 20402
-#include <fontconfig/fcfreetype.h>
-#endif
-#endif
-
-QT_BEGIN_NAMESPACE
-
-// from qfont_x11.cpp
-extern double qt_pointSize(double pixelSize, int dpi);
-extern double qt_pixelSize(double pointSize, int dpi);
-
-// from qapplication.cpp
-extern bool qt_is_gui_used;
-
-static inline void capitalize (char *s)
-{
- bool space = true;
- while(*s) {
- if (space)
- *s = toupper(*s);
- space = (*s == ' ');
- ++s;
- }
-}
-
-
-/*
- To regenerate the writingSystems_for_xlfd_encoding table, run
- 'util/unicode/x11/makeencodings' and paste the generated
- 'encodings.c' here.
-*/
-// ----- begin of generated code -----
-
-#define make_tag( c1, c2, c3, c4 ) \
- ((((unsigned int)c1)<<24) | (((unsigned int)c2)<<16) | \
- (((unsigned int)c3)<<8) | ((unsigned int)c4))
-
-struct XlfdEncoding {
- const char *name;
- int id;
- int mib;
- unsigned int hash1;
- unsigned int hash2;
-};
-
-static const XlfdEncoding xlfd_encoding[] = {
- { "iso8859-1", 0, 4, make_tag('i','s','o','8'), make_tag('5','9','-','1') },
- { "iso8859-2", 1, 5, make_tag('i','s','o','8'), make_tag('5','9','-','2') },
- { "iso8859-3", 2, 6, make_tag('i','s','o','8'), make_tag('5','9','-','3') },
- { "iso8859-4", 3, 7, make_tag('i','s','o','8'), make_tag('5','9','-','4') },
- { "iso8859-9", 4, 12, make_tag('i','s','o','8'), make_tag('5','9','-','9') },
- { "iso8859-10", 5, 13, make_tag('i','s','o','8'), make_tag('9','-','1','0') },
- { "iso8859-13", 6, 109, make_tag('i','s','o','8'), make_tag('9','-','1','3') },
- { "iso8859-14", 7, 110, make_tag('i','s','o','8'), make_tag('9','-','1','4') },
- { "iso8859-15", 8, 111, make_tag('i','s','o','8'), make_tag('9','-','1','5') },
- { "hp-roman8", 9, 2004, make_tag('h','p','-','r'), make_tag('m','a','n','8') },
- { "iso8859-5", 10, 8, make_tag('i','s','o','8'), make_tag('5','9','-','5') },
- { "*-cp1251", 11, 2251, 0, make_tag('1','2','5','1') },
- { "koi8-ru", 12, 2084, make_tag('k','o','i','8'), make_tag('8','-','r','u') },
- { "koi8-u", 13, 2088, make_tag('k','o','i','8'), make_tag('i','8','-','u') },
- { "koi8-r", 14, 2084, make_tag('k','o','i','8'), make_tag('i','8','-','r') },
- { "iso8859-7", 15, 10, make_tag('i','s','o','8'), make_tag('5','9','-','7') },
- { "iso8859-8", 16, 85, make_tag('i','s','o','8'), make_tag('5','9','-','8') },
- { "gb18030-0", 17, -114, make_tag('g','b','1','8'), make_tag('3','0','-','0') },
- { "gb18030.2000-0", 18, -113, make_tag('g','b','1','8'), make_tag('0','0','-','0') },
- { "gbk-0", 19, -113, make_tag('g','b','k','-'), make_tag('b','k','-','0') },
- { "gb2312.*-0", 20, 57, make_tag('g','b','2','3'), 0 },
- { "jisx0201*-0", 21, 15, make_tag('j','i','s','x'), 0 },
- { "jisx0208*-0", 22, 63, make_tag('j','i','s','x'), 0 },
- { "ksc5601*-*", 23, 36, make_tag('k','s','c','5'), 0 },
- { "big5hkscs-0", 24, -2101, make_tag('b','i','g','5'), make_tag('c','s','-','0') },
- { "hkscs-1", 25, -2101, make_tag('h','k','s','c'), make_tag('c','s','-','1') },
- { "big5*-*", 26, -2026, make_tag('b','i','g','5'), 0 },
- { "tscii-*", 27, 2028, make_tag('t','s','c','i'), 0 },
- { "tis620*-*", 28, 2259, make_tag('t','i','s','6'), 0 },
- { "iso8859-11", 29, 2259, make_tag('i','s','o','8'), make_tag('9','-','1','1') },
- { "mulelao-1", 30, -4242, make_tag('m','u','l','e'), make_tag('a','o','-','1') },
- { "ethiopic-unicode", 31, 0, make_tag('e','t','h','i'), make_tag('c','o','d','e') },
- { "iso10646-1", 32, 0, make_tag('i','s','o','1'), make_tag('4','6','-','1') },
- { "unicode-*", 33, 0, make_tag('u','n','i','c'), 0 },
- { "*-symbol", 34, 0, 0, make_tag('m','b','o','l') },
- { "*-fontspecific", 35, 0, 0, make_tag('i','f','i','c') },
- { "fontspecific-*", 36, 0, make_tag('f','o','n','t'), 0 },
- { 0, 0, 0, 0, 0 }
-};
-
-static const char writingSystems_for_xlfd_encoding[sizeof(xlfd_encoding)][QFontDatabase::WritingSystemsCount] = {
- // iso8859-1
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-2
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-3
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-4
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-9
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-10
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-13
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-14
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-15
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // hp-roman8
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-5
- { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // *-cp1251
- { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // koi8-ru
- { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // koi8-u
- { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // koi8-r
- { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-7
- { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-8
- { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // gb18030-0
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0 },
- // gb18030.2000-0
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0 },
- // gbk-0
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0 },
- // gb2312.*-0
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0 },
- // jisx0201*-0
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0 },
- // jisx0208*-0
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0 },
- // ksc5601*-*
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
- 0, 0 },
- // big5hkscs-0
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 0 },
- // hkscs-1
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 0 },
- // big5*-*
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 0 },
- // tscii-*
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // tis620*-*
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso8859-11
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // mulelao-1
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // ethiopic-unicode
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0 },
- // iso10646-1
- { 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 1, 1, 0, 1, 0, 1, 1, 0, 0, 0,
- 0, 0 },
- // unicode-*
- { 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 1, 1, 0, 1, 0, 1, 1, 0, 0, 0,
- 0, 0 },
- // *-symbol
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0 },
- // *-fontspecific
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0 },
- // fontspecific-*
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0 }
-
-};
-
-// ----- end of generated code -----
-
-
-const int numEncodings = sizeof(xlfd_encoding) / sizeof(XlfdEncoding) - 1;
-
-int qt_xlfd_encoding_id(const char *encoding)
-{
- // qDebug("looking for encoding id for '%s'", encoding);
- int len = strlen(encoding);
- if (len < 4)
- return -1;
- unsigned int hash1 = make_tag(encoding[0], encoding[1], encoding[2], encoding[3]);
- const char *ch = encoding + len - 4;
- unsigned int hash2 = make_tag(ch[0], ch[1], ch[2], ch[3]);
-
- const XlfdEncoding *enc = xlfd_encoding;
- for (; enc->name; ++enc) {
- if ((enc->hash1 && enc->hash1 != hash1) ||
- (enc->hash2 && enc->hash2 != hash2))
- continue;
- // hashes match, do a compare if strings match
- // the enc->name can contain '*'s we have to interpret correctly
- const char *n = enc->name;
- const char *e = encoding;
- while (1) {
- // qDebug("bol: *e='%c', *n='%c'", *e, *n);
- if (*e == '\0') {
- if (*n)
- break;
- // qDebug("found encoding id %d", enc->id);
- return enc->id;
- }
- if (*e == *n) {
- ++e;
- ++n;
- continue;
- }
- if (*n != '*')
- break;
- ++n;
- // qDebug("skip: *e='%c', *n='%c'", *e, *n);
- while (*e && *e != *n)
- ++e;
- }
- }
- // qDebug("couldn't find encoding %s", encoding);
- return -1;
-}
-
-int qt_mib_for_xlfd_encoding(const char *encoding)
-{
- int id = qt_xlfd_encoding_id(encoding);
- if (id != -1) return xlfd_encoding[id].mib;
- return 0;
-}
-
-int qt_encoding_id_for_mib(int mib)
-{
- const XlfdEncoding *enc = xlfd_encoding;
- for (; enc->name; ++enc) {
- if (enc->mib == mib)
- return enc->id;
- }
- return -1;
-}
-
-static const char * xlfd_for_id(int id)
-{
- // special case: -1 returns the "*-*" encoding, allowing us to do full
- // database population in a single X server round trip.
- if (id < 0 || id > numEncodings)
- return "*-*";
- return xlfd_encoding[id].name;
-}
-
-enum XLFDFieldNames {
- Foundry,
- Family,
- Weight,
- Slant,
- Width,
- AddStyle,
- PixelSize,
- PointSize,
- ResolutionX,
- ResolutionY,
- Spacing,
- AverageWidth,
- CharsetRegistry,
- CharsetEncoding,
- NFontFields
-};
-
-// Splits an X font name into fields separated by '-'
-static bool parseXFontName(char *fontName, char **tokens)
-{
- if (! fontName || fontName[0] == '0' || fontName[0] != '-') {
- tokens[0] = 0;
- return false;
- }
-
- int i;
- ++fontName;
- for (i = 0; i < NFontFields && fontName && fontName[0]; ++i) {
- tokens[i] = fontName;
- for (;; ++fontName) {
- if (*fontName == '-')
- break;
- if (! *fontName) {
- fontName = 0;
- break;
- }
- }
-
- if (fontName) *fontName++ = '\0';
- }
-
- if (i < NFontFields) {
- for (int j = i ; j < NFontFields; ++j)
- tokens[j] = 0;
- return false;
- }
-
- return true;
-}
-
-static inline bool isZero(char *x)
-{
- return (x[0] == '0' && x[1] == 0);
-}
-
-static inline bool isScalable(char **tokens)
-{
- return (isZero(tokens[PixelSize]) &&
- isZero(tokens[PointSize]) &&
- isZero(tokens[AverageWidth]));
-}
-
-static inline bool isSmoothlyScalable(char **tokens)
-{
- return (isZero(tokens[ResolutionX]) &&
- isZero(tokens[ResolutionY]));
-}
-
-static inline bool isFixedPitch(char **tokens)
-{
- return (tokens[Spacing][0] == 'm' ||
- tokens[Spacing][0] == 'c' ||
- tokens[Spacing][0] == 'M' ||
- tokens[Spacing][0] == 'C');
-}
-
-/*
- Fills in a font definition (QFontDef) from an XLFD (X Logical Font
- Description).
-
- Returns true if the given xlfd is valid.
-*/
-bool qt_fillFontDef(const QByteArray &xlfd, QFontDef *fd, int dpi, QtFontDesc *desc)
-{
- char *tokens[NFontFields];
- QByteArray buffer = xlfd;
- if (! parseXFontName(buffer.data(), tokens))
- return false;
-
- capitalize(tokens[Family]);
- capitalize(tokens[Foundry]);
-
- fd->styleStrategy |= QFont::NoAntialias;
- fd->family = QString::fromLatin1(tokens[Family]);
- QString foundry = QString::fromLatin1(tokens[Foundry]);
- if (! foundry.isEmpty() && foundry != QLatin1String("*") && (!desc || desc->family->count > 1))
- fd->family +=
- QLatin1String(" [") + foundry + QLatin1Char(']');
-
- if (qstrlen(tokens[AddStyle]) > 0)
- fd->addStyle = QString::fromLatin1(tokens[AddStyle]);
- else
- fd->addStyle.clear();
-
- fd->pointSize = atoi(tokens[PointSize])/10.;
- fd->styleHint = QFont::AnyStyle; // ### any until we match families
-
- char slant = tolower((uchar) tokens[Slant][0]);
- fd->style = (slant == 'o' ? QFont::StyleOblique : (slant == 'i' ? QFont::StyleItalic : QFont::StyleNormal));
- char fixed = tolower((uchar) tokens[Spacing][0]);
- fd->fixedPitch = (fixed == 'm' || fixed == 'c');
- fd->weight = getFontWeight(QLatin1String(tokens[Weight]));
-
- int r = atoi(tokens[ResolutionY]);
- fd->pixelSize = atoi(tokens[PixelSize]);
- // not "0" or "*", or required DPI
- if (r && fd->pixelSize && r != dpi) {
- // calculate actual pointsize for display DPI
- fd->pointSize = qt_pointSize(fd->pixelSize, dpi);
- } else if (fd->pixelSize == 0 && fd->pointSize) {
- // calculate pixel size from pointsize/dpi
- fd->pixelSize = qRound(qt_pixelSize(fd->pointSize, dpi));
- }
-
- return true;
-}
-
-/*
- Fills in a font definition (QFontDef) from the font properties in an
- XFontStruct.
-
- Returns true if the QFontDef could be filled with properties from
- the XFontStruct.
-*/
-static bool qt_fillFontDef(XFontStruct *fs, QFontDef *fd, int dpi, QtFontDesc *desc)
-{
- unsigned long value;
- if (!fs || !XGetFontProperty(fs, XA_FONT, &value))
- return false;
-
- char *n = XGetAtomName(QX11Info::display(), value);
- QByteArray xlfd(n);
- if (n)
- XFree(n);
- return qt_fillFontDef(xlfd.toLower(), fd, dpi, desc);
-}
-
-
-static QtFontStyle::Key getStyle(char ** tokens)
-{
- QtFontStyle::Key key;
-
- char slant0 = tolower((uchar) tokens[Slant][0]);
-
- if (slant0 == 'r') {
- if (tokens[Slant][1]) {
- char slant1 = tolower((uchar) tokens[Slant][1]);
-
- if (slant1 == 'o')
- key.style = QFont::StyleOblique;
- else if (slant1 == 'i')
- key.style = QFont::StyleItalic;
- }
- } else if (slant0 == 'o')
- key.style = QFont::StyleOblique;
- else if (slant0 == 'i')
- key.style = QFont::StyleItalic;
-
- key.weight = getFontWeight(QLatin1String(tokens[Weight]));
-
- if (qstrcmp(tokens[Width], "normal") == 0) {
- key.stretch = 100;
- } else if (qstrcmp(tokens[Width], "semi condensed") == 0 ||
- qstrcmp(tokens[Width], "semicondensed") == 0) {
- key.stretch = 90;
- } else if (qstrcmp(tokens[Width], "condensed") == 0) {
- key.stretch = 80;
- } else if (qstrcmp(tokens[Width], "narrow") == 0) {
- key.stretch = 60;
- }
-
- return key;
-}
-
-
-static bool xlfdsFullyLoaded = false;
-static unsigned char encodingLoaded[numEncodings];
-
-static void loadXlfds(const char *reqFamily, int encoding_id)
-{
- QFontDatabasePrivate *db = privateDb();
- QtFontFamily *fontFamily = reqFamily ? db->family(QLatin1String(reqFamily)) : 0;
-
- // make sure we don't load twice
- if ((encoding_id == -1 && xlfdsFullyLoaded)
- || (encoding_id != -1 && encodingLoaded[encoding_id]))
- return;
- if (fontFamily && fontFamily->xlfdLoaded)
- return;
-
- int fontCount;
- // force the X server to give us XLFDs
- QByteArray xlfd_pattern("-*-");
- xlfd_pattern += (reqFamily && reqFamily[0] != '\0') ? reqFamily : "*";
- xlfd_pattern += "-*-*-*-*-*-*-*-*-*-*-";
- xlfd_pattern += xlfd_for_id(encoding_id);
-
- char **fontList = XListFonts(QX11Info::display(),
- xlfd_pattern,
- 0xffff, &fontCount);
- // qDebug("requesting xlfd='%s', got %d fonts", xlfd_pattern.data(), fontCount);
-
-
- char *tokens[NFontFields];
-
- for(int i = 0 ; i < fontCount ; i++) {
- if (! parseXFontName(fontList[i], tokens))
- continue;
-
- // get the encoding_id for this xlfd. we need to do this
- // here, since we can pass -1 to this function to do full
- // database population
- *(tokens[CharsetEncoding] - 1) = '-';
- int encoding_id = qt_xlfd_encoding_id(tokens[CharsetRegistry]);
- if (encoding_id == -1)
- continue;
-
- char *familyName = tokens[Family];
- capitalize(familyName);
- char *foundryName = tokens[Foundry];
- capitalize(foundryName);
- QtFontStyle::Key styleKey = getStyle(tokens);
-
- bool smooth_scalable = false;
- bool bitmap_scalable = false;
- if (isScalable(tokens)) {
- if (isSmoothlyScalable(tokens))
- smooth_scalable = true;
- else
- bitmap_scalable = true;
- }
- uint pixelSize = atoi(tokens[PixelSize]);
- uint xpointSize = atoi(tokens[PointSize]);
- uint xres = atoi(tokens[ResolutionX]);
- uint yres = atoi(tokens[ResolutionY]);
- uint avgwidth = atoi(tokens[AverageWidth]);
- bool fixedPitch = isFixedPitch(tokens);
-
- if (avgwidth == 0 && pixelSize != 0) {
- /*
- Ignore bitmap scalable fonts that are automatically
- generated by some X servers. We know they are bitmap
- scalable because even though they have a specified pixel
- size, the average width is zero.
- */
- continue;
- }
-
- QtFontFamily *family = fontFamily ? fontFamily : db->family(QLatin1String(familyName), true);
- family->fontFileIndex = -1;
- family->symbol_checked = true;
- QtFontFoundry *foundry = family->foundry(QLatin1String(foundryName), true);
- QtFontStyle *style = foundry->style(styleKey, QString(), true);
-
- delete [] style->weightName;
- style->weightName = qstrdup(tokens[Weight]);
- delete [] style->setwidthName;
- style->setwidthName = qstrdup(tokens[Width]);
-
- if (smooth_scalable) {
- style->smoothScalable = true;
- style->bitmapScalable = false;
- pixelSize = SMOOTH_SCALABLE;
- }
- if (!style->smoothScalable && bitmap_scalable)
- style->bitmapScalable = true;
- if (!fixedPitch)
- family->fixedPitch = false;
-
- QtFontSize *size = style->pixelSize(pixelSize, true);
- QtFontEncoding *enc =
- size->encodingID(encoding_id, xpointSize, xres, yres, avgwidth, true);
- enc->pitch = *tokens[Spacing];
- if (!enc->pitch) enc->pitch = '*';
-
- for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
- if (writingSystems_for_xlfd_encoding[encoding_id][i])
- family->writingSystems[i] = QtFontFamily::Supported;
- }
- }
- if (!reqFamily) {
- // mark encoding as loaded
- if (encoding_id == -1)
- xlfdsFullyLoaded = true;
- else
- encodingLoaded[encoding_id] = true;
- }
-
- XFreeFontNames(fontList);
-}
-
-
-#ifndef QT_NO_FONTCONFIG
-
-#ifndef FC_WIDTH
-#define FC_WIDTH "width"
-#endif
-
-static int getFCWeight(int fc_weight)
-{
- int qtweight = QFont::Black;
- if (fc_weight <= (FC_WEIGHT_LIGHT + FC_WEIGHT_MEDIUM) / 2)
- qtweight = QFont::Light;
- else if (fc_weight <= (FC_WEIGHT_MEDIUM + FC_WEIGHT_DEMIBOLD) / 2)
- qtweight = QFont::Normal;
- else if (fc_weight <= (FC_WEIGHT_DEMIBOLD + FC_WEIGHT_BOLD) / 2)
- qtweight = QFont::DemiBold;
- else if (fc_weight <= (FC_WEIGHT_BOLD + FC_WEIGHT_BLACK) / 2)
- qtweight = QFont::Bold;
-
- return qtweight;
-}
-
-QFontDef qt_FcPatternToQFontDef(FcPattern *pattern, const QFontDef &request)
-{
- QFontDef fontDef;
- fontDef.styleStrategy = request.styleStrategy;
-
- fontDef.hintingPreference = request.hintingPreference;
- FcChar8 *value = 0;
- if (FcPatternGetString(pattern, FC_FAMILY, 0, &value) == FcResultMatch) {
- fontDef.family = QString::fromUtf8(reinterpret_cast<const char *>(value));
- }
-
- double dpi;
- if (FcPatternGetDouble(pattern, FC_DPI, 0, &dpi) != FcResultMatch) {
- if (X11->display)
- dpi = QX11Info::appDpiY();
- else
- dpi = qt_defaultDpiY();
- }
-
- double size;
- if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &size) == FcResultMatch)
- fontDef.pixelSize = size;
- else
- fontDef.pixelSize = 12;
-
- fontDef.pointSize = qt_pointSize(fontDef.pixelSize, qRound(dpi));
-
- /* ###
- fontDef.styleHint
- */
-
- int weight;
- if (FcPatternGetInteger(pattern, FC_WEIGHT, 0, &weight) != FcResultMatch)
- weight = FC_WEIGHT_MEDIUM;
- fontDef.weight = getFCWeight(weight);
-
- int slant;
- if (FcPatternGetInteger(pattern, FC_SLANT, 0, &slant) != FcResultMatch)
- slant = FC_SLANT_ROMAN;
- fontDef.style = (slant == FC_SLANT_ITALIC)
- ? QFont::StyleItalic
- : ((slant == FC_SLANT_OBLIQUE)
- ? QFont::StyleOblique
- : QFont::StyleNormal);
-
-
- FcBool scalable;
- if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &scalable) != FcResultMatch)
- scalable = false;
- if (scalable) {
- fontDef.stretch = request.stretch;
- fontDef.style = request.style;
- } else {
- int width;
- if (FcPatternGetInteger(pattern, FC_WIDTH, 0, &width) == FcResultMatch)
- fontDef.stretch = width;
- else
- fontDef.stretch = 100;
- }
-
- int spacing;
- if (FcPatternGetInteger(pattern, FC_SPACING, 0, &spacing) == FcResultMatch) {
- fontDef.fixedPitch = (spacing >= FC_MONO);
- fontDef.ignorePitch = false;
- } else {
- fontDef.ignorePitch = true;
- }
-
- return fontDef;
-}
-
-static const char *specialLanguages[] = {
- "en", // Common
- "el", // Greek
- "ru", // Cyrillic
- "hy", // Armenian
- "he", // Hebrew
- "ar", // Arabic
- "syr", // Syriac
- "div", // Thaana
- "hi", // Devanagari
- "bn", // Bengali
- "pa", // Gurmukhi
- "gu", // Gujarati
- "or", // Oriya
- "ta", // Tamil
- "te", // Telugu
- "kn", // Kannada
- "ml", // Malayalam
- "si", // Sinhala
- "th", // Thai
- "lo", // Lao
- "bo", // Tibetan
- "my", // Myanmar
- "ka", // Georgian
- "ko", // Hangul
- "", // Ogham
- "", // Runic
- "km", // Khmer
- "" // N'Ko
-};
-enum { SpecialLanguageCount = sizeof(specialLanguages) / sizeof(const char *) };
-
-static const ushort specialChars[] = {
- 0, // English
- 0, // Greek
- 0, // Cyrillic
- 0, // Armenian
- 0, // Hebrew
- 0, // Arabic
- 0, // Syriac
- 0, // Thaana
- 0, // Devanagari
- 0, // Bengali
- 0, // Gurmukhi
- 0, // Gujarati
- 0, // Oriya
- 0, // Tamil
- 0xc15, // Telugu
- 0xc95, // Kannada
- 0xd15, // Malayalam
- 0xd9a, // Sinhala
- 0, // Thai
- 0, // Lao
- 0, // Tibetan
- 0x1000, // Myanmar
- 0, // Georgian
- 0, // Hangul
- 0x1681, // Ogham
- 0x16a0, // Runic
- 0, // Khmer
- 0x7ca // N'Ko
-};
-enum { SpecialCharCount = sizeof(specialChars) / sizeof(ushort) };
-
-// this could become a list of all languages used for each writing
-// system, instead of using the single most common language.
-static const char *languageForWritingSystem[] = {
- 0, // Any
- "en", // Latin
- "el", // Greek
- "ru", // Cyrillic
- "hy", // Armenian
- "he", // Hebrew
- "ar", // Arabic
- "syr", // Syriac
- "div", // Thaana
- "hi", // Devanagari
- "bn", // Bengali
- "pa", // Gurmukhi
- "gu", // Gujarati
- "or", // Oriya
- "ta", // Tamil
- "te", // Telugu
- "kn", // Kannada
- "ml", // Malayalam
- "si", // Sinhala
- "th", // Thai
- "lo", // Lao
- "bo", // Tibetan
- "my", // Myanmar
- "ka", // Georgian
- "km", // Khmer
- "zh-cn", // SimplifiedChinese
- "zh-tw", // TraditionalChinese
- "ja", // Japanese
- "ko", // Korean
- "vi", // Vietnamese
- 0, // Symbol
- 0, // Ogham
- 0, // Runic
- 0 // N'Ko
-};
-enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) };
-
-// Unfortunately FontConfig doesn't know about some languages. We have to test these through the
-// charset. The lists below contain the systems where we need to do this.
-static const ushort sampleCharForWritingSystem[] = {
- 0, // Any
- 0, // Latin
- 0, // Greek
- 0, // Cyrillic
- 0, // Armenian
- 0, // Hebrew
- 0, // Arabic
- 0, // Syriac
- 0, // Thaana
- 0, // Devanagari
- 0, // Bengali
- 0, // Gurmukhi
- 0, // Gujarati
- 0, // Oriya
- 0, // Tamil
- 0xc15, // Telugu
- 0xc95, // Kannada
- 0xd15, // Malayalam
- 0xd9a, // Sinhala
- 0, // Thai
- 0, // Lao
- 0, // Tibetan
- 0x1000, // Myanmar
- 0, // Georgian
- 0, // Khmer
- 0, // SimplifiedChinese
- 0, // TraditionalChinese
- 0, // Japanese
- 0, // Korean
- 0, // Vietnamese
- 0, // Symbol
- 0x1681, // Ogham
- 0x16a0, // Runic
- 0x7ca // N'Ko
-};
-enum { SampleCharCount = sizeof(sampleCharForWritingSystem) / sizeof(ushort) };
-
-// Newer FontConfig let's us sort out fonts that contain certain glyphs, but no
-// open type tables for is directly. Do this so we don't pick some strange
-// pseudo unicode font
-static const char *openType[] = {
- 0, // Any
- 0, // Latin
- 0, // Greek
- 0, // Cyrillic
- 0, // Armenian
- 0, // Hebrew
- 0, // Arabic
- "syrc", // Syriac
- "thaa", // Thaana
- "deva", // Devanagari
- "beng", // Bengali
- "guru", // Gurmukhi
- "gurj", // Gujarati
- "orya", // Oriya
- "taml", // Tamil
- "telu", // Telugu
- "knda", // Kannada
- "mlym", // Malayalam
- "sinh", // Sinhala
- 0, // Thai
- 0, // Lao
- "tibt", // Tibetan
- "mymr", // Myanmar
- 0, // Georgian
- "khmr", // Khmer
- 0, // SimplifiedChinese
- 0, // TraditionalChinese
- 0, // Japanese
- 0, // Korean
- 0, // Vietnamese
- 0, // Symbol
- 0, // Ogham
- 0, // Runic
- "nko " // N'Ko
-};
-enum { OpenTypeCount = sizeof(openType) / sizeof(const char *) };
-
-
-static void loadFontConfig()
-{
- Q_ASSERT_X(X11, "QFontDatabase",
- "A QApplication object needs to be constructed before FontConfig is used.");
- if (!X11->has_fontconfig)
- return;
-
- Q_ASSERT_X(int(QUnicodeTables::ScriptCount) == SpecialLanguageCount,
- "QFontDatabase", "New scripts have been added.");
- Q_ASSERT_X(int(QUnicodeTables::ScriptCount) == SpecialCharCount,
- "QFontDatabase", "New scripts have been added.");
- Q_ASSERT_X(int(QFontDatabase::WritingSystemsCount) == LanguageCount,
- "QFontDatabase", "New writing systems have been added.");
- Q_ASSERT_X(int(QFontDatabase::WritingSystemsCount) == SampleCharCount,
- "QFontDatabase", "New writing systems have been added.");
- Q_ASSERT_X(int(QFontDatabase::WritingSystemsCount) == OpenTypeCount,
- "QFontDatabase", "New writing systems have been added.");
-
- QFontDatabasePrivate *db = privateDb();
- FcFontSet *fonts;
-
- FcPattern *pattern = FcPatternCreate();
- FcDefaultSubstitute(pattern);
- FcChar8 *lang = 0;
- if (FcPatternGetString(pattern, FC_LANG, 0, &lang) == FcResultMatch)
- db->systemLang = QString::fromUtf8((const char *) lang);
- FcPatternDestroy(pattern);
-
- QString familyName;
- FcChar8 *value = 0;
- int weight_value;
- int slant_value;
- int spacing_value;
- FcChar8 *file_value;
- int index_value;
- FcChar8 *foundry_value;
- FcChar8 *style_value;
- FcBool scalable;
-
- {
- FcObjectSet *os = FcObjectSetCreate();
- FcPattern *pattern = FcPatternCreate();
- const char *properties [] = {
- FC_FAMILY, FC_STYLE, FC_WEIGHT, FC_SLANT,
- FC_SPACING, FC_FILE, FC_INDEX,
- FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE, FC_WEIGHT,
- FC_WIDTH,
-#if FC_VERSION >= 20297
- FC_CAPABILITY,
-#endif
- (const char *)0
- };
- const char **p = properties;
- while (*p) {
- FcObjectSetAdd(os, *p);
- ++p;
- }
- fonts = FcFontList(0, pattern, os);
- FcObjectSetDestroy(os);
- FcPatternDestroy(pattern);
- }
-
- for (int i = 0; i < fonts->nfont; i++) {
- if (FcPatternGetString(fonts->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
- continue;
- // capitalize(value);
- familyName = QString::fromUtf8((const char *)value);
- slant_value = FC_SLANT_ROMAN;
- weight_value = FC_WEIGHT_MEDIUM;
- spacing_value = FC_PROPORTIONAL;
- file_value = 0;
- index_value = 0;
- scalable = FcTrue;
-
- if (FcPatternGetInteger (fonts->fonts[i], FC_SLANT, 0, &slant_value) != FcResultMatch)
- slant_value = FC_SLANT_ROMAN;
- if (FcPatternGetInteger (fonts->fonts[i], FC_WEIGHT, 0, &weight_value) != FcResultMatch)
- weight_value = FC_WEIGHT_MEDIUM;
- if (FcPatternGetInteger (fonts->fonts[i], FC_SPACING, 0, &spacing_value) != FcResultMatch)
- spacing_value = FC_PROPORTIONAL;
- if (FcPatternGetString (fonts->fonts[i], FC_FILE, 0, &file_value) != FcResultMatch)
- file_value = 0;
- if (FcPatternGetInteger (fonts->fonts[i], FC_INDEX, 0, &index_value) != FcResultMatch)
- index_value = 0;
- if (FcPatternGetBool(fonts->fonts[i], FC_SCALABLE, 0, &scalable) != FcResultMatch)
- scalable = FcTrue;
- if (FcPatternGetString(fonts->fonts[i], FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
- foundry_value = 0;
- if (FcPatternGetString(fonts->fonts[i], FC_STYLE, 0, &style_value) != FcResultMatch)
- style_value = 0;
- QtFontFamily *family = db->family(familyName, true);
-
- FcLangSet *langset = 0;
- FcResult res = FcPatternGetLangSet(fonts->fonts[i], FC_LANG, 0, &langset);
- if (res == FcResultMatch) {
- for (int i = 1; i < LanguageCount; ++i) {
- const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[i];
- if (!lang) {
- family->writingSystems[i] |= QtFontFamily::UnsupportedFT;
- } else {
- FcLangResult langRes = FcLangSetHasLang(langset, lang);
- if (langRes != FcLangDifferentLang)
- family->writingSystems[i] = QtFontFamily::Supported;
- else
- family->writingSystems[i] |= QtFontFamily::UnsupportedFT;
- }
- }
- family->writingSystems[QFontDatabase::Other] = QtFontFamily::UnsupportedFT;
- family->ftWritingSystemCheck = true;
- } else {
- // we set Other to supported for symbol fonts. It makes no
- // sense to merge these with other ones, as they are
- // special in a way.
- for (int i = 1; i < LanguageCount; ++i)
- family->writingSystems[i] |= QtFontFamily::UnsupportedFT;
- family->writingSystems[QFontDatabase::Other] = QtFontFamily::Supported;
- }
-
- FcCharSet *cs = 0;
- res = FcPatternGetCharSet(fonts->fonts[i], FC_CHARSET, 0, &cs);
- if (res == FcResultMatch) {
- // some languages are not supported by FontConfig, we rather check the
- // charset to detect these
- for (int i = 1; i < SampleCharCount; ++i) {
- if (!sampleCharForWritingSystem[i])
- continue;
- if (FcCharSetHasChar(cs, sampleCharForWritingSystem[i]))
- family->writingSystems[i] = QtFontFamily::Supported;
- }
- }
-
-#if FC_VERSION >= 20297
- for (int j = 1; j < LanguageCount; ++j) {
- if (family->writingSystems[j] == QtFontFamily::Supported && requiresOpenType(j) && openType[j]) {
- FcChar8 *cap;
- res = FcPatternGetString (fonts->fonts[i], FC_CAPABILITY, 0, &cap);
- if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
- family->writingSystems[j] = QtFontFamily::UnsupportedFT;
- }
- }
-#endif
-
- QByteArray file((const char *)file_value);
- family->fontFilename = file;
- family->fontFileIndex = index_value;
-
- QtFontStyle::Key styleKey;
- QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString();
- styleKey.style = (slant_value == FC_SLANT_ITALIC)
- ? QFont::StyleItalic
- : ((slant_value == FC_SLANT_OBLIQUE)
- ? QFont::StyleOblique
- : QFont::StyleNormal);
- styleKey.weight = getFCWeight(weight_value);
- if (!scalable) {
- int width = 100;
- FcPatternGetInteger (fonts->fonts[i], FC_WIDTH, 0, &width);
- styleKey.stretch = width;
- }
-
- QtFontFoundry *foundry
- = family->foundry(foundry_value ? QString::fromUtf8((const char *)foundry_value) : QString(), true);
- QtFontStyle *style = foundry->style(styleKey, styleName, true);
-
- if (spacing_value < FC_MONO)
- family->fixedPitch = false;
-
- QtFontSize *size;
- if (scalable) {
- style->smoothScalable = true;
- size = style->pixelSize(SMOOTH_SCALABLE, true);
- } else {
- double pixel_size = 0;
- FcPatternGetDouble (fonts->fonts[i], FC_PIXEL_SIZE, 0, &pixel_size);
- size = style->pixelSize((int)pixel_size, true);
- }
- QtFontEncoding *enc = size->encodingID(-1, 0, 0, 0, 0, true);
- enc->pitch = (spacing_value >= FC_CHARCELL ? 'c' :
- (spacing_value >= FC_MONO ? 'm' : 'p'));
- }
-
- FcFontSetDestroy (fonts);
-
- struct FcDefaultFont {
- const char *qtname;
- const char *rawname;
- bool fixed;
- };
- const FcDefaultFont defaults[] = {
- { "Serif", "serif", false },
- { "Sans Serif", "sans-serif", false },
- { "Monospace", "monospace", true },
- { 0, 0, false }
- };
- const FcDefaultFont *f = defaults;
- while (f->qtname) {
- QtFontFamily *family = db->family(QLatin1String(f->qtname), true);
- family->fixedPitch = f->fixed;
- family->synthetic = true;
- QtFontFoundry *foundry = family->foundry(QString(), true);
-
- // aliases only make sense for 'common', not for any of the specials
- for (int i = 1; i < LanguageCount; ++i) {
- if (requiresOpenType(i))
- family->writingSystems[i] = QtFontFamily::UnsupportedFT;
- else
- family->writingSystems[i] = QtFontFamily::Supported;
- }
- family->writingSystems[QFontDatabase::Other] = QtFontFamily::UnsupportedFT;
-
- QtFontStyle::Key styleKey;
- for (int i = 0; i < 4; ++i) {
- styleKey.style = (i%2) ? QFont::StyleNormal : QFont::StyleItalic;
- styleKey.weight = (i > 1) ? QFont::Bold : QFont::Normal;
- QtFontStyle *style = foundry->style(styleKey, QString(), true);
- style->smoothScalable = true;
- QtFontSize *size = style->pixelSize(SMOOTH_SCALABLE, true);
- QtFontEncoding *enc = size->encodingID(-1, 0, 0, 0, 0, true);
- enc->pitch = (f->fixed ? 'm' : 'p');
- }
- ++f;
- }
-}
-#endif // QT_NO_FONTCONFIG
-
-static void initializeDb();
-
-static void load(const QString &family = QString(), int script = -1, bool forceXLFD = false)
-{
- if (X11->has_fontconfig && !forceXLFD) {
- initializeDb();
- return;
- }
-
-#ifdef QFONTDATABASE_DEBUG
- QElapsedTimer t;
- t.start();
-#endif
-
- if (family.isNull() && script == -1) {
- loadXlfds(0, -1);
- } else {
- if (family.isNull()) {
- // load all families in all writing systems that match \a script
- for (int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws) {
- if (scriptForWritingSystem[ws] != script)
- continue;
- for (int i = 0; i < numEncodings; ++i) {
- if (writingSystems_for_xlfd_encoding[i][ws])
- loadXlfds(0, i);
- }
- }
- } else {
- QtFontFamily *f = privateDb()->family(family);
- // could reduce this further with some more magic:
- // would need to remember the encodings loaded for the family.
- if (!f || !f->xlfdLoaded)
- loadXlfds(family.toLatin1(), -1);
- }
- }
-
-#ifdef QFONTDATABASE_DEBUG
- FD_DEBUG("QFontDatabase: load(%s, %d) took %d ms",
- family.toLatin1().constData(), script, t.elapsed());
-#endif
-}
-
-static void checkSymbolFont(QtFontFamily *family)
-{
- if (!family || family->symbol_checked || family->fontFilename.isEmpty())
- return;
-// qDebug() << "checking " << family->rawName;
- family->symbol_checked = true;
-
- QFontEngine::FaceId id;
- id.filename = family->fontFilename;
- id.index = family->fontFileIndex;
- QFreetypeFace *f = QFreetypeFace::getFace(id);
- if (!f) {
- qWarning("checkSymbolFonts: Couldn't open face %s (%s/%d)",
- qPrintable(family->name), family->fontFilename.data(), family->fontFileIndex);
- return;
- }
- for (int i = 0; i < f->face->num_charmaps; ++i) {
- FT_CharMap cm = f->face->charmaps[i];
- if (cm->encoding == FT_ENCODING_ADOBE_CUSTOM
- || cm->encoding == FT_ENCODING_MS_SYMBOL) {
- for (int x = QFontDatabase::Latin; x < QFontDatabase::Other; ++x)
- family->writingSystems[x] = QtFontFamily::Unsupported;
- family->writingSystems[QFontDatabase::Other] = QtFontFamily::Supported;
- break;
- }
- }
- f->release(id);
-}
-
-static void checkSymbolFonts(const QString &family = QString())
-{
-#ifndef QT_NO_FONTCONFIG
- QFontDatabasePrivate *d = privateDb();
-
- if (family.isEmpty()) {
- for (int i = 0; i < d->count; ++i)
- checkSymbolFont(d->families[i]);
- } else {
- checkSymbolFont(d->family(family));
- }
-#endif
-}
-
-static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt);
-
-static void initializeDb()
-{
- QFontDatabasePrivate *db = privateDb();
- if (!db || db->count)
- return;
-
- QElapsedTimer t;
- t.start();
-
-#ifndef QT_NO_FONTCONFIG
- if (db->reregisterAppFonts) {
- db->reregisterAppFonts = false;
- for (int i = 0; i < db->applicationFonts.count(); ++i)
- if (!db->applicationFonts.at(i).families.isEmpty()) {
- registerFont(&db->applicationFonts[i]);
- }
- }
-
- loadFontConfig();
- FD_DEBUG("QFontDatabase: loaded FontConfig: %d ms", int(t.elapsed()));
-#endif
-
- t.start();
-
-#ifndef QT_NO_FONTCONFIG
- for (int i = 0; i < db->count; i++) {
- for (int j = 0; j < db->families[i]->count; ++j) { // each foundry
- QtFontFoundry *foundry = db->families[i]->foundries[j];
- for (int k = 0; k < foundry->count; ++k) {
- QtFontStyle *style = foundry->styles[k];
- if (style->key.style != QFont::StyleNormal) continue;
-
- QtFontSize *size = style->pixelSize(SMOOTH_SCALABLE);
- if (! size) continue; // should not happen
- QtFontEncoding *enc = size->encodingID(-1, 0, 0, 0, 0, true);
- if (! enc) continue; // should not happen either
-
- QtFontStyle::Key key = style->key;
-
- // does this style have an italic equivalent?
- key.style = QFont::StyleItalic;
- QtFontStyle *equiv = foundry->style(key);
- if (equiv) continue;
-
- // does this style have an oblique equivalent?
- key.style = QFont::StyleOblique;
- equiv = foundry->style(key);
- if (equiv) continue;
-
- // let's fake one...
- equiv = foundry->style(key, QString(), true);
- equiv->smoothScalable = true;
-
- QtFontSize *equiv_size = equiv->pixelSize(SMOOTH_SCALABLE, true);
- QtFontEncoding *equiv_enc = equiv_size->encodingID(-1, 0, 0, 0, 0, true);
-
- // keep the same pitch
- equiv_enc->pitch = enc->pitch;
- }
- }
- }
-#endif
-
-
-#ifdef QFONTDATABASE_DEBUG
-#ifndef QT_NO_FONTCONFIG
- if (!X11->has_fontconfig)
-#endif
- // load everything at startup in debug mode.
- loadXlfds(0, -1);
-
- // print the database
- for (int f = 0; f < db->count; f++) {
- QtFontFamily *family = db->families[f];
- FD_DEBUG("'%s' %s fixed=%s", family->name.latin1(), (family->fixedPitch ? "fixed" : ""),
- (family->fixedPitch ? "yes" : "no"));
- for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
- QFontDatabase::WritingSystem ws = QFontDatabase::WritingSystem(i);
- FD_DEBUG("\t%s: %s", QFontDatabase::writingSystemName(ws).toLatin1().constData(),
- ((family->writingSystems[i] & QtFontFamily::Supported) ? "Supported" :
- (family->writingSystems[i] & QtFontFamily::Unsupported) == QtFontFamily::Unsupported ?
- "Unsupported" : "Unknown"));
- }
-
- for (int fd = 0; fd < family->count; fd++) {
- QtFontFoundry *foundry = family->foundries[fd];
- FD_DEBUG("\t\t'%s'", foundry->name.latin1());
- for (int s = 0; s < foundry->count; s++) {
- QtFontStyle *style = foundry->styles[s];
- FD_DEBUG("\t\t\tstyle: style=%d weight=%d (%s)\n"
- "\t\t\tstretch=%d (%s)",
- style->key.style, style->key.weight,
- style->weightName, style->key.stretch,
- style->setwidthName ? style->setwidthName : "nil");
- if (style->smoothScalable)
- FD_DEBUG("\t\t\t\tsmooth scalable");
- else if (style->bitmapScalable)
- FD_DEBUG("\t\t\t\tbitmap scalable");
- if (style->pixelSizes) {
- qDebug("\t\t\t\t%d pixel sizes", style->count);
- for (int z = 0; z < style->count; ++z) {
- QtFontSize *size = style->pixelSizes + z;
- for (int e = 0; e < size->count; ++e) {
- FD_DEBUG("\t\t\t\t size %5d pitch %c encoding %s",
- size->pixelSize,
- size->encodings[e].pitch,
- xlfd_for_id(size->encodings[e].encoding));
- }
- }
- }
- }
- }
- }
-#endif // QFONTDATABASE_DEBUG
-}
-
-
-// --------------------------------------------------------------------------------------
-// font loader
-// --------------------------------------------------------------------------------------
-
-static const char *styleHint(const QFontDef &request)
-{
- const char *stylehint = 0;
- switch (request.styleHint) {
- case QFont::SansSerif:
- stylehint = "sans-serif";
- break;
- case QFont::Serif:
- stylehint = "serif";
- break;
- case QFont::TypeWriter:
- stylehint = "monospace";
- break;
- default:
- if (request.fixedPitch)
- stylehint = "monospace";
- break;
- }
- return stylehint;
-}
-
-#ifndef QT_NO_FONTCONFIG
-
-void qt_addPatternProps(FcPattern *pattern, int screen, int script, const QFontDef &request)
-{
- double size_value = qMax(qreal(1.), request.pixelSize);
- FcPatternDel(pattern, FC_PIXEL_SIZE);
- FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size_value);
-
- if (X11->display && QX11Info::appDepth(screen) <= 8) {
- FcPatternDel(pattern, FC_ANTIALIAS);
- // can't do antialiasing on 8bpp
- FcPatternAddBool(pattern, FC_ANTIALIAS, false);
- } else if (request.styleStrategy & (QFont::PreferAntialias|QFont::NoAntialias)) {
- FcPatternDel(pattern, FC_ANTIALIAS);
- FcPatternAddBool(pattern, FC_ANTIALIAS,
- !(request.styleStrategy & QFont::NoAntialias));
- }
-
- if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') {
- Q_ASSERT(script < QUnicodeTables::ScriptCount);
- FcLangSet *ls = FcLangSetCreate();
- FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
- FcPatternDel(pattern, FC_LANG);
- FcPatternAddLangSet(pattern, FC_LANG, ls);
- FcLangSetDestroy(ls);
- }
-
- if (!request.styleName.isEmpty()) {
- QByteArray cs = request.styleName.toUtf8();
- FcPatternAddString(pattern, FC_STYLE, (const FcChar8 *) cs.constData());
- return;
- }
-
- int weight_value = FC_WEIGHT_BLACK;
- if (request.weight == 0)
- weight_value = FC_WEIGHT_MEDIUM;
- else if (request.weight < (QFont::Light + QFont::Normal) / 2)
- weight_value = FC_WEIGHT_LIGHT;
- else if (request.weight < (QFont::Normal + QFont::DemiBold) / 2)
- weight_value = FC_WEIGHT_MEDIUM;
- else if (request.weight < (QFont::DemiBold + QFont::Bold) / 2)
- weight_value = FC_WEIGHT_DEMIBOLD;
- else if (request.weight < (QFont::Bold + QFont::Black) / 2)
- weight_value = FC_WEIGHT_BOLD;
- FcPatternDel(pattern, FC_WEIGHT);
- FcPatternAddInteger(pattern, FC_WEIGHT, weight_value);
-
- int slant_value = FC_SLANT_ROMAN;
- if (request.style == QFont::StyleItalic)
- slant_value = FC_SLANT_ITALIC;
- else if (request.style == QFont::StyleOblique)
- slant_value = FC_SLANT_OBLIQUE;
- FcPatternDel(pattern, FC_SLANT);
- FcPatternAddInteger(pattern, FC_SLANT, slant_value);
-
- int stretch = request.stretch;
- if (!stretch)
- stretch = 100;
- FcPatternDel(pattern, FC_WIDTH);
- FcPatternAddInteger(pattern, FC_WIDTH, stretch);
-}
-
-static bool preferScalable(const QFontDef &request)
-{
- return request.styleStrategy & (QFont::PreferOutline|QFont::ForceOutline|QFont::PreferQuality|QFont::PreferAntialias);
-}
-
-
-static FcPattern *getFcPattern(const QFontPrivate *fp, int script, const QFontDef &request)
-{
- if (!X11->has_fontconfig)
- return 0;
-
- FcPattern *pattern = FcPatternCreate();
- if (!pattern)
- return 0;
-
- FcValue value;
- value.type = FcTypeString;
-
- QtFontDesc desc;
- QStringList families_and_foundries = familyList(request);
- for (int i = 0; i < families_and_foundries.size(); ++i) {
- QString family, foundry;
- parseFontName(families_and_foundries.at(i), foundry, family);
- if (!family.isEmpty()) {
- QByteArray cs = family.toUtf8();
- value.u.s = (const FcChar8 *)cs.data();
- FcPatternAdd(pattern, FC_FAMILY, value, FcTrue);
- }
- if (i == 0) {
- QT_PREPEND_NAMESPACE(match)(script, request, family, foundry, -1, &desc);
- if (!foundry.isEmpty()) {
- QByteArray cs = foundry.toUtf8();
- value.u.s = (const FcChar8 *)cs.data();
- FcPatternAddWeak(pattern, FC_FOUNDRY, value, FcTrue);
- }
- }
- }
-
- const char *stylehint = styleHint(request);
- if (stylehint) {
- value.u.s = (const FcChar8 *)stylehint;
- FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
- }
-
- if (!request.ignorePitch) {
- char pitch_value = FC_PROPORTIONAL;
- if (request.fixedPitch || (desc.family && desc.family->fixedPitch))
- pitch_value = FC_MONO;
- FcPatternAddInteger(pattern, FC_SPACING, pitch_value);
- }
- FcPatternAddBool(pattern, FC_OUTLINE, !(request.styleStrategy & QFont::PreferBitmap));
- if (preferScalable(request) || (desc.style && desc.style->smoothScalable))
- FcPatternAddBool(pattern, FC_SCALABLE, true);
-
- qt_addPatternProps(pattern, fp->screen, script, request);
-
- FcConfigSubstitute(0, pattern, FcMatchPattern);
- FcDefaultSubstitute(pattern);
-
- // these should only get added to the pattern _after_ substitution
- // append the default fallback font for the specified script
- extern QString qt_fallback_font_family(int);
- QString fallback = qt_fallback_font_family(script);
- if (!fallback.isEmpty()) {
- QByteArray cs = fallback.toUtf8();
- value.u.s = (const FcChar8 *)cs.data();
- FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
- }
-
- // add the default family
- QString defaultFamily = QApplication::font().family();
- QByteArray cs = defaultFamily.toUtf8();
- value.u.s = (const FcChar8 *)cs.data();
- FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
-
- // add QFont::defaultFamily() to the list, for compatibility with
- // previous versions
- defaultFamily = QApplication::font().defaultFamily();
- cs = defaultFamily.toUtf8();
- value.u.s = (const FcChar8 *)cs.data();
- FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
-
- return pattern;
-}
-
-
-static void FcFontSetRemove(FcFontSet *fs, int at)
-{
- Q_ASSERT(at < fs->nfont);
- FcPatternDestroy(fs->fonts[at]);
- int len = (--fs->nfont - at) * sizeof(FcPattern *);;
- if (len > 0)
- memmove(fs->fonts + at, fs->fonts + at + 1, len);
-}
-
-static QFontEngine *tryPatternLoad(FcPattern *match, int screen,
- const QFontDef &request, int script)
-{
-#ifdef FONT_MATCH_DEBUG
- FcChar8 *fam;
- FcPatternGetString(match, FC_FAMILY, 0, &fam);
- FM_DEBUG("==== trying %s\n", fam);
-#endif
- FM_DEBUG("passes charset test\n");
-
- QFontEngineX11FT *engine = 0;
- if (!match) // probably no fonts available.
- goto done;
-
- if (script != QUnicodeTables::Common) {
- // skip font if it doesn't support the language we want
- if (specialChars[script]) {
- // need to check the charset, as the langset doesn't work for these scripts
- FcCharSet *cs;
- if (FcPatternGetCharSet(match, FC_CHARSET, 0, &cs) != FcResultMatch)
- goto done;
- if (!FcCharSetHasChar(cs, specialChars[script]))
- goto done;
- } else if (*specialLanguages[script] != '\0'){
- FcLangSet *langSet = 0;
- if (FcPatternGetLangSet(match, FC_LANG, 0, &langSet) != FcResultMatch)
- goto done;
- if (FcLangSetHasLang(langSet, (const FcChar8*)specialLanguages[script]) != FcLangEqual)
- goto done;
- }
- }
-
- // enforce non-antialiasing if requested. the ft font engine looks at this property.
- if (request.styleStrategy & QFont::NoAntialias) {
- FcPatternDel(match, FC_ANTIALIAS);
- FcPatternAddBool(match, FC_ANTIALIAS, false);
- }
-
- engine = new QFontEngineX11FT(match, qt_FcPatternToQFontDef(match, request), screen);
- if (engine->invalid()) {
- FM_DEBUG(" --> invalid!\n");
- delete engine;
- engine = 0;
- } else if (scriptRequiresOpenType(script)) {
- HB_Face hbFace = engine->harfbuzzFace();
- if (!hbFace || !hbFace->supported_scripts[script]) {
- FM_DEBUG(" OpenType support missing for script\n");
- delete engine;
- engine = 0;
- }
- }
-done:
- return engine;
-}
-
-FcFontSet *qt_fontSetForPattern(FcPattern *pattern, const QFontDef &request)
-{
- FcResult result;
- FcFontSet *fs = FcFontSort(0, pattern, FcTrue, 0, &result);
-#ifdef FONT_MATCH_DEBUG
- FM_DEBUG("first font in fontset:\n");
- FcPatternPrint(fs->fonts[0]);
-#endif
-
- FcBool forceScalable = request.styleStrategy & QFont::ForceOutline;
-
- // remove fonts if they are not scalable (and should be)
- if (forceScalable && fs) {
- for (int i = 0; i < fs->nfont; ++i) {
- FcPattern *font = fs->fonts[i];
- FcResult res;
- FcBool scalable;
- res = FcPatternGetBool(font, FC_SCALABLE, 0, &scalable);
- if (res != FcResultMatch || !scalable) {
- FcFontSetRemove(fs, i);
-#ifdef FONT_MATCH_DEBUG
- FM_DEBUG("removing pattern:");
- FcPatternPrint(font);
-#endif
- --i; // go back one
- }
- }
- }
-
- FM_DEBUG("final pattern contains %d fonts\n", fs->nfont);
-
- return fs;
-}
-
-static QFontEngine *loadFc(const QFontPrivate *fp, int script, const QFontDef &request)
-{
- FM_DEBUG("===================== loadFc: script=%d family='%s'\n", script, request.family.toLatin1().data());
- FcPattern *pattern = getFcPattern(fp, script, request);
-
-#ifdef FONT_MATCH_DEBUG
- FM_DEBUG("\n\nfinal FcPattern contains:\n");
- FcPatternPrint(pattern);
-#endif
-
- QFontEngine *fe = 0;
- FcResult res;
- FcPattern *match = FcFontMatch(0, pattern, &res);
- fe = tryPatternLoad(match, fp->screen, request, script);
- if (!fe) {
- FcFontSet *fs = qt_fontSetForPattern(pattern, request);
-
- if (match) {
- FcPatternDestroy(match);
- match = 0;
- }
-
- if (fs) {
- for (int i = 0; !fe && i < fs->nfont; ++i) {
- match = FcFontRenderPrepare(NULL, pattern, fs->fonts[i]);
- fe = tryPatternLoad(match, fp->screen, request, script);
- if (fe)
- break;
- FcPatternDestroy(match);
- match = 0;
- }
- FcFontSetDestroy(fs);
- }
- FM_DEBUG("engine for script %d is %s\n", script, fe ? fe->fontDef.family.toLatin1().data(): "(null)");
- }
- if (fe
- && script == QUnicodeTables::Common
- && !(request.styleStrategy & QFont::NoFontMerging) && !fe->symbol) {
- fe = new QFontEngineMultiFT(fe, match, pattern, fp->screen, request);
- } else {
- FcPatternDestroy(pattern);
- if (match)
- FcPatternDestroy(match);
- }
- return fe;
-}
-
-static FcPattern *queryFont(const FcChar8 *file, const QByteArray &data, int id, FcBlanks *blanks, int *count)
-{
-#if FC_VERSION < 20402
- Q_UNUSED(data)
- return FcFreeTypeQuery(file, id, blanks, count);
-#else
- if (data.isEmpty())
- return FcFreeTypeQuery(file, id, blanks, count);
-
- extern FT_Library qt_getFreetype();
- FT_Library lib = qt_getFreetype();
-
- FcPattern *pattern = 0;
-
- FT_Face face;
- if (!FT_New_Memory_Face(lib, (const FT_Byte *)data.constData(), data.size(), id, &face)) {
- *count = face->num_faces;
-
- pattern = FcFreeTypeQueryFace(face, file, id, blanks);
-
- FT_Done_Face(face);
- }
-
- return pattern;
-#endif
-}
-#endif // QT_NO_FONTCONFIG
-
-static QFontEngine *loadRaw(const QFontPrivate *fp, const QFontDef &request)
-{
- Q_ASSERT(fp && fp->rawMode);
-
- QByteArray xlfd = request.family.toLatin1();
- FM_DEBUG("Loading XLFD (rawmode) '%s'", xlfd.data());
-
- QFontEngine *fe;
- XFontStruct *xfs;
- if (!(xfs = XLoadQueryFont(QX11Info::display(), xlfd.data())))
- if (!(xfs = XLoadQueryFont(QX11Info::display(), "fixed")))
- return 0;
-
- fe = new QFontEngineXLFD(xfs, xlfd, 0);
- if (! qt_fillFontDef(xfs, &fe->fontDef, fp->dpi, 0) &&
- ! qt_fillFontDef(xlfd, &fe->fontDef, fp->dpi, 0))
- fe->fontDef = QFontDef();
- return fe;
-}
-
-QFontEngine *QFontDatabase::loadXlfd(int screen, int script, const QFontDef &request, int force_encoding_id)
-{
- QMutexLocker locker(fontDatabaseMutex());
-
- QtFontDesc desc;
- FM_DEBUG() << "---> loadXlfd: request is" << request.family;
- QStringList families_and_foundries = familyList(request);
- const char *stylehint = styleHint(request);
- if (stylehint)
- families_and_foundries << QString::fromLatin1(stylehint);
- families_and_foundries << QString();
- FM_DEBUG() << "loadXlfd: list is" << families_and_foundries;
- for (int i = 0; i < families_and_foundries.size(); ++i) {
- QString family, foundry;
- QT_PREPEND_NAMESPACE(parseFontName)(families_and_foundries.at(i), foundry, family);
- FM_DEBUG("loadXlfd: >>>>>>>>>>>>>>trying to match '%s' encoding=%d", family.toLatin1().data(), force_encoding_id);
- QT_PREPEND_NAMESPACE(match)(script, request, family, foundry, force_encoding_id, &desc, QList<int>(), true);
- if (desc.family)
- break;
- }
-
- QFontEngine *fe = 0;
- if (force_encoding_id != -1
- || (request.styleStrategy & QFont::NoFontMerging)
- || (desc.family && desc.family->writingSystems[QFontDatabase::Symbol] & QtFontFamily::Supported)) {
- if (desc.family) {
- int px = desc.size->pixelSize;
- if (desc.style->smoothScalable && px == SMOOTH_SCALABLE)
- px = request.pixelSize;
- else if (desc.style->bitmapScalable && px == 0)
- px = request.pixelSize;
-
- QByteArray xlfd("-");
- xlfd += desc.foundry->name.isEmpty() ? QByteArray("*") : desc.foundry->name.toLatin1();
- xlfd += '-';
- xlfd += desc.family->name.isEmpty() ? QByteArray("*") : desc.family->name.toLatin1();
- xlfd += '-';
- xlfd += desc.style->weightName ? desc.style->weightName : "*";
- xlfd += '-';
- xlfd += (desc.style->key.style == QFont::StyleItalic
- ? 'i'
- : (desc.style->key.style == QFont::StyleOblique ? 'o' : 'r'));
- xlfd += '-';
- xlfd += desc.style->setwidthName ? desc.style->setwidthName : "*";
- // ### handle add-style
- xlfd += "-*-";
- xlfd += QByteArray::number(px);
- xlfd += '-';
- xlfd += QByteArray::number(desc.encoding->xpoint);
- xlfd += '-';
- xlfd += QByteArray::number(desc.encoding->xres);
- xlfd += '-';
- xlfd += QByteArray::number(desc.encoding->yres);
- xlfd += '-';
- xlfd += desc.encoding->pitch;
- xlfd += '-';
- xlfd += QByteArray::number(desc.encoding->avgwidth);
- xlfd += '-';
- xlfd += xlfd_for_id(desc.encoding->encoding);
-
- FM_DEBUG(" using XLFD: %s\n", xlfd.data());
-
- const int mib = xlfd_encoding[desc.encoding->encoding].mib;
- XFontStruct *xfs;
- if ((xfs = XLoadQueryFont(QX11Info::display(), xlfd))) {
- fe = new QFontEngineXLFD(xfs, xlfd, mib);
- const int dpi = QX11Info::appDpiY();
- if (!qt_fillFontDef(xfs, &fe->fontDef, dpi, &desc)
- && !qt_fillFontDef(xlfd, &fe->fontDef, dpi, &desc)) {
- initFontDef(desc, request, &fe->fontDef);
- }
- }
- }
- if (!fe) {
- fe = new QFontEngineBox(request.pixelSize);
- fe->fontDef = QFontDef();
- }
- } else {
- QList<int> encodings;
- if (desc.encoding) {
- if (desc.encoding->encoding >= 0)
- encodings.append(int(desc.encoding->encoding));
- }
-
- if (desc.size) {
- // append all other encodings for the matched font
- for (int i = 0; i < desc.size->count; ++i) {
- QtFontEncoding *e = desc.size->encodings + i;
- if (e == desc.encoding || e->encoding < 0)
- continue;
- encodings.append(int(e->encoding));
- }
- }
- // fill in the missing encodings
- const XlfdEncoding *enc = xlfd_encoding;
- for (; enc->name; ++enc) {
- if (!encodings.contains(enc->id) && enc->id >= 0) {
- encodings.append(enc->id);
- }
- }
-
-#if defined(FONT_MATCH_DEBUG)
- FM_DEBUG(" using MultiXLFD, encodings:");
- for (int i = 0; i < encodings.size(); ++i) {
- const int id = encodings.at(i);
- FM_DEBUG(" %2d: %s", xlfd_encoding[id].id, xlfd_encoding[id].name);
- }
-#endif
-
- fe = new QFontEngineMultiXLFD(request, encodings, screen);
- }
- return fe;
-}
-
-#if (defined(QT_ARCH_ARM) || defined(QT_ARCH_ARMV6)) && defined(Q_CC_GNU) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
-#define NEEDS_GCC_BUG_WORKAROUND
-#endif
-
-#ifdef NEEDS_GCC_BUG_WORKAROUND
-static inline void gccBugWorkaround(const QFontDef &req)
-{
- char buffer[8];
- snprintf(buffer, 8, "%f", req.pixelSize);
-}
-#endif
-
-/*! \internal
- Loads a QFontEngine for the specified \a script that matches the
- QFontDef \e request member variable.
-*/
-void QFontDatabase::load(const QFontPrivate *d, int script)
-{
- Q_ASSERT(script >= 0 && script < QUnicodeTables::ScriptCount);
-
- // normalize the request to get better caching
- QFontDef req = d->request;
- if (req.pixelSize <= 0)
- req.pixelSize = qFloor(qt_pixelSize(req.pointSize, d->dpi) * 100.0 + 0.5) * 0.01;
- if (req.pixelSize < 1)
- req.pixelSize = 1;
-
-#ifdef NEEDS_GCC_BUG_WORKAROUND
- // req.pixelSize ends up with a bogus value unless this workaround is called
- gccBugWorkaround(req);
-#endif
-
- if (req.weight == 0)
- req.weight = QFont::Normal;
- if (req.stretch == 0)
- req.stretch = 100;
-
- QFontCache::Key key(req, d->rawMode ? QUnicodeTables::Common : script, d->screen);
- if (!d->engineData)
- getEngineData(d, key);
-
- // the cached engineData could have already loaded the engine we want
- if (d->engineData->engines[script])
- return;
-
- // set it to the actual pointsize, so QFontInfo will do the right thing
- if (req.pointSize < 0)
- req.pointSize = qt_pointSize(req.pixelSize, d->dpi);
-
-
- QFontEngine *fe = QFontCache::instance()->findEngine(key);
-
- if (!fe) {
- QMutexLocker locker(fontDatabaseMutex());
- if (!privateDb()->count)
- initializeDb();
-
- const bool mainThread = (qApp->thread() == QThread::currentThread());
- if (qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) {
- fe = new QTestFontEngine(req.pixelSize);
- fe->fontDef = req;
- } else if (d->rawMode) {
- if (mainThread)
- fe = loadRaw(d, req);
-#ifndef QT_NO_FONTCONFIG
- } else if (X11->has_fontconfig) {
- fe = loadFc(d, script, req);
-#endif
- } else if (mainThread && qt_is_gui_used) {
- fe = loadXlfd(d->screen, script, req);
- }
- if (!fe) {
- fe = new QFontEngineBox(req.pixelSize);
- fe->fontDef = QFontDef();
- }
- }
- if (fe->symbol || (d->request.styleStrategy & QFont::NoFontMerging)) {
- for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) {
- if (!d->engineData->engines[i]) {
- d->engineData->engines[i] = fe;
- fe->ref.ref();
- }
- }
- } else {
- d->engineData->engines[script] = fe;
- fe->ref.ref();
- }
- QFontCache::instance()->insertEngine(key, fe);
-}
-
-// Needed for fontconfig version < 2.2.97
-#ifndef FC_FAMILYLANG
-#define FC_FAMILYLANG "familylang"
-#endif
-
-static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
-{
-#if defined(QT_NO_FONTCONFIG)
- return;
-#else
- if (!X11->has_fontconfig)
- return;
-
- FcConfig *config = FcConfigGetCurrent();
- if (!config)
- return;
-
- FcFontSet *set = FcConfigGetFonts(config, FcSetApplication);
- if (!set) {
- FcConfigAppFontAddFile(config, (const FcChar8 *)":/non-existent");
- set = FcConfigGetFonts(config, FcSetApplication); // try again
- if (!set)
- return;
- }
-
- QString fileNameForQuery = fnt->fileName;
-#if FC_VERSION < 20402
- QTemporaryFile tmp;
-
- if (!fnt->data.isEmpty()) {
- if (!tmp.open())
- return;
- tmp.write(fnt->data);
- tmp.flush();
- fileNameForQuery = tmp.fileName();
- }
-#endif
-
- int id = 0;
- FcBlanks *blanks = FcConfigGetBlanks(0);
- int count = 0;
-
- QStringList families;
- QFontDatabasePrivate *db = privateDb();
-
- FcPattern *pattern = 0;
- do {
- pattern = queryFont((const FcChar8 *)QFile::encodeName(fileNameForQuery).constData(),
- fnt->data, id, blanks, &count);
- if (!pattern)
- return;
-
- FcPatternDel(pattern, FC_FILE);
- QByteArray cs = fnt->fileName.toUtf8();
- FcPatternAddString(pattern, FC_FILE, (const FcChar8 *) cs.constData());
-
- FcChar8 *fam = 0, *familylang = 0;
- int i, n = 0;
- for (i = 0; ; i++) {
- if (FcPatternGetString(pattern, FC_FAMILYLANG, i, &familylang) != FcResultMatch)
- break;
- QString familyLang = QString::fromUtf8((const char *) familylang);
- if (familyLang.compare(db->systemLang, Qt::CaseInsensitive) == 0) {
- n = i;
- break;
- }
- }
-
- if (FcPatternGetString(pattern, FC_FAMILY, n, &fam) == FcResultMatch) {
- QString family = QString::fromUtf8(reinterpret_cast<const char *>(fam));
- families << family;
- }
-
- if (!FcFontSetAdd(set, pattern))
- return;
-
- ++id;
- } while (pattern && id < count);
-
- fnt->families = families;
-#endif
-}
-
-bool QFontDatabase::removeApplicationFont(int handle)
-{
-#if defined(QT_NO_FONTCONFIG)
- return false;
-#else
- QMutexLocker locker(fontDatabaseMutex());
-
- QFontDatabasePrivate *db = privateDb();
- if (handle < 0 || handle >= db->applicationFonts.count())
- return false;
-
- FcConfigAppFontClear(0);
-
- db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont();
-
- db->reregisterAppFonts = true;
- db->invalidate();
- return true;
-#endif
-}
-
-bool QFontDatabase::removeAllApplicationFonts()
-{
-#if defined(QT_NO_FONTCONFIG)
- return false;
-#else
- QMutexLocker locker(fontDatabaseMutex());
-
- QFontDatabasePrivate *db = privateDb();
- if (db->applicationFonts.isEmpty())
- return false;
-
- FcConfigAppFontClear(0);
- db->applicationFonts.clear();
- db->invalidate();
- return true;
-#endif
-}
-
-bool QFontDatabase::supportsThreadedFontRendering()
-{
-#if defined(QT_NO_FONTCONFIG)
- return false;
-#else
- return X11->has_fontconfig;
-#endif
-}
-
-QString QFontDatabase::resolveFontFamilyAlias(const QString &family)
-{
-#if defined(QT_NO_FONTCONFIG)
- return family;
-#else
- FcPattern *pattern = FcPatternCreate();
- if (!pattern)
- return family;
-
- QByteArray cs = family.toUtf8();
- FcPatternAddString(pattern, FC_FAMILY, (const FcChar8 *) cs.constData());
- FcConfigSubstitute(0, pattern, FcMatchPattern);
- FcDefaultSubstitute(pattern);
-
- FcChar8 *familyAfterSubstitution;
- FcPatternGetString(pattern, FC_FAMILY, 0, &familyAfterSubstitution);
- QString resolved = QString::fromUtf8((const char *) familyAfterSubstitution);
- FcPatternDestroy(pattern);
-
- return resolved;
-#endif
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index a258b72708..9d42d8ab69 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -1681,11 +1681,42 @@ bool QFontEngineMulti::canRender(const QChar *string, int len)
return allExist;
}
-QImage QFontEngineMulti::alphaMapForGlyph(glyph_t)
+/* Implement alphaMapForGlyph() which is called by Lighthouse/Windows code.
+ * Ideally, that code should be fixed to correctly handle QFontEngineMulti. */
+
+QImage QFontEngineMulti::alphaMapForGlyph(glyph_t glyph)
+{
+ const int which = highByte(glyph);
+ Q_ASSERT(which < engines.size());
+ return engine(which)->alphaMapForGlyph(stripped(glyph));
+}
+
+QImage QFontEngineMulti::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition)
+{
+ const int which = highByte(glyph);
+ Q_ASSERT(which < engines.size());
+ return engine(which)->alphaMapForGlyph(stripped(glyph), subPixelPosition);
+}
+
+QImage QFontEngineMulti::alphaMapForGlyph(glyph_t glyph, const QTransform &t)
{
- Q_ASSERT(false);
- return QImage();
+ const int which = highByte(glyph);
+ Q_ASSERT(which < engines.size());
+ return engine(which)->alphaMapForGlyph(stripped(glyph), t);
}
+QImage QFontEngineMulti::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t)
+{
+ const int which = highByte(glyph);
+ Q_ASSERT(which < engines.size());
+ return engine(which)->alphaMapForGlyph(stripped(glyph), subPixelPosition, t);
+}
+
+QImage QFontEngineMulti::alphaRGBMapForGlyph(glyph_t glyph, QFixed subPixelPosition, int margin, const QTransform &t)
+{
+ const int which = highByte(glyph);
+ Q_ASSERT(which < engines.size());
+ return engine(which)->alphaRGBMapForGlyph(stripped(glyph), subPixelPosition, margin, t);
+}
QT_END_NAMESPACE
diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm
deleted file mode 100644
index 9943229787..0000000000
--- a/src/gui/text/qfontengine_coretext.mm
+++ /dev/null
@@ -1,870 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qfontengine_coretext_p.h"
-
-#include <QtCore/qendian.h>
-#include <QtCore/qsettings.h>
-
-#include <private/qimage_p.h>
-
-#if !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
-
-QT_BEGIN_NAMESPACE
-
-static float SYNTHETIC_ITALIC_SKEW = tanf(14 * acosf(0) / 90);
-
-static void loadAdvancesForGlyphs(CTFontRef ctfont,
- QVarLengthArray<CGGlyph> &cgGlyphs,
- QGlyphLayout *glyphs, int len,
- QTextEngine::ShaperFlags flags,
- const QFontDef &fontDef)
-{
- Q_UNUSED(flags);
- QVarLengthArray<CGSize> advances(len);
- CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, cgGlyphs.data(), advances.data(), len);
-
- for (int i = 0; i < len; ++i) {
- if (glyphs->glyphs[i] & 0xff000000)
- continue;
- glyphs->advances_x[i] = QFixed::fromReal(advances[i].width);
- glyphs->advances_y[i] = QFixed::fromReal(advances[i].height);
- }
-
- if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
- for (int i = 0; i < len; ++i) {
- glyphs->advances_x[i] = glyphs->advances_x[i].round();
- glyphs->advances_y[i] = glyphs->advances_y[i].round();
- }
- }
-}
-
-QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning)
- : QFontEngineMulti(0)
-{
- this->fontDef = fontDef;
- CTFontSymbolicTraits symbolicTraits = 0;
- if (fontDef.weight >= QFont::Bold)
- symbolicTraits |= kCTFontBoldTrait;
- switch (fontDef.style) {
- case QFont::StyleNormal:
- break;
- case QFont::StyleItalic:
- case QFont::StyleOblique:
- symbolicTraits |= kCTFontItalicTrait;
- break;
- }
-
- transform = CGAffineTransformIdentity;
- if (fontDef.stretch != 100) {
- transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1);
- }
-
- QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pixelSize);
- QCFType<CTFontRef> baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, &transform);
- ctfont = NULL;
- // There is a side effect in Core Text: if we apply 0 as symbolic traits to a font in normal weight,
- // we will get the light version of that font (while the way supposed to work doesn't:
- // setting kCTFontWeightTrait to some value between -1.0 to 0.0 has no effect on font selection)
- if (fontDef.weight != QFont::Normal || symbolicTraits)
- ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, &transform, symbolicTraits, symbolicTraits);
-
- // CTFontCreateCopyWithSymbolicTraits returns NULL if we ask for a trait that does
- // not exist for the given font. (for example italic)
- if (ctfont == 0) {
- ctfont = baseFont;
- CFRetain(ctfont);
- }
- init(kerning);
-}
-
-QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(CTFontRef ctFontRef, const QFontDef &fontDef, bool kerning)
- : QFontEngineMulti(0)
-{
- this->fontDef = fontDef;
- ctfont = (CTFontRef) CFRetain(ctFontRef);
- init(kerning);
-}
-
-QCoreTextFontEngineMulti::~QCoreTextFontEngineMulti()
-{
- CFRelease(ctfont);
-}
-
-void QCoreTextFontEngineMulti::init(bool kerning)
-{
- Q_ASSERT(ctfont != NULL);
- attributeDict = CFDictionaryCreateMutable(0, 2,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- CFDictionaryAddValue(attributeDict, NSFontAttributeName, ctfont);
- if (!kerning) {
- float zero = 0.0;
- QCFType<CFNumberRef> noKern = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &zero);
- CFDictionaryAddValue(attributeDict, kCTKernAttributeName, noKern);
- }
-
- QCoreTextFontEngine *fe = new QCoreTextFontEngine(ctfont, fontDef);
- fontDef.family = fe->fontDef.family;
- fontDef.styleName = fe->fontDef.styleName;
- transform = fe->transform;
- fe->ref.ref();
- engines.append(fe);
-}
-
-uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef font) const
-{
- for (int i = 0; i < engines.count(); ++i) {
- if (CFEqual(engineAt(i)->ctfont, font))
- return i;
- }
-
- QCoreTextFontEngineMulti *that = const_cast<QCoreTextFontEngineMulti *>(this);
- QCoreTextFontEngine *fe = new QCoreTextFontEngine(font, fontDef);
- fe->ref.ref();
- that->engines.append(fe);
- return engines.count() - 1;
-}
-
-bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
- int *nglyphs, QTextEngine::ShaperFlags flags,
- unsigned short *logClusters, const HB_CharAttributes *,
- QScriptItem *si) const
-{
- QCFType<CFStringRef> cfstring = CFStringCreateWithCharactersNoCopy(0,
- reinterpret_cast<const UniChar *>(str),
- len, kCFAllocatorNull);
- QCFType<CFAttributedStringRef> attributedString = CFAttributedStringCreate(0, cfstring, attributeDict);
- QCFType<CTTypesetterRef> typeSetter;
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
- if (flags & QTextEngine::RightToLeft) {
- const void *optionKeys[] = { kCTTypesetterOptionForcedEmbeddingLevel };
- const short rtlForcedEmbeddingLevelValue = 1;
- const void *rtlOptionValues[] = { CFNumberCreate(kCFAllocatorDefault, kCFNumberShortType, &rtlForcedEmbeddingLevelValue) };
- QCFType<CFDictionaryRef> options = CFDictionaryCreate(kCFAllocatorDefault, optionKeys, rtlOptionValues, 1,
- &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- typeSetter = CTTypesetterCreateWithAttributedStringAndOptions(attributedString, options);
- } else
-#else
- Q_UNUSED(flags);
-#endif
- typeSetter = CTTypesetterCreateWithAttributedString(attributedString);
-
- CFRange range = {0, 0};
- QCFType<CTLineRef> line = CTTypesetterCreateLine(typeSetter, range);
- CFArrayRef array = CTLineGetGlyphRuns(line);
- uint arraySize = CFArrayGetCount(array);
- glyph_t *outGlyphs = glyphs->glyphs;
- HB_GlyphAttributes *outAttributes = glyphs->attributes;
- QFixed *outAdvances_x = glyphs->advances_x;
- QFixed *outAdvances_y = glyphs->advances_y;
- glyph_t *initialGlyph = outGlyphs;
-
- if (arraySize == 0) {
- // CoreText failed to shape the text we gave it, so we assume one glyph
- // per character and build a list of invalid glyphs with zero advance
- *nglyphs = len;
- for (int i = 0; i < len; ++i) {
- outGlyphs[i] = 0;
- if (logClusters)
- logClusters[i] = i;
- outAdvances_x[i] = QFixed();
- outAdvances_y[i] = QFixed();
- outAttributes[i].clusterStart = true;
- }
- return true;
- }
-
- const bool rtl = (CTRunGetStatus(static_cast<CTRunRef>(CFArrayGetValueAtIndex(array, 0))) & kCTRunStatusRightToLeft);
-
- bool outOBounds = false;
- for (uint i = 0; i < arraySize; ++i) {
- CTRunRef run = static_cast<CTRunRef>(CFArrayGetValueAtIndex(array, rtl ? (arraySize - 1 - i) : i));
- CFIndex glyphCount = CTRunGetGlyphCount(run);
- if (glyphCount == 0)
- continue;
-
- Q_ASSERT((CTRunGetStatus(run) & kCTRunStatusRightToLeft) == rtl);
- CFRange stringRange = CTRunGetStringRange(run);
- int prepend = 0;
-#if MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5
- UniChar beginGlyph = CFStringGetCharacterAtIndex(cfstring, stringRange.location);
- QChar dir = QChar::direction(beginGlyph);
- bool beginWithOverride = dir == QChar::DirLRO || dir == QChar::DirRLO || dir == QChar::DirLRE || dir == QChar::DirRLE;
- if (beginWithOverride) {
- logClusters[stringRange.location] = 0;
- outGlyphs[0] = 0xFFFF;
- outAdvances_x[0] = 0;
- outAdvances_y[0] = 0;
- outAttributes[0].clusterStart = true;
- outAttributes[0].dontPrint = true;
- outGlyphs++;
- outAdvances_x++;
- outAdvances_y++;
- outAttributes++;
- prepend = 1;
- }
-#endif
- UniChar endGlyph = CFStringGetCharacterAtIndex(cfstring, stringRange.location + stringRange.length - 1);
- bool endWithPDF = QChar::direction(endGlyph) == QChar::DirPDF;
- if (endWithPDF)
- glyphCount++;
-
- if (!outOBounds && outGlyphs + glyphCount - initialGlyph > *nglyphs) {
- outOBounds = true;
- }
- if (!outOBounds) {
- CFDictionaryRef runAttribs = CTRunGetAttributes(run);
- //NSLog(@"Dictionary %@", runAttribs);
- if (!runAttribs)
- runAttribs = attributeDict;
- CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(runAttribs, NSFontAttributeName));
- uint fontIndex = fontIndexForFont(runFont);
- const QFontEngine *engine = engineAt(fontIndex);
- fontIndex <<= 24;
- si->ascent = qMax(engine->ascent(), si->ascent);
- si->descent = qMax(engine->descent(), si->descent);
- si->leading = qMax(engine->leading(), si->leading);
- //NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont));
- if (endWithPDF)
- glyphCount--;
-
- QVarLengthArray<CGGlyph, 512> cgglyphs(0);
- const CGGlyph *tmpGlyphs = CTRunGetGlyphsPtr(run);
- if (!tmpGlyphs) {
- cgglyphs.resize(glyphCount);
- CTRunGetGlyphs(run, range, cgglyphs.data());
- tmpGlyphs = cgglyphs.constData();
- }
- QVarLengthArray<CGPoint, 512> cgpoints(0);
- const CGPoint *tmpPoints = CTRunGetPositionsPtr(run);
- if (!tmpPoints) {
- cgpoints.resize(glyphCount);
- CTRunGetPositions(run, range, cgpoints.data());
- tmpPoints = cgpoints.constData();
- }
-
- const int rtlOffset = rtl ? (glyphCount - 1) : 0;
- const int rtlSign = rtl ? -1 : 1;
-
- if (logClusters) {
- CFRange stringRange = CTRunGetStringRange(run);
- QVarLengthArray<CFIndex, 512> stringIndices(0);
- const CFIndex *tmpIndices = CTRunGetStringIndicesPtr(run);
- if (!tmpIndices) {
- stringIndices.resize(glyphCount);
- CTRunGetStringIndices(run, range, stringIndices.data());
- tmpIndices = stringIndices.constData();
- }
-
- const int firstGlyphIndex = outGlyphs - initialGlyph;
- outAttributes[0].clusterStart = true;
-
- CFIndex k = 0;
- CFIndex i = 0;
- for (i = stringRange.location + prepend;
- (i < stringRange.location + stringRange.length) && (k < glyphCount); ++i) {
- if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location + prepend) {
- logClusters[i] = k + firstGlyphIndex;
- outAttributes[k].clusterStart = true;
- ++k;
- } else {
- logClusters[i] = k + firstGlyphIndex - 1;
- }
- }
- // in case of a ligature at the end, fill the remaining logcluster entries
- for (;i < stringRange.location + stringRange.length; i++) {
- logClusters[i] = k + firstGlyphIndex - 1;
- }
- }
- for (CFIndex i = 0; i < glyphCount - 1; ++i) {
- int idx = rtlOffset + rtlSign * i;
- outGlyphs[idx] = tmpGlyphs[i] | fontIndex;
- outAdvances_x[idx] = QFixed::fromReal(tmpPoints[i + 1].x - tmpPoints[i].x);
- // Use negative y advance for flipped coordinate system
- outAdvances_y[idx] = QFixed::fromReal(tmpPoints[i].y - tmpPoints[i + 1].y);
-
- if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
- outAdvances_x[idx] = outAdvances_x[idx].round();
- outAdvances_y[idx] = outAdvances_y[idx].round();
- }
- }
- CGSize lastGlyphAdvance;
- CTFontGetAdvancesForGlyphs(runFont, kCTFontHorizontalOrientation, tmpGlyphs + glyphCount - 1, &lastGlyphAdvance, 1);
-
- outGlyphs[rtl ? 0 : (glyphCount - 1)] = tmpGlyphs[glyphCount - 1] | fontIndex;
- outAdvances_x[rtl ? 0 : (glyphCount - 1)] =
- (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? QFixed::fromReal(lastGlyphAdvance.width).round()
- : QFixed::fromReal(lastGlyphAdvance.width);
-
- if (endWithPDF) {
- logClusters[stringRange.location + stringRange.length - 1] = glyphCount + prepend;
- outGlyphs[glyphCount] = 0xFFFF;
- outAdvances_x[glyphCount] = 0;
- outAdvances_y[glyphCount] = 0;
- outAttributes[glyphCount].clusterStart = true;
- outAttributes[glyphCount].dontPrint = true;
- glyphCount++;
- }
- }
- outGlyphs += glyphCount;
- outAttributes += glyphCount;
- outAdvances_x += glyphCount;
- outAdvances_y += glyphCount;
- }
- *nglyphs = (outGlyphs - initialGlyph);
- return !outOBounds;
-}
-
-bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
- int *nglyphs, QTextEngine::ShaperFlags flags) const
-{
- *nglyphs = len;
- QCFType<CFStringRef> cfstring;
-
- QVarLengthArray<CGGlyph> cgGlyphs(len);
- CTFontGetGlyphsForCharacters(ctfont, (const UniChar*)str, cgGlyphs.data(), len);
-
- for (int i = 0; i < len; ++i) {
- if (cgGlyphs[i]) {
- glyphs->glyphs[i] = cgGlyphs[i];
- } else {
- if (!cfstring)
- cfstring = CFStringCreateWithCharactersNoCopy(0, reinterpret_cast<const UniChar *>(str), len, kCFAllocatorNull);
- QCFType<CTFontRef> substituteFont = CTFontCreateForString(ctfont, cfstring, CFRangeMake(i, 1));
- CGGlyph substituteGlyph = 0;
- CTFontGetGlyphsForCharacters(substituteFont, (const UniChar*)str + i, &substituteGlyph, 1);
- if (substituteGlyph) {
- const uint fontIndex = (fontIndexForFont(substituteFont) << 24);
- glyphs->glyphs[i] = substituteGlyph | fontIndex;
- if (!(flags & QTextEngine::GlyphIndicesOnly)) {
- CGSize advance;
- CTFontGetAdvancesForGlyphs(substituteFont, kCTFontHorizontalOrientation, &substituteGlyph, &advance, 1);
- glyphs->advances_x[i] = QFixed::fromReal(advance.width);
- glyphs->advances_y[i] = QFixed::fromReal(advance.height);
- }
- }
- }
- }
-
- if (flags & QTextEngine::GlyphIndicesOnly)
- return true;
-
- loadAdvancesForGlyphs(ctfont, cgGlyphs, glyphs, len, flags, fontDef);
- return true;
-}
-
-void QCoreTextFontEngineMulti::loadEngine(int)
-{
- // Do nothing
- Q_ASSERT(false);
-}
-
-extern int qt_antialiasing_threshold; // from qapplication.cpp
-
-CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef)
-{
- CGAffineTransform transform = CGAffineTransformIdentity;
- if (fontDef.stretch != 100)
- transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1);
- return transform;
-}
-
-QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def)
-{
- fontDef = def;
- transform = qt_transform_from_fontdef(fontDef);
- ctfont = font;
- CFRetain(ctfont);
- cgFont = CTFontCopyGraphicsFont(font, NULL);
- init();
-}
-
-QCoreTextFontEngine::QCoreTextFontEngine(CGFontRef font, const QFontDef &def)
-{
- fontDef = def;
- transform = qt_transform_from_fontdef(fontDef);
- cgFont = font;
- // Keep reference count balanced
- CFRetain(cgFont);
- ctfont = CTFontCreateWithGraphicsFont(font, fontDef.pixelSize, &transform, NULL);
- init();
-}
-
-QCoreTextFontEngine::~QCoreTextFontEngine()
-{
- CFRelease(cgFont);
- CFRelease(ctfont);
-}
-
-extern QFont::Weight weightFromInteger(int weight); // qfontdatabase.cpp
-
-int getTraitValue(CFDictionaryRef allTraits, CFStringRef trait)
-{
- if (CFDictionaryContainsKey(allTraits, trait)) {
- CFNumberRef traitNum = (CFNumberRef) CFDictionaryGetValue(allTraits, trait);
- float v = 0;
- CFNumberGetValue(traitNum, kCFNumberFloatType, &v);
- // the value we get from CFNumberRef is from -1.0 to 1.0
- int value = v * 500 + 500;
- return value;
- }
-
- return 0;
-}
-
-void QCoreTextFontEngine::init()
-{
- Q_ASSERT(ctfont != NULL);
- Q_ASSERT(cgFont != NULL);
-
- QCFString family = CTFontCopyFamilyName(ctfont);
- fontDef.family = family;
-
- QCFString styleName = (CFStringRef) CTFontCopyAttribute(ctfont, kCTFontStyleNameAttribute);
- fontDef.styleName = styleName;
-
- synthesisFlags = 0;
- CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctfont);
- if (traits & kCTFontItalicTrait)
- fontDef.style = QFont::StyleItalic;
-
- CFDictionaryRef allTraits = CTFontCopyTraits(ctfont);
- fontDef.weight = weightFromInteger(getTraitValue(allTraits, kCTFontWeightTrait));
- int slant = getTraitValue(allTraits, kCTFontSlantTrait);
- if (slant > 500 && !(traits & kCTFontItalicTrait))
- fontDef.style = QFont::StyleOblique;
- CFRelease(allTraits);
-
- if (fontDef.weight >= QFont::Bold && !(traits & kCTFontBoldTrait))
- synthesisFlags |= SynthesizedBold;
- // XXX: we probably don't need to synthesis italic for oblique font
- if (fontDef.style != QFont::StyleNormal && !(traits & kCTFontItalicTrait))
- synthesisFlags |= SynthesizedItalic;
-
- avgCharWidth = 0;
- QByteArray os2Table = getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
- unsigned emSize = CTFontGetUnitsPerEm(ctfont);
- if (os2Table.size() >= 10) {
- fsType = qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(os2Table.constData() + 8));
- // qAbs is a workaround for weird fonts like Lucida Grande
- qint16 width = qAbs(qFromBigEndian<qint16>(reinterpret_cast<const uchar *>(os2Table.constData() + 2)));
- avgCharWidth = QFixed::fromReal(width * fontDef.pixelSize / emSize);
- } else
- avgCharWidth = QFontEngine::averageCharWidth();
-}
-
-bool QCoreTextFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
- int *nglyphs, QTextEngine::ShaperFlags flags) const
-{
- *nglyphs = len;
- QCFType<CFStringRef> cfstring;
-
- QVarLengthArray<CGGlyph> cgGlyphs(len);
- CTFontGetGlyphsForCharacters(ctfont, (const UniChar*)str, cgGlyphs.data(), len);
-
- for (int i = 0; i < len; ++i)
- if (cgGlyphs[i])
- glyphs->glyphs[i] = cgGlyphs[i];
-
- if (flags & QTextEngine::GlyphIndicesOnly)
- return true;
-
- loadAdvancesForGlyphs(ctfont, cgGlyphs, glyphs, len, flags, fontDef);
- return true;
-}
-
-glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs)
-{
- QFixed w;
- bool round = fontDef.styleStrategy & QFont::ForceIntegerMetrics;
-
- for (int i = 0; i < glyphs.numGlyphs; ++i) {
- w += round ? glyphs.effectiveAdvance(i).round()
- : glyphs.effectiveAdvance(i);
- }
- return glyph_metrics_t(0, -(ascent()), w - lastRightBearing(glyphs, round), ascent()+descent(), w, 0);
-}
-
-glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph)
-{
- glyph_metrics_t ret;
- CGGlyph g = glyph;
- CGRect rect = CTFontGetBoundingRectsForGlyphs(ctfont, kCTFontHorizontalOrientation, &g, 0, 1);
- if (synthesisFlags & QFontEngine::SynthesizedItalic) {
- rect.size.width += rect.size.height * SYNTHETIC_ITALIC_SKEW;
- }
- ret.width = QFixed::fromReal(rect.size.width);
- ret.height = QFixed::fromReal(rect.size.height);
- ret.x = QFixed::fromReal(rect.origin.x);
- ret.y = -QFixed::fromReal(rect.origin.y) - ret.height;
- CGSize advances[1];
- CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, &g, advances, 1);
- ret.xoff = QFixed::fromReal(advances[0].width);
- ret.yoff = QFixed::fromReal(advances[0].height);
-
- if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
- ret.xoff = ret.xoff.round();
- ret.yoff = ret.yoff.round();
- }
-
- return ret;
-}
-
-QFixed QCoreTextFontEngine::ascent() const
-{
- return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? QFixed::fromReal(CTFontGetAscent(ctfont)).round()
- : QFixed::fromReal(CTFontGetAscent(ctfont));
-}
-QFixed QCoreTextFontEngine::descent() const
-{
- QFixed d = QFixed::fromReal(CTFontGetDescent(ctfont));
- if (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- d = d.round();
-
- // subtract a pixel to even out the historical +1 in QFontMetrics::height().
- // Fix in Qt 5.
- return d - 1;
-}
-QFixed QCoreTextFontEngine::leading() const
-{
- return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? QFixed::fromReal(CTFontGetLeading(ctfont)).round()
- : QFixed::fromReal(CTFontGetLeading(ctfont));
-}
-QFixed QCoreTextFontEngine::xHeight() const
-{
- return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? QFixed::fromReal(CTFontGetXHeight(ctfont)).round()
- : QFixed::fromReal(CTFontGetXHeight(ctfont));
-}
-
-QFixed QCoreTextFontEngine::averageCharWidth() const
-{
- return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? avgCharWidth.round() : avgCharWidth;
-}
-
-qreal QCoreTextFontEngine::maxCharWidth() const
-{
- return 0;
-}
-
-qreal QCoreTextFontEngine::minLeftBearing() const
-{
- return 0;
-}
-
-qreal QCoreTextFontEngine::minRightBearing() const
-{
- return 0;
-}
-
-void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight)
-{
- QVarLengthArray<QFixedPoint> positions;
- QVarLengthArray<glyph_t> glyphs;
- QTransform matrix;
- matrix.translate(x, y);
- getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
- if (glyphs.size() == 0)
- return;
-
- CGContextSetFontSize(ctx, fontDef.pixelSize);
-
- CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx);
-
- CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, -1, 0, -paintDeviceHeight);
-
- CGAffineTransformConcat(cgMatrix, oldTextMatrix);
-
- if (synthesisFlags & QFontEngine::SynthesizedItalic)
- cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -SYNTHETIC_ITALIC_SKEW, 1, 0, 0));
-
- cgMatrix = CGAffineTransformConcat(cgMatrix, transform);
-
- CGContextSetTextMatrix(ctx, cgMatrix);
-
- CGContextSetTextDrawingMode(ctx, kCGTextFill);
-
-
- QVarLengthArray<CGSize> advances(glyphs.size());
- QVarLengthArray<CGGlyph> cgGlyphs(glyphs.size());
-
- for (int i = 0; i < glyphs.size() - 1; ++i) {
- advances[i].width = (positions[i + 1].x - positions[i].x).toReal();
- advances[i].height = (positions[i + 1].y - positions[i].y).toReal();
- cgGlyphs[i] = glyphs[i];
- }
- advances[glyphs.size() - 1].width = 0;
- advances[glyphs.size() - 1].height = 0;
- cgGlyphs[glyphs.size() - 1] = glyphs[glyphs.size() - 1];
-
- CGContextSetFont(ctx, cgFont);
- //NSLog(@"Font inDraw %@ ctfont %@", CGFontCopyFullName(cgFont), CTFontCopyFamilyName(ctfont));
-
- CGContextSetTextPosition(ctx, positions[0].x.toReal(), positions[0].y.toReal());
-
- CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size());
-
- if (synthesisFlags & QFontEngine::SynthesizedBold) {
- CGContextSetTextPosition(ctx, positions[0].x.toReal() + 0.5 * lineThickness().toReal(),
- positions[0].y.toReal());
-
- CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size());
- }
-
- CGContextSetTextMatrix(ctx, oldTextMatrix);
-}
-
-struct ConvertPathInfo
-{
- ConvertPathInfo(QPainterPath *newPath, const QPointF &newPos) : path(newPath), pos(newPos) {}
- QPainterPath *path;
- QPointF pos;
-};
-
-static void convertCGPathToQPainterPath(void *info, const CGPathElement *element)
-{
- ConvertPathInfo *myInfo = static_cast<ConvertPathInfo *>(info);
- switch(element->type) {
- case kCGPathElementMoveToPoint:
- myInfo->path->moveTo(element->points[0].x + myInfo->pos.x(),
- element->points[0].y + myInfo->pos.y());
- break;
- case kCGPathElementAddLineToPoint:
- myInfo->path->lineTo(element->points[0].x + myInfo->pos.x(),
- element->points[0].y + myInfo->pos.y());
- break;
- case kCGPathElementAddQuadCurveToPoint:
- myInfo->path->quadTo(element->points[0].x + myInfo->pos.x(),
- element->points[0].y + myInfo->pos.y(),
- element->points[1].x + myInfo->pos.x(),
- element->points[1].y + myInfo->pos.y());
- break;
- case kCGPathElementAddCurveToPoint:
- myInfo->path->cubicTo(element->points[0].x + myInfo->pos.x(),
- element->points[0].y + myInfo->pos.y(),
- element->points[1].x + myInfo->pos.x(),
- element->points[1].y + myInfo->pos.y(),
- element->points[2].x + myInfo->pos.x(),
- element->points[2].y + myInfo->pos.y());
- break;
- case kCGPathElementCloseSubpath:
- myInfo->path->closeSubpath();
- break;
- default:
- qDebug() << "Unhandled path transform type: " << element->type;
- }
-
-}
-
-void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nGlyphs,
- QPainterPath *path, QTextItem::RenderFlags)
-{
- CGAffineTransform cgMatrix = CGAffineTransformIdentity;
- cgMatrix = CGAffineTransformScale(cgMatrix, 1, -1);
-
- if (synthesisFlags & QFontEngine::SynthesizedItalic)
- cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -SYNTHETIC_ITALIC_SKEW, 1, 0, 0));
-
- for (int i = 0; i < nGlyphs; ++i) {
- QCFType<CGPathRef> cgpath = CTFontCreatePathForGlyph(ctfont, glyphs[i], &cgMatrix);
- ConvertPathInfo info(path, positions[i].toPointF());
- CGPathApply(cgpath, &info, convertCGPathToQPainterPath);
- }
-}
-
-QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int /*margin*/, bool aa)
-{
- const glyph_metrics_t br = boundingBox(glyph);
- QImage im(qRound(br.width)+2, qRound(br.height)+2, QImage::Format_RGB32);
- im.fill(0);
-
- CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
- uint cgflags = kCGImageAlphaNoneSkipFirst;
-#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
- cgflags |= kCGBitmapByteOrder32Host;
-#endif
- CGContextRef ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(),
- 8, im.bytesPerLine(), colorspace,
- cgflags);
- CGContextSetFontSize(ctx, fontDef.pixelSize);
- CGContextSetShouldAntialias(ctx, (aa || fontDef.pointSize > qt_antialiasing_threshold)
- && !(fontDef.styleStrategy & QFont::NoAntialias));
- CGContextSetShouldSmoothFonts(ctx, aa);
- CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx);
- CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0);
-
- CGAffineTransformConcat(cgMatrix, oldTextMatrix);
-
- if (synthesisFlags & QFontEngine::SynthesizedItalic)
- cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, SYNTHETIC_ITALIC_SKEW, 1, 0, 0));
-
- cgMatrix = CGAffineTransformConcat(cgMatrix, transform);
-
- CGContextSetTextMatrix(ctx, cgMatrix);
- CGContextSetRGBFillColor(ctx, 1, 1, 1, 1);
- CGContextSetTextDrawingMode(ctx, kCGTextFill);
-
- CGContextSetFont(ctx, cgFont);
-
- qreal pos_x = -br.x.truncate() + subPixelPosition.toReal();
- qreal pos_y = im.height() + br.y.toReal();
- CGContextSetTextPosition(ctx, pos_x, pos_y);
-
- CGSize advance;
- advance.width = 0;
- advance.height = 0;
- CGGlyph cgGlyph = glyph;
- CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1);
-
- if (synthesisFlags & QFontEngine::SynthesizedBold) {
- CGContextSetTextPosition(ctx, pos_x + 0.5 * lineThickness().toReal(), pos_y);
- CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1);
- }
-
- CGContextRelease(ctx);
-
- return im;
-}
-
-QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition)
-{
- QImage im = imageForGlyph(glyph, subPixelPosition, 0, false);
-
- QImage indexed(im.width(), im.height(), QImage::Format_Indexed8);
- QVector<QRgb> colors(256);
- for (int i=0; i<256; ++i)
- colors[i] = qRgba(0, 0, 0, i);
- indexed.setColorTable(colors);
-
- for (int y=0; y<im.height(); ++y) {
- uint *src = (uint*) im.scanLine(y);
- uchar *dst = indexed.scanLine(y);
- for (int x=0; x<im.width(); ++x) {
- *dst = qGray(*src);
- ++dst;
- ++src;
- }
- }
-
- return indexed;
-}
-
-QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed subPixelPosition, int margin, const QTransform &x)
-{
- if (x.type() >= QTransform::TxScale)
- return QFontEngine::alphaRGBMapForGlyph(glyph, subPixelPosition, margin, x);
-
- QImage im = imageForGlyph(glyph, subPixelPosition, margin, true);
- qGamma_correct_back_to_linear_cs(&im);
- return im;
-}
-
-void QCoreTextFontEngine::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
-{
- int i, numGlyphs = glyphs->numGlyphs;
- QVarLengthArray<CGGlyph> cgGlyphs(numGlyphs);
-
- for (i = 0; i < numGlyphs; ++i) {
- if (glyphs->glyphs[i] & 0xff000000)
- cgGlyphs[i] = 0;
- else
- cgGlyphs[i] = glyphs->glyphs[i];
- }
-
- loadAdvancesForGlyphs(ctfont, cgGlyphs, glyphs, numGlyphs, flags, fontDef);
-}
-
-QFontEngine::FaceId QCoreTextFontEngine::faceId() const
-{
- return QFontEngine::FaceId();
-}
-
-bool QCoreTextFontEngine::canRender(const QChar *string, int len)
-{
- QVarLengthArray<CGGlyph> cgGlyphs(len);
- return CTFontGetGlyphsForCharacters(ctfont, (const UniChar *) string, cgGlyphs.data(), len);
-}
-
-bool QCoreTextFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const
-{
- QCFType<CFDataRef> table = CTFontCopyTable(ctfont, tag, 0);
- if (!table || !length)
- return false;
- CFIndex tableLength = CFDataGetLength(table);
- int availableLength = *length;
- *length = tableLength;
- if (buffer) {
- if (tableLength > availableLength)
- return false;
- CFDataGetBytes(table, CFRangeMake(0, tableLength), buffer);
- }
- return true;
-}
-
-void QCoreTextFontEngine::getUnscaledGlyph(glyph_t, QPainterPath *, glyph_metrics_t *)
-{
- // ###
-}
-
-QFixed QCoreTextFontEngine::emSquareSize() const
-{
- return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont)));
-}
-
-QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const
-{
- QFontDef newFontDef = fontDef;
- newFontDef.pixelSize = pixelSize;
- newFontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi();
-
- return new QCoreTextFontEngine(cgFont, newFontDef);
-}
-
-QT_END_NAMESPACE
-
-#endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
-
diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h
deleted file mode 100644
index d8a3033be6..0000000000
--- a/src/gui/text/qfontengine_coretext_p.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFONTENGINE_CORETEXT_P_H
-#define QFONTENGINE_CORETEXT_P_H
-
-#include <private/qfontengine_p.h>
-
-#if !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-class QRawFontPrivate;
-class QCoreTextFontEngineMulti;
-class QCoreTextFontEngine : public QFontEngine
-{
-public:
- QCoreTextFontEngine(CTFontRef font, const QFontDef &def);
- QCoreTextFontEngine(CGFontRef font, const QFontDef &def);
- ~QCoreTextFontEngine();
-
- virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
- virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
-
- virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
- virtual glyph_metrics_t boundingBox(glyph_t glyph);
-
- virtual QFixed ascent() const;
- virtual QFixed descent() const;
- virtual QFixed leading() const;
- virtual QFixed xHeight() const;
- virtual qreal maxCharWidth() const;
- virtual QFixed averageCharWidth() const;
-
- virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs,
- QPainterPath *path, QTextItem::RenderFlags);
-
- virtual const char *name() const { return "QCoreTextFontEngine"; }
-
- virtual bool canRender(const QChar *string, int len);
-
- virtual int synthesized() const { return synthesisFlags; }
- virtual bool supportsSubPixelPositions() const { return true; }
-
- virtual Type type() const { return QFontEngine::Mac; }
-
- void draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight);
-
- virtual FaceId faceId() const;
- virtual bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const;
- virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
- virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition);
- virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t);
- virtual qreal minRightBearing() const;
- virtual qreal minLeftBearing() const;
- virtual QFixed emSquareSize() const;
-
- virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
-
-private:
- friend class QRawFontPrivate;
-
- void init();
- QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int margin, bool colorful);
- CTFontRef ctfont;
- CGFontRef cgFont;
- int synthesisFlags;
- CGAffineTransform transform;
- QFixed avgCharWidth;
- friend class QCoreTextFontEngineMulti;
-};
-
-class QCoreTextFontEngineMulti : public QFontEngineMulti
-{
-public:
- QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning);
- QCoreTextFontEngineMulti(CTFontRef ctFontRef, const QFontDef &fontDef, bool kerning);
- ~QCoreTextFontEngineMulti();
-
- virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
- QTextEngine::ShaperFlags flags) const;
- bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
- QTextEngine::ShaperFlags flags,
- unsigned short *logClusters, const HB_CharAttributes *charAttributes,
- QScriptItem *si) const;
-
- virtual const char *name() const { return "CoreText"; }
- inline CTFontRef macFontID() const { return ctfont; }
-
-protected:
- virtual void loadEngine(int at);
-
-private:
- void init(bool kerning);
- inline const QCoreTextFontEngine *engineAt(int i) const
- { return static_cast<const QCoreTextFontEngine *>(engines.at(i)); }
-
- uint fontIndexForFont(CTFontRef font) const;
- CTFontRef ctfont;
- mutable QCFType<CFMutableDictionaryRef> attributeDict;
- CGAffineTransform transform;
- friend class QFontDialogPrivate;
-};
-
-CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef);
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
-
-#endif // QFONTENGINE_CORETEXT_P_H
diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h
index bd8e24a3fe..e320be4421 100644
--- a/src/gui/text/qfontengine_ft_p.h
+++ b/src/gui/text/qfontengine_ft_p.h
@@ -51,7 +51,7 @@
// We mean it.
//
-#include "qfontengine_p.h"
+#include "private/qfontengine_p.h"
#ifndef QT_NO_FREETYPE
diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm
deleted file mode 100644
index 9d9eaed058..0000000000
--- a/src/gui/text/qfontengine_mac.mm
+++ /dev/null
@@ -1,1236 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qfontengine_mac_p.h"
-
-#include <private/qapplication_p.h>
-#include <private/qfontengine_p.h>
-#include <private/qpainter_p.h>
-#include <private/qtextengine_p.h>
-#include <qbitmap.h>
-#include <private/qpaintengine_mac_p.h>
-#include <private/qprintengine_mac_p.h>
-#include <qglobal.h>
-#include <qpixmap.h>
-#include <qpixmapcache.h>
-#include <qvarlengtharray.h>
-#include <qdebug.h>
-#include <qendian.h>
-#include <qmath.h>
-#include <private/qimage_p.h>
-
-#include <ApplicationServices/ApplicationServices.h>
-#include <AppKit/AppKit.h>
-
-QT_BEGIN_NAMESPACE
-
-/*****************************************************************************
- QFontEngine debug facilities
- *****************************************************************************/
-//#define DEBUG_ADVANCES
-
-extern int qt_antialiasing_threshold; // QApplication.cpp
-
-#ifndef FixedToQFixed
-#define FixedToQFixed(a) QFixed::fromFixed((a) >> 10)
-#define QFixedToFixed(x) ((x).value() << 10)
-#endif
-
-class QMacFontPath
-{
- float x, y;
- QPainterPath *path;
-public:
- inline QMacFontPath(float _x, float _y, QPainterPath *_path) : x(_x), y(_y), path(_path) { }
- inline void setPosition(float _x, float _y) { x = _x; y = _y; }
- inline void advance(float _x) { x += _x; }
- static OSStatus lineTo(const Float32Point *, void *);
- static OSStatus cubicTo(const Float32Point *, const Float32Point *,
- const Float32Point *, void *);
- static OSStatus moveTo(const Float32Point *, void *);
- static OSStatus closePath(void *);
-};
-
-OSStatus QMacFontPath::lineTo(const Float32Point *pt, void *data)
-
-{
- QMacFontPath *p = static_cast<QMacFontPath*>(data);
- p->path->lineTo(p->x + pt->x, p->y + pt->y);
- return noErr;
-}
-
-OSStatus QMacFontPath::cubicTo(const Float32Point *cp1, const Float32Point *cp2,
- const Float32Point *ep, void *data)
-
-{
- QMacFontPath *p = static_cast<QMacFontPath*>(data);
- p->path->cubicTo(p->x + cp1->x, p->y + cp1->y,
- p->x + cp2->x, p->y + cp2->y,
- p->x + ep->x, p->y + ep->y);
- return noErr;
-}
-
-OSStatus QMacFontPath::moveTo(const Float32Point *pt, void *data)
-{
- QMacFontPath *p = static_cast<QMacFontPath*>(data);
- p->path->moveTo(p->x + pt->x, p->y + pt->y);
- return noErr;
-}
-
-OSStatus QMacFontPath::closePath(void *data)
-{
- static_cast<QMacFontPath*>(data)->path->closeSubpath();
- return noErr;
-}
-
-
-#ifndef QT_MAC_USE_COCOA
-QFontEngineMacMulti::QFontEngineMacMulti(const ATSFontFamilyRef &atsFamily, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool kerning)
- : QFontEngineMulti(0)
-{
- this->fontDef = fontDef;
- this->kerning = kerning;
-
- // hopefully (CTFontCreateWithName or CTFontCreateWithFontDescriptor) + CTFontCreateCopyWithSymbolicTraits
- // (or CTFontCreateWithQuickdrawInstance)
- FMFontFamily fmFamily;
- FMFontStyle fntStyle = 0;
- fmFamily = FMGetFontFamilyFromATSFontFamilyRef(atsFamily);
- if (fmFamily == kInvalidFontFamily) {
- // Use the ATSFont then...
- fontID = FMGetFontFromATSFontRef(atsFontRef);
- } else {
- if (fontDef.weight >= QFont::Bold)
- fntStyle |= ::bold;
- if (fontDef.style != QFont::StyleNormal)
- fntStyle |= ::italic;
-
- FMFontStyle intrinsicStyle;
- FMFont fnt = 0;
- if (FMGetFontFromFontFamilyInstance(fmFamily, fntStyle, &fnt, &intrinsicStyle) == noErr)
- fontID = FMGetATSFontRefFromFont(fnt);
- }
-
- // CFDictionaryRef, <CTStringAttributes.h>
- OSStatus status;
-
- status = ATSUCreateTextLayout(&textLayout);
- Q_ASSERT(status == noErr);
-
- const int maxAttributeCount = 5;
- ATSUAttributeTag tags[maxAttributeCount + 1];
- ByteCount sizes[maxAttributeCount + 1];
- ATSUAttributeValuePtr values[maxAttributeCount + 1];
- int attributeCount = 0;
-
- Fixed size = FixRatio(fontDef.pixelSize, 1);
- tags[attributeCount] = kATSUSizeTag;
- sizes[attributeCount] = sizeof(size);
- values[attributeCount] = &size;
- ++attributeCount;
-
- tags[attributeCount] = kATSUFontTag;
- sizes[attributeCount] = sizeof(fontID);
- values[attributeCount] = &this->fontID;
- ++attributeCount;
-
- transform = CGAffineTransformIdentity;
- if (fontDef.stretch != 100) {
- transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1);
- tags[attributeCount] = kATSUFontMatrixTag;
- sizes[attributeCount] = sizeof(transform);
- values[attributeCount] = &transform;
- ++attributeCount;
- }
-
- status = ATSUCreateStyle(&style);
- Q_ASSERT(status == noErr);
-
- Q_ASSERT(attributeCount < maxAttributeCount + 1);
- status = ATSUSetAttributes(style, attributeCount, tags, sizes, values);
- Q_ASSERT(status == noErr);
-
- QFontEngineMac *fe = new QFontEngineMac(style, fontID, fontDef, this);
- fe->ref.ref();
- engines.append(fe);
-}
-
-QFontEngineMacMulti::~QFontEngineMacMulti()
-{
- ATSUDisposeTextLayout(textLayout);
- ATSUDisposeStyle(style);
-
- for (int i = 0; i < engines.count(); ++i) {
- QFontEngineMac *fe = const_cast<QFontEngineMac *>(static_cast<const QFontEngineMac *>(engines.at(i)));
- fe->multiEngine = 0;
- if (!fe->ref.deref())
- delete fe;
- }
- engines.clear();
-}
-
-struct QGlyphLayoutInfo
-{
- QGlyphLayout *glyphs;
- int *numGlyphs;
- bool callbackCalled;
- int *mappedFonts;
- QTextEngine::ShaperFlags flags;
- QFontEngineMacMulti::ShaperItem *shaperItem;
- unsigned int styleStrategy;
-};
-
-static OSStatus atsuPostLayoutCallback(ATSULayoutOperationSelector selector, ATSULineRef lineRef, URefCon refCon,
- void *operationExtraParameter, ATSULayoutOperationCallbackStatus *callbackStatus)
-{
- Q_UNUSED(selector);
- Q_UNUSED(operationExtraParameter);
-
- QGlyphLayoutInfo *nfo = reinterpret_cast<QGlyphLayoutInfo *>(refCon);
- nfo->callbackCalled = true;
-
- ATSLayoutRecord *layoutData = 0;
- ItemCount itemCount = 0;
-
- OSStatus e = noErr;
- e = ATSUDirectGetLayoutDataArrayPtrFromLineRef(lineRef, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
- /*iCreate =*/ false,
- (void **) &layoutData,
- &itemCount);
- if (e != noErr)
- return e;
-
- *nfo->numGlyphs = itemCount - 1;
-
- Fixed *baselineDeltas = 0;
-
- e = ATSUDirectGetLayoutDataArrayPtrFromLineRef(lineRef, kATSUDirectDataBaselineDeltaFixedArray,
- /*iCreate =*/ true,
- (void **) &baselineDeltas,
- &itemCount);
- if (e != noErr)
- return e;
-
- int nextCharStop = -1;
- int currentClusterGlyph = -1; // first glyph in log cluster
- QFontEngineMacMulti::ShaperItem *item = nfo->shaperItem;
- if (item->charAttributes) {
- item = nfo->shaperItem;
-#if !defined(QT_NO_DEBUG)
- int surrogates = 0;
- const QChar *str = item->string;
- for (int i = item->from; i < item->from + item->length - 1; ++i) {
- surrogates += (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00
- && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000);
- }
-#endif
- for (nextCharStop = item->from; nextCharStop < item->from + item->length; ++nextCharStop)
- if (item->charAttributes[nextCharStop].charStop)
- break;
- nextCharStop -= item->from;
- }
-
- nfo->glyphs->attributes[0].clusterStart = true;
- int glyphIdx = 0;
- int glyphIncrement = 1;
- if (nfo->flags & QTextEngine::RightToLeft) {
- glyphIdx = itemCount - 2;
- glyphIncrement = -1;
- }
- for (int i = 0; i < *nfo->numGlyphs; ++i, glyphIdx += glyphIncrement) {
-
- int charOffset = layoutData[glyphIdx].originalOffset / sizeof(UniChar);
- const int fontIdx = nfo->mappedFonts[charOffset];
-
- ATSGlyphRef glyphId = layoutData[glyphIdx].glyphID;
-
- QFixed yAdvance = FixedToQFixed(baselineDeltas[glyphIdx]);
- QFixed xAdvance = FixedToQFixed(layoutData[glyphIdx + 1].realPos - layoutData[glyphIdx].realPos);
-
- if (nfo->styleStrategy & QFont::ForceIntegerMetrics) {
- yAdvance = yAdvance.round();
- xAdvance = xAdvance.round();
- }
-
- if (glyphId != 0xffff || i == 0) {
- if (i < nfo->glyphs->numGlyphs)
- {
- nfo->glyphs->glyphs[i] = (glyphId & 0x00ffffff) | (fontIdx << 24);
-
- nfo->glyphs->advances_y[i] = yAdvance;
- nfo->glyphs->advances_x[i] = xAdvance;
- }
- } else {
- // ATSUI gives us 0xffff as glyph id at the index in the glyph array for
- // a character position that maps to a ligtature. Such a glyph id does not
- // result in any visual glyph, but it may have an advance, which is why we
- // sum up the glyph advances.
- --i;
- nfo->glyphs->advances_y[i] += yAdvance;
- nfo->glyphs->advances_x[i] += xAdvance;
- *nfo->numGlyphs -= 1;
- }
-
- if (item->log_clusters) {
- if (charOffset >= nextCharStop) {
- nfo->glyphs->attributes[i].clusterStart = true;
- currentClusterGlyph = i;
-
- ++nextCharStop;
- for (; nextCharStop < item->length; ++nextCharStop)
- if (item->charAttributes[item->from + nextCharStop].charStop)
- break;
- } else {
- if (currentClusterGlyph == -1)
- currentClusterGlyph = i;
- }
- item->log_clusters[charOffset] = currentClusterGlyph;
-
- // surrogate handling
- if (charOffset < item->length - 1) {
- QChar current = item->string[item->from + charOffset];
- QChar next = item->string[item->from + charOffset + 1];
- if (current.unicode() >= 0xd800 && current.unicode() < 0xdc00
- && next.unicode() >= 0xdc00 && next.unicode() < 0xe000) {
- item->log_clusters[charOffset + 1] = currentClusterGlyph;
- }
- }
- }
- }
-
- /*
- if (item) {
- qDebug() << "resulting logclusters:";
- for (int i = 0; i < item->length; ++i)
- qDebug() << "logClusters[" << i << "] =" << item->log_clusters[i];
- qDebug() << "clusterstarts:";
- for (int i = 0; i < *nfo->numGlyphs; ++i)
- qDebug() << "clusterStart[" << i << "] =" << nfo->glyphs[i].attributes.clusterStart;
- }
- */
-
- ATSUDirectReleaseLayoutDataArrayPtr(lineRef, kATSUDirectDataBaselineDeltaFixedArray,
- (void **) &baselineDeltas);
-
- ATSUDirectReleaseLayoutDataArrayPtr(lineRef, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
- (void **) &layoutData);
-
- *callbackStatus = kATSULayoutOperationCallbackStatusHandled;
- return noErr;
-}
-
-int QFontEngineMacMulti::fontIndexForFontID(ATSUFontID id) const
-{
- for (int i = 0; i < engines.count(); ++i) {
- if (engineAt(i)->fontID == id)
- return i;
- }
-
- QFontEngineMacMulti *that = const_cast<QFontEngineMacMulti *>(this);
- QFontEngineMac *fe = new QFontEngineMac(style, id, fontDef, that);
- fe->ref.ref();
- that->engines.append(fe);
- return engines.count() - 1;
-}
-
-bool QFontEngineMacMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
-{
- return stringToCMap(str, len, glyphs, nglyphs, flags, /*logClusters=*/0, /*charAttributes=*/0);
-}
-
-bool QFontEngineMacMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,
- unsigned short *logClusters, const HB_CharAttributes *charAttributes, QScriptItem *) const
-{
- if (*nglyphs < len) {
- *nglyphs = len;
- return false;
- }
-
- ShaperItem shaperItem;
- shaperItem.string = str;
- shaperItem.from = 0;
- shaperItem.length = len;
- shaperItem.glyphs = *glyphs;
- shaperItem.glyphs.numGlyphs = *nglyphs;
- shaperItem.flags = flags;
- shaperItem.log_clusters = logClusters;
- shaperItem.charAttributes = charAttributes;
-
- const int maxChars = qMax(1,
- int(SHRT_MAX / maxCharWidth())
- - 10 // subtract a few to be on the safe side
- );
- if (len < maxChars || !charAttributes)
- return stringToCMapInternal(str, len, glyphs, nglyphs, flags, &shaperItem);
-
- int charIdx = 0;
- int glyphIdx = 0;
- ShaperItem tmpItem = shaperItem;
-
- do {
- tmpItem.from = shaperItem.from + charIdx;
-
- int charCount = qMin(maxChars, len - charIdx);
-
- int lastWhitespace = tmpItem.from + charCount - 1;
- int lastSoftBreak = lastWhitespace;
- int lastCharStop = lastSoftBreak;
- for (int i = lastCharStop; i >= tmpItem.from; --i) {
- if (tmpItem.charAttributes[i].whiteSpace) {
- lastWhitespace = i;
- break;
- } if (tmpItem.charAttributes[i].lineBreakType != HB_NoBreak) {
- lastSoftBreak = i;
- } if (tmpItem.charAttributes[i].charStop) {
- lastCharStop = i;
- }
- }
- charCount = qMin(lastWhitespace, qMin(lastSoftBreak, lastCharStop)) - tmpItem.from + 1;
-
- int glyphCount = shaperItem.glyphs.numGlyphs - glyphIdx;
- if (glyphCount <= 0)
- return false;
- tmpItem.length = charCount;
- tmpItem.glyphs = shaperItem.glyphs.mid(glyphIdx, glyphCount);
- tmpItem.log_clusters = shaperItem.log_clusters + charIdx;
- if (!stringToCMapInternal(tmpItem.string + tmpItem.from, tmpItem.length,
- &tmpItem.glyphs, &glyphCount, flags,
- &tmpItem)) {
- *nglyphs = glyphIdx + glyphCount;
- return false;
- }
- for (int i = 0; i < charCount; ++i)
- tmpItem.log_clusters[i] += glyphIdx;
- glyphIdx += glyphCount;
- charIdx += charCount;
- } while (charIdx < len);
- *nglyphs = glyphIdx;
- glyphs->numGlyphs = glyphIdx;
-
- return true;
-}
-
-bool QFontEngineMacMulti::stringToCMapInternal(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,ShaperItem *shaperItem) const
-{
- //qDebug() << "stringToCMap" << QString(str, len);
-
- OSStatus e = noErr;
-
- e = ATSUSetTextPointerLocation(textLayout, (UniChar *)(str), 0, len, len);
- if (e != noErr) {
- qWarning("Qt: internal: %ld: Error ATSUSetTextPointerLocation %s: %d", long(e), __FILE__, __LINE__);
- return false;
- }
-
- QGlyphLayoutInfo nfo;
- nfo.glyphs = glyphs;
- nfo.numGlyphs = nglyphs;
- nfo.callbackCalled = false;
- nfo.flags = flags;
- nfo.shaperItem = shaperItem;
- nfo.styleStrategy = fontDef.styleStrategy;
-
- int prevNumGlyphs = *nglyphs;
-
- QVarLengthArray<int> mappedFonts(len);
- for (int i = 0; i < len; ++i)
- mappedFonts[i] = 0;
- nfo.mappedFonts = mappedFonts.data();
-
- Q_ASSERT(sizeof(void *) <= sizeof(URefCon));
- e = ATSUSetTextLayoutRefCon(textLayout, (URefCon)&nfo);
- if (e != noErr) {
- qWarning("Qt: internal: %ld: Error ATSUSetTextLayoutRefCon %s: %d", long(e), __FILE__, __LINE__);
- return false;
- }
-
- {
- const int maxAttributeCount = 3;
- ATSUAttributeTag tags[maxAttributeCount + 1];
- ByteCount sizes[maxAttributeCount + 1];
- ATSUAttributeValuePtr values[maxAttributeCount + 1];
- int attributeCount = 0;
-
- tags[attributeCount] = kATSULineLayoutOptionsTag;
- ATSLineLayoutOptions layopts = kATSLineHasNoOpticalAlignment
- | kATSLineIgnoreFontLeading
- | kATSLineNoSpecialJustification // we do kashidas ourselves
- | kATSLineDisableAllJustification
- ;
-
- if (fontDef.styleStrategy & QFont::NoAntialias)
- layopts |= kATSLineNoAntiAliasing;
-
- if (!kerning)
- layopts |= kATSLineDisableAllKerningAdjustments;
-
- values[attributeCount] = &layopts;
- sizes[attributeCount] = sizeof(layopts);
- ++attributeCount;
-
- tags[attributeCount] = kATSULayoutOperationOverrideTag;
- ATSULayoutOperationOverrideSpecifier spec;
- spec.operationSelector = kATSULayoutOperationPostLayoutAdjustment;
- spec.overrideUPP = atsuPostLayoutCallback;
- values[attributeCount] = &spec;
- sizes[attributeCount] = sizeof(spec);
- ++attributeCount;
-
- // CTWritingDirection
- Boolean direction;
- if (flags & QTextEngine::RightToLeft)
- direction = kATSURightToLeftBaseDirection;
- else
- direction = kATSULeftToRightBaseDirection;
- tags[attributeCount] = kATSULineDirectionTag;
- values[attributeCount] = &direction;
- sizes[attributeCount] = sizeof(direction);
- ++attributeCount;
-
- Q_ASSERT(attributeCount < maxAttributeCount + 1);
- e = ATSUSetLayoutControls(textLayout, attributeCount, tags, sizes, values);
- if (e != noErr) {
- qWarning("Qt: internal: %ld: Error ATSUSetLayoutControls %s: %d", long(e), __FILE__, __LINE__);
- return false;
- }
-
- }
-
- e = ATSUSetRunStyle(textLayout, style, 0, len);
- if (e != noErr) {
- qWarning("Qt: internal: %ld: Error ATSUSetRunStyle %s: %d", long(e), __FILE__, __LINE__);
- return false;
- }
-
- if (!(fontDef.styleStrategy & QFont::NoFontMerging)) {
- int pos = 0;
- do {
- ATSUFontID substFont = 0;
- UniCharArrayOffset changedOffset = 0;
- UniCharCount changeCount = 0;
-
- e = ATSUMatchFontsToText(textLayout, pos, len - pos,
- &substFont, &changedOffset,
- &changeCount);
- if (e == kATSUFontsMatched) {
- int fontIdx = fontIndexForFontID(substFont);
- for (uint i = 0; i < changeCount; ++i)
- mappedFonts[changedOffset + i] = fontIdx;
- pos = changedOffset + changeCount;
- ATSUSetRunStyle(textLayout, engineAt(fontIdx)->style, changedOffset, changeCount);
- } else if (e == kATSUFontsNotMatched) {
- pos = changedOffset + changeCount;
- }
- } while (pos < len && e != noErr);
- }
- { // trigger the a layout
- // CFAttributedStringCreate, CTFramesetterCreateWithAttributedString (or perhaps Typesetter)
- Rect rect;
- e = ATSUMeasureTextImage(textLayout, kATSUFromTextBeginning, kATSUToTextEnd,
- /*iLocationX =*/ 0, /*iLocationY =*/ 0,
- &rect);
- if (e != noErr) {
- qWarning("Qt: internal: %ld: Error ATSUMeasureTextImage %s: %d", long(e), __FILE__, __LINE__);
- return false;
- }
- }
-
- if (!nfo.callbackCalled) {
- qWarning("Qt: internal: %ld: Error ATSUMeasureTextImage did not trigger callback %s: %d", long(e), __FILE__, __LINE__);
- return false;
- }
-
- ATSUClearLayoutCache(textLayout, kATSUFromTextBeginning);
- if (prevNumGlyphs < *nfo.numGlyphs)
- return false;
- return true;
-}
-
-void QFontEngineMacMulti::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
-{
- Q_ASSERT(false);
- Q_UNUSED(glyphs);
- Q_UNUSED(flags);
-}
-
-void QFontEngineMacMulti::doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const
-{
- //Q_ASSERT(false);
-}
-
-void QFontEngineMacMulti::loadEngine(int /*at*/)
-{
- // should never be called!
- Q_ASSERT(false);
-}
-
-bool QFontEngineMacMulti::canRender(const QChar *string, int len)
-{
- ATSUSetTextPointerLocation(textLayout, reinterpret_cast<const UniChar *>(string), 0, len, len);
- ATSUSetRunStyle(textLayout, style, 0, len);
-
- OSStatus e = noErr;
- int pos = 0;
- do {
- FMFont substFont = 0;
- UniCharArrayOffset changedOffset = 0;
- UniCharCount changeCount = 0;
-
- // CTFontCreateForString
- e = ATSUMatchFontsToText(textLayout, pos, len - pos,
- &substFont, &changedOffset,
- &changeCount);
- if (e == kATSUFontsMatched) {
- pos = changedOffset + changeCount;
- } else if (e == kATSUFontsNotMatched) {
- break;
- }
- } while (pos < len && e != noErr);
-
- return e == noErr || e == kATSUFontsMatched;
-}
-
-QFontEngineMac::QFontEngineMac(ATSUStyle baseStyle, ATSUFontID fontID, const QFontDef &def, QFontEngineMacMulti *multiEngine)
- : fontID(fontID), multiEngine(multiEngine), cmap(0), symbolCMap(false)
-{
- fontDef = def;
- ATSUCreateAndCopyStyle(baseStyle, &style);
- ATSFontRef atsFont = FMGetATSFontRefFromFont(fontID);
- cgFont = CGFontCreateWithPlatformFont(&atsFont);
-
- const int maxAttributeCount = 4;
- ATSUAttributeTag tags[maxAttributeCount + 1];
- ByteCount sizes[maxAttributeCount + 1];
- ATSUAttributeValuePtr values[maxAttributeCount + 1];
- int attributeCount = 0;
-
- synthesisFlags = 0;
-
- // synthesizing using CG is not recommended
- quint16 macStyle = 0;
- {
- uchar data[4];
- ByteCount len = 4;
- if (ATSFontGetTable(atsFont, MAKE_TAG('h', 'e', 'a', 'd'), 44, 4, &data, &len) == noErr)
- macStyle = qFromBigEndian<quint16>(data);
- }
-
- Boolean atsuBold = false;
- Boolean atsuItalic = false;
- if (fontDef.weight >= QFont::Bold) {
- if (!(macStyle & 1)) {
- synthesisFlags |= SynthesizedBold;
- atsuBold = true;
- tags[attributeCount] = kATSUQDBoldfaceTag;
- sizes[attributeCount] = sizeof(atsuBold);
- values[attributeCount] = &atsuBold;
- ++attributeCount;
- }
- }
- if (fontDef.style != QFont::StyleNormal) {
- if (!(macStyle & 2)) {
- synthesisFlags |= SynthesizedItalic;
- atsuItalic = true;
- tags[attributeCount] = kATSUQDItalicTag;
- sizes[attributeCount] = sizeof(atsuItalic);
- values[attributeCount] = &atsuItalic;
- ++attributeCount;
- }
- }
-
- tags[attributeCount] = kATSUFontTag;
- values[attributeCount] = &fontID;
- sizes[attributeCount] = sizeof(fontID);
- ++attributeCount;
-
- Q_ASSERT(attributeCount < maxAttributeCount + 1);
- OSStatus err = ATSUSetAttributes(style, attributeCount, tags, sizes, values);
- Q_ASSERT(err == noErr);
- Q_UNUSED(err);
-
- // CTFontCopyTable
- quint16 tmpFsType;
- if (ATSFontGetTable(atsFont, MAKE_TAG('O', 'S', '/', '2'), 8, 2, &tmpFsType, 0) == noErr)
- fsType = qFromBigEndian<quint16>(tmpFsType);
- else
- fsType = 0;
-
- if (multiEngine)
- transform = multiEngine->transform;
- else
- transform = CGAffineTransformIdentity;
-
- ATSUTextMeasurement metric;
-
- ATSUGetAttribute(style, kATSUAscentTag, sizeof(metric), &metric, 0);
- m_ascent = FixRound(metric);
-
- ATSUGetAttribute(style, kATSUDescentTag, sizeof(metric), &metric, 0);
- m_descent = FixRound(metric);
-
- ATSUGetAttribute(style, kATSULeadingTag, sizeof(metric), &metric, 0);
- m_leading = FixRound(metric);
-
- ATSFontMetrics metrics;
-
- ATSFontGetHorizontalMetrics(FMGetATSFontRefFromFont(fontID), kATSOptionFlagsDefault, &metrics);
- m_maxCharWidth = metrics.maxAdvanceWidth * fontDef.pointSize;
-
- ATSFontGetHorizontalMetrics(FMGetATSFontRefFromFont(fontID), kATSOptionFlagsDefault, &metrics);
- m_xHeight = QFixed::fromReal(metrics.xHeight * fontDef.pointSize);
-
- ATSFontGetHorizontalMetrics(FMGetATSFontRefFromFont(fontID), kATSOptionFlagsDefault, &metrics);
- m_averageCharWidth = QFixed::fromReal(metrics.avgAdvanceWidth * fontDef.pointSize);
-
- // Use width of 'X' if ATSFontGetHorizontalMetrics returns 0 for avgAdvanceWidth.
- if (m_averageCharWidth == QFixed(0)) {
- QChar c('X');
- QGlyphLayoutArray<1> glyphs;
- int nglyphs = 1;
- stringToCMap(&c, 1, &glyphs, &nglyphs, 0);
- glyph_metrics_t metrics = boundingBox(glyphs);
- m_averageCharWidth = metrics.width;
- }
-}
-
-QFontEngineMac::~QFontEngineMac()
-{
- ATSUDisposeStyle(style);
-}
-
-static inline unsigned int getChar(const QChar *str, int &i, const int len)
-{
- unsigned int uc = str[i].unicode();
- if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {
- uint low = str[i+1].unicode();
- if (low >= 0xdc00 && low < 0xe000) {
- uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
- ++i;
- }
- }
- return uc;
-}
-
-// Not used directly for shaping, only used to calculate m_averageCharWidth
-bool QFontEngineMac::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
-{
- if (!cmap) {
- cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p'));
- int size = 0;
- cmap = getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()), cmapTable.size(), &symbolCMap, &size);
- if (!cmap)
- return false;
- }
- if (symbolCMap) {
- for (int i = 0; i < len; ++i) {
- unsigned int uc = getChar(str, i, len);
- glyphs->glyphs[i] = getTrueTypeGlyphIndex(cmap, uc);
- if(!glyphs->glyphs[i] && uc < 0x100)
- glyphs->glyphs[i] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
- }
- } else {
- for (int i = 0; i < len; ++i) {
- unsigned int uc = getChar(str, i, len);
- glyphs->glyphs[i] = getTrueTypeGlyphIndex(cmap, uc);
- }
- }
-
- *nglyphs = len;
- glyphs->numGlyphs = *nglyphs;
-
- if (!(flags & QTextEngine::GlyphIndicesOnly))
- recalcAdvances(glyphs, flags);
-
- return true;
-}
-
-void QFontEngineMac::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
-{
- Q_UNUSED(flags)
-
- QVarLengthArray<GlyphID> atsuGlyphs(glyphs->numGlyphs);
- for (int i = 0; i < glyphs->numGlyphs; ++i)
- atsuGlyphs[i] = glyphs->glyphs[i];
-
- QVarLengthArray<ATSGlyphScreenMetrics> metrics(glyphs->numGlyphs);
-
- ATSUGlyphGetScreenMetrics(style, glyphs->numGlyphs, atsuGlyphs.data(), sizeof(GlyphID),
- /* iForcingAntiAlias =*/ false,
- /* iAntiAliasSwitch =*/true,
- metrics.data());
-
- for (int i = 0; i < glyphs->numGlyphs; ++i) {
- glyphs->advances_x[i] = QFixed::fromReal(metrics[i].deviceAdvance.x);
- glyphs->advances_y[i] = QFixed::fromReal(metrics[i].deviceAdvance.y);
-
- if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
- glyphs->advances_x[i] = glyphs->advances_x[i].round();
- glyphs->advances_y[i] = glyphs->advances_y[i].round();
- }
- }
-}
-
-glyph_metrics_t QFontEngineMac::boundingBox(const QGlyphLayout &glyphs)
-{
- QFixed w;
- bool round = fontDef.styleStrategy & QFont::ForceIntegerMetrics;
- for (int i = 0; i < glyphs.numGlyphs; ++i) {
- w += round ? glyphs.effectiveAdvance(i).round()
- : glyphs.effectiveAdvance(i);
- }
- return glyph_metrics_t(0, -(ascent()), w - lastRightBearing(glyphs, round), ascent()+descent(), w, 0);
-}
-
-glyph_metrics_t QFontEngineMac::boundingBox(glyph_t glyph)
-{
- GlyphID atsuGlyph = glyph;
-
- ATSGlyphScreenMetrics metrics;
-
- ATSUGlyphGetScreenMetrics(style, 1, &atsuGlyph, 0,
- /* iForcingAntiAlias =*/ false,
- /* iAntiAliasSwitch =*/true,
- &metrics);
-
- // ### check again
-
- glyph_metrics_t gm;
- gm.width = int(metrics.width);
- gm.height = int(metrics.height);
- gm.x = QFixed::fromReal(metrics.topLeft.x);
- gm.y = -QFixed::fromReal(metrics.topLeft.y);
- gm.xoff = QFixed::fromReal(metrics.deviceAdvance.x);
- gm.yoff = QFixed::fromReal(metrics.deviceAdvance.y);
-
- if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
- gm.x = gm.x.floor();
- gm.y = gm.y.floor();
- gm.xoff = gm.xoff.round();
- gm.yoff = gm.yoff.round();
- }
-
- return gm;
-}
-
-QFixed QFontEngineMac::ascent() const
-{
- return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? m_ascent.round()
- : m_ascent;
-}
-
-QFixed QFontEngineMac::descent() const
-{
- // subtract a pixel to even out the historical +1 in QFontMetrics::height().
- // Fix in Qt 5.
- return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? m_descent.round() - 1
- : m_descent;
-}
-
-QFixed QFontEngineMac::leading() const
-{
- return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? m_leading.round()
- : m_leading;
-}
-
-qreal QFontEngineMac::maxCharWidth() const
-{
- return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? qRound(m_maxCharWidth)
- : m_maxCharWidth;
-}
-
-QFixed QFontEngineMac::xHeight() const
-{
- return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? m_xHeight.round()
- : m_xHeight;
-}
-
-QFixed QFontEngineMac::averageCharWidth() const
-{
- return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? m_averageCharWidth.round()
- : m_averageCharWidth;
-}
-
-static void addGlyphsToPathHelper(ATSUStyle style, glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, QPainterPath *path)
-{
- if (!numGlyphs)
- return;
-
- OSStatus e;
-
- QMacFontPath fontpath(0, 0, path);
- ATSCubicMoveToUPP moveTo = NewATSCubicMoveToUPP(QMacFontPath::moveTo);
- ATSCubicLineToUPP lineTo = NewATSCubicLineToUPP(QMacFontPath::lineTo);
- ATSCubicCurveToUPP cubicTo = NewATSCubicCurveToUPP(QMacFontPath::cubicTo);
- ATSCubicClosePathUPP closePath = NewATSCubicClosePathUPP(QMacFontPath::closePath);
-
- // CTFontCreatePathForGlyph
- for (int i = 0; i < numGlyphs; ++i) {
- GlyphID glyph = glyphs[i];
-
- fontpath.setPosition(positions[i].x.toReal(), positions[i].y.toReal());
- ATSUGlyphGetCubicPaths(style, glyph, moveTo, lineTo,
- cubicTo, closePath, &fontpath, &e);
- }
-
- DisposeATSCubicMoveToUPP(moveTo);
- DisposeATSCubicLineToUPP(lineTo);
- DisposeATSCubicCurveToUPP(cubicTo);
- DisposeATSCubicClosePathUPP(closePath);
-}
-
-void QFontEngineMac::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, QPainterPath *path,
- QTextItem::RenderFlags)
-{
- addGlyphsToPathHelper(style, glyphs, positions, numGlyphs, path);
-}
-
-
-/*!
- Helper function for alphaMapForGlyph and alphaRGBMapForGlyph. The two are identical, except for
- the subpixel antialiasing...
-*/
-QImage QFontEngineMac::imageForGlyph(glyph_t glyph, int margin, bool colorful)
-{
- const glyph_metrics_t br = boundingBox(glyph);
- QImage im(qRound(br.width)+2, qRound(br.height)+4, QImage::Format_RGB32);
- im.fill(0xff000000);
-
- CGColorSpaceRef colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace();
- uint cgflags = kCGImageAlphaNoneSkipFirst;
-#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
- cgflags |= kCGBitmapByteOrder32Host;
-#endif
- CGContextRef ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(),
- 8, im.bytesPerLine(), colorspace,
- cgflags);
- CGContextSetFontSize(ctx, fontDef.pixelSize);
- CGContextSetShouldAntialias(ctx, fontDef.pointSize > qt_antialiasing_threshold && !(fontDef.styleStrategy & QFont::NoAntialias));
- // turn off sub-pixel hinting - no support for that in OpenGL
- CGContextSetShouldSmoothFonts(ctx, colorful);
- CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx);
- CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0);
- CGAffineTransformConcat(cgMatrix, oldTextMatrix);
-
- if (synthesisFlags & QFontEngine::SynthesizedItalic)
- cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, tanf(14 * acosf(0) / 90), 1, 0, 0));
-
- cgMatrix = CGAffineTransformConcat(cgMatrix, transform);
-
- CGContextSetTextMatrix(ctx, cgMatrix);
- CGContextSetRGBFillColor(ctx, 1, 1, 1, 1);
- CGContextSetTextDrawingMode(ctx, kCGTextFill);
- CGContextSetFont(ctx, cgFont);
-
- qreal pos_x = -br.x.toReal() + 1;
- qreal pos_y = im.height() + br.y.toReal() - 2;
- CGContextSetTextPosition(ctx, pos_x, pos_y);
-
- CGSize advance;
- advance.width = 0;
- advance.height = 0;
- CGGlyph cgGlyph = glyph;
- CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1);
-
- if (synthesisFlags & QFontEngine::SynthesizedBold) {
- CGContextSetTextPosition(ctx, pos_x + 0.5 * lineThickness().toReal(), pos_y);
- CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1);
- }
-
- CGContextRelease(ctx);
-
- return im;
-}
-
-QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph)
-{
- QImage im = imageForGlyph(glyph, 2, false);
-
- QImage indexed(im.width(), im.height(), QImage::Format_Indexed8);
- QVector<QRgb> colors(256);
- for (int i=0; i<256; ++i)
- colors[i] = qRgba(0, 0, 0, i);
- indexed.setColorTable(colors);
-
- for (int y=0; y<im.height(); ++y) {
- uint *src = (uint*) im.scanLine(y);
- uchar *dst = indexed.scanLine(y);
- for (int x=0; x<im.width(); ++x) {
- *dst = qGray(*src);
- ++dst;
- ++src;
- }
- }
-
- return indexed;
-}
-
-QImage QFontEngineMac::alphaRGBMapForGlyph(glyph_t glyph, QFixed, int margin, const QTransform &t)
-{
- QImage im = imageForGlyph(glyph, margin, true);
-
- if (t.type() >= QTransform::TxScale) {
- im = im.transformed(t);
- }
-
- qGamma_correct_back_to_linear_cs(&im);
-
- return im;
-}
-
-
-bool QFontEngineMac::canRender(const QChar *string, int len)
-{
- Q_ASSERT(false);
- Q_UNUSED(string);
- Q_UNUSED(len);
- return false;
-}
-
-void QFontEngineMac::draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight)
-{
- QVarLengthArray<QFixedPoint> positions;
- QVarLengthArray<glyph_t> glyphs;
- QTransform matrix;
- matrix.translate(x, y);
- getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
- if (glyphs.size() == 0)
- return;
-
- CGContextSetFontSize(ctx, fontDef.pixelSize);
-
- CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx);
-
- CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, -1, 0, -paintDeviceHeight);
-
- CGAffineTransformConcat(cgMatrix, oldTextMatrix);
-
- if (synthesisFlags & QFontEngine::SynthesizedItalic)
- cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0));
-
- cgMatrix = CGAffineTransformConcat(cgMatrix, transform);
-
- CGContextSetTextMatrix(ctx, cgMatrix);
-
- CGContextSetTextDrawingMode(ctx, kCGTextFill);
-
-
- QVarLengthArray<CGSize> advances(glyphs.size());
- QVarLengthArray<CGGlyph> cgGlyphs(glyphs.size());
-
- for (int i = 0; i < glyphs.size() - 1; ++i) {
- advances[i].width = (positions[i + 1].x - positions[i].x).toReal();
- advances[i].height = (positions[i + 1].y - positions[i].y).toReal();
- cgGlyphs[i] = glyphs[i];
- }
- advances[glyphs.size() - 1].width = 0;
- advances[glyphs.size() - 1].height = 0;
- cgGlyphs[glyphs.size() - 1] = glyphs[glyphs.size() - 1];
-
- CGContextSetFont(ctx, cgFont);
-
- CGContextSetTextPosition(ctx, positions[0].x.toReal(), positions[0].y.toReal());
-
- CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size());
-
- if (synthesisFlags & QFontEngine::SynthesizedBold) {
- CGContextSetTextPosition(ctx, positions[0].x.toReal() + 0.5 * lineThickness().toReal(),
- positions[0].y.toReal());
-
- CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size());
- }
-
- CGContextSetTextMatrix(ctx, oldTextMatrix);
-}
-
-QFontEngine::FaceId QFontEngineMac::faceId() const
-{
- FaceId ret;
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
-if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
- // CTFontGetPlatformFont
- FSRef ref;
- if (ATSFontGetFileReference(FMGetATSFontRefFromFont(fontID), &ref) != noErr)
- return ret;
- ret.filename = QByteArray(128, 0);
- ret.index = fontID;
- FSRefMakePath(&ref, (UInt8 *)ret.filename.data(), ret.filename.size());
-}else
-#endif
-{
- FSSpec spec;
- if (ATSFontGetFileSpecification(FMGetATSFontRefFromFont(fontID), &spec) != noErr)
- return ret;
-
- FSRef ref;
- FSpMakeFSRef(&spec, &ref);
- ret.filename = QByteArray(128, 0);
- ret.index = fontID;
- FSRefMakePath(&ref, (UInt8 *)ret.filename.data(), ret.filename.size());
-}
- return ret;
-}
-
-QByteArray QFontEngineMac::getSfntTable(uint tag) const
-{
- ATSFontRef atsFont = FMGetATSFontRefFromFont(fontID);
-
- ByteCount length;
- OSStatus status = ATSFontGetTable(atsFont, tag, 0, 0, 0, &length);
- if (status != noErr)
- return QByteArray();
- QByteArray table(length, 0);
- // CTFontCopyTable
- status = ATSFontGetTable(atsFont, tag, 0, table.length(), table.data(), &length);
- if (status != noErr)
- return QByteArray();
- return table;
-}
-
-QFontEngine::Properties QFontEngineMac::properties() const
-{
- QFontEngine::Properties props;
- ATSFontRef atsFont = FMGetATSFontRefFromFont(fontID);
- quint16 tmp;
- // CTFontGetUnitsPerEm
- if (ATSFontGetTable(atsFont, MAKE_TAG('h', 'e', 'a', 'd'), 18, 2, &tmp, 0) == noErr)
- props.emSquare = qFromBigEndian<quint16>(tmp);
- struct {
- qint16 xMin;
- qint16 yMin;
- qint16 xMax;
- qint16 yMax;
- } bbox;
- bbox.xMin = bbox.xMax = bbox.yMin = bbox.yMax = 0;
- // CTFontGetBoundingBox
- if (ATSFontGetTable(atsFont, MAKE_TAG('h', 'e', 'a', 'd'), 36, 8, &bbox, 0) == noErr) {
- bbox.xMin = qFromBigEndian<quint16>(bbox.xMin);
- bbox.yMin = qFromBigEndian<quint16>(bbox.yMin);
- bbox.xMax = qFromBigEndian<quint16>(bbox.xMax);
- bbox.yMax = qFromBigEndian<quint16>(bbox.yMax);
- }
- struct {
- qint16 ascender;
- qint16 descender;
- qint16 linegap;
- } metrics;
- metrics.ascender = metrics.descender = metrics.linegap = 0;
- // CTFontGetAscent, etc.
- if (ATSFontGetTable(atsFont, MAKE_TAG('h', 'h', 'e', 'a'), 4, 6, &metrics, 0) == noErr) {
- metrics.ascender = qFromBigEndian<quint16>(metrics.ascender);
- metrics.descender = qFromBigEndian<quint16>(metrics.descender);
- metrics.linegap = qFromBigEndian<quint16>(metrics.linegap);
- }
- props.ascent = metrics.ascender;
- props.descent = -metrics.descender;
- props.leading = metrics.linegap;
- props.boundingBox = QRectF(bbox.xMin, -bbox.yMax,
- bbox.xMax - bbox.xMin,
- bbox.yMax - bbox.yMin);
- props.italicAngle = 0;
- props.capHeight = props.ascent;
-
- qint16 lw = 0;
- // fonts lie
- if (ATSFontGetTable(atsFont, MAKE_TAG('p', 'o', 's', 't'), 10, 2, &lw, 0) == noErr)
- lw = qFromBigEndian<quint16>(lw);
- props.lineWidth = lw;
-
- // CTFontCopyPostScriptName
- QCFString psName;
- if (ATSFontGetPostScriptName(FMGetATSFontRefFromFont(fontID), kATSOptionFlagsDefault, &psName) == noErr)
- props.postscriptName = QString(psName).toUtf8();
- props.postscriptName = QFontEngine::convertToPostscriptFontFamilyName(props.postscriptName);
- return props;
-}
-
-void QFontEngineMac::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics)
-{
- ATSUStyle unscaledStyle;
- ATSUCreateAndCopyStyle(style, &unscaledStyle);
-
- int emSquare = properties().emSquare.toInt();
-
- const int maxAttributeCount = 4;
- ATSUAttributeTag tags[maxAttributeCount + 1];
- ByteCount sizes[maxAttributeCount + 1];
- ATSUAttributeValuePtr values[maxAttributeCount + 1];
- int attributeCount = 0;
-
- Fixed size = FixRatio(emSquare, 1);
- tags[attributeCount] = kATSUSizeTag;
- sizes[attributeCount] = sizeof(size);
- values[attributeCount] = &size;
- ++attributeCount;
-
- Q_ASSERT(attributeCount < maxAttributeCount + 1);
- OSStatus err = ATSUSetAttributes(unscaledStyle, attributeCount, tags, sizes, values);
- Q_ASSERT(err == noErr);
- Q_UNUSED(err);
-
- // various CTFont metrics functions: CTFontGetBoundingRectsForGlyphs, CTFontGetAdvancesForGlyphs
- GlyphID atsuGlyph = glyph;
- ATSGlyphScreenMetrics atsuMetrics;
- ATSUGlyphGetScreenMetrics(unscaledStyle, 1, &atsuGlyph, 0,
- /* iForcingAntiAlias =*/ false,
- /* iAntiAliasSwitch =*/true,
- &atsuMetrics);
-
- metrics->width = int(atsuMetrics.width);
- metrics->height = int(atsuMetrics.height);
- metrics->x = QFixed::fromReal(atsuMetrics.topLeft.x);
- metrics->y = -QFixed::fromReal(atsuMetrics.topLeft.y);
- metrics->xoff = QFixed::fromReal(atsuMetrics.deviceAdvance.x);
- metrics->yoff = QFixed::fromReal(atsuMetrics.deviceAdvance.y);
-
- QFixedPoint p;
- addGlyphsToPathHelper(unscaledStyle, &glyph, &p, 1, path);
-
- ATSUDisposeStyle(unscaledStyle);
-}
-#endif // !QT_MAC_USE_COCOA
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfontengine_mac_p.h b/src/gui/text/qfontengine_mac_p.h
deleted file mode 100644
index 10561e54d6..0000000000
--- a/src/gui/text/qfontengine_mac_p.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFONTENGINE_MAC_P_H
-#define QFONTENGINE_MAC_P_H
-
-#include <private/qfontengine_p.h>
-
-#ifndef QT_MAC_USE_COCOA
-class QFontEngineMacMulti;
-class QFontEngineMac : public QFontEngine
-{
- friend class QFontEngineMacMulti;
-public:
- QFontEngineMac(ATSUStyle baseStyle, ATSUFontID fontID, const QFontDef &def, QFontEngineMacMulti *multiEngine = 0);
- virtual ~QFontEngineMac();
-
- virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *numGlyphs, QTextEngine::ShaperFlags flags) const;
- virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
-
- virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
- virtual glyph_metrics_t boundingBox(glyph_t glyph);
-
- virtual QFixed ascent() const;
- virtual QFixed descent() const;
- virtual QFixed leading() const;
- virtual QFixed xHeight() const;
- virtual qreal maxCharWidth() const;
- virtual QFixed averageCharWidth() const;
-
- virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs,
- QPainterPath *path, QTextItem::RenderFlags);
-
- virtual const char *name() const { return "QFontEngineMac"; }
-
- virtual bool canRender(const QChar *string, int len);
-
- virtual int synthesized() const { return synthesisFlags; }
-
- virtual Type type() const { return QFontEngine::Mac; }
-
- void draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight);
-
- virtual FaceId faceId() const;
- virtual QByteArray getSfntTable(uint tag) const;
- virtual Properties properties() const;
- virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
- virtual QImage alphaMapForGlyph(glyph_t);
- virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t);
-
-private:
- QImage imageForGlyph(glyph_t glyph, int margin, bool colorful);
-
- ATSUFontID fontID;
- QCFType<CGFontRef> cgFont;
- ATSUStyle style;
- int synthesisFlags;
- mutable QGlyphLayout kashidaGlyph;
- QFontEngineMacMulti *multiEngine;
- mutable const unsigned char *cmap;
- mutable bool symbolCMap;
- mutable QByteArray cmapTable;
- CGAffineTransform transform;
- QFixed m_ascent;
- QFixed m_descent;
- QFixed m_leading;
- qreal m_maxCharWidth;
- QFixed m_xHeight;
- QFixed m_averageCharWidth;
-};
-
-class QFontEngineMacMulti : public QFontEngineMulti
-{
- friend class QFontEngineMac;
-public:
- // internal
- struct ShaperItem
- {
- inline ShaperItem() : string(0), from(0), length(0),
- log_clusters(0), charAttributes(0) {}
-
- const QChar *string;
- int from;
- int length;
- QGlyphLayout glyphs;
- unsigned short *log_clusters;
- const HB_CharAttributes *charAttributes;
- QTextEngine::ShaperFlags flags;
- };
-
- QFontEngineMacMulti(const ATSFontFamilyRef &atsFamily, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool kerning);
- virtual ~QFontEngineMacMulti();
-
- virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
- bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,
- unsigned short *logClusters, const HB_CharAttributes *charAttributes, QScriptItem *) const;
-
- virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
- virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const;
-
- virtual const char *name() const { return "ATSUI"; }
-
- virtual bool canRender(const QChar *string, int len);
-
- inline ATSUFontID macFontID() const { return fontID; }
-
-protected:
- virtual void loadEngine(int at);
-
-private:
- inline const QFontEngineMac *engineAt(int i) const
- { return static_cast<const QFontEngineMac *>(engines.at(i)); }
-
- bool stringToCMapInternal(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags, ShaperItem *item) const;
-
- int fontIndexForFontID(ATSUFontID id) const;
-
- ATSUFontID fontID;
- uint kerning : 1;
-
- mutable ATSUTextLayout textLayout;
- mutable ATSUStyle style;
- CGAffineTransform transform;
-};
-#endif //!QT_MAC_USE_COCOA
-
-#endif // QFONTENGINE_MAC_P_H
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index 5f779e155a..b32e6916f0 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -394,7 +394,7 @@ private:
int _size;
};
-class QFontEngineMulti : public QFontEngine
+class Q_GUI_EXPORT QFontEngineMulti : public QFontEngine
{
public:
explicit QFontEngineMulti(int engineCount);
@@ -417,6 +417,10 @@ public:
virtual QFixed xHeight() const;
virtual QFixed averageCharWidth() const;
virtual QImage alphaMapForGlyph(glyph_t);
+ virtual QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition);
+ virtual QImage alphaMapForGlyph(glyph_t, const QTransform &t);
+ virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
+ virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t);
virtual QFixed lineThickness() const;
virtual QFixed underlinePosition() const;
diff --git a/src/gui/text/qfontengine_qpa.cpp b/src/gui/text/qfontengine_qpa.cpp
index cb1e7d6830..6fd85150e3 100644
--- a/src/gui/text/qfontengine_qpa.cpp
+++ b/src/gui/text/qfontengine_qpa.cpp
@@ -46,7 +46,6 @@
#include <QtCore/QDir>
#include <QtCore/QBuffer>
-#include <QtGui/private/qapplication_p.h>
#include <QtGui/QPlatformFontDatabase>
#include <QtGui/private/qpaintengine_raster_p.h>
@@ -667,9 +666,11 @@ QFontEngineMultiQPA::QFontEngineMultiQPA(QFontEngine *fe, int _script, const QSt
: QFontEngineMulti(fallbacks.size() + 1),
fallbackFamilies(fallbacks), script(_script)
{
+ Q_ASSERT(fe && fe->type() != QFontEngine::Multi);
engines[0] = fe;
fe->ref.ref();
fontDef = engines[0]->fontDef;
+ setObjectName(QStringLiteral("QFontEngineMultiQPA"));
}
void QFontEngineMultiQPA::loadEngine(int at)
diff --git a/src/gui/text/qfontengine_qws.cpp b/src/gui/text/qfontengine_qws.cpp
deleted file mode 100644
index 4c6dff241d..0000000000
--- a/src/gui/text/qfontengine_qws.cpp
+++ /dev/null
@@ -1,665 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qfontengine_p.h"
-#include <private/qunicodetables_p.h>
-#include <qwsdisplay_qws.h>
-#include <qvarlengtharray.h>
-#include <private/qpainter_p.h>
-#include <private/qpaintengine_raster_p.h>
-#include <private/qpdf_p.h>
-#include "qtextengine_p.h"
-#include "private/qcore_unix_p.h" // overrides QT_OPEN
-
-#include <qdebug.h>
-
-
-#ifndef QT_NO_QWS_QPF
-
-#include "qfile.h"
-#include "qdir.h"
-
-#define QT_USE_MMAP
-#include <stdlib.h>
-
-#ifdef QT_USE_MMAP
-// for mmap
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <errno.h>
-
-# if defined(QT_LINUXBASE) && !defined(MAP_FILE)
- // LSB 3.2 does not define MAP_FILE
-# define MAP_FILE 0
-# endif
-
-#endif
-
-#endif // QT_NO_QWS_QPF
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_QWS_QPF
-QT_BEGIN_INCLUDE_NAMESPACE
-#include "qplatformdefs.h"
-QT_END_INCLUDE_NAMESPACE
-
-static inline unsigned int getChar(const QChar *str, int &i, const int len)
-{
- unsigned int uc = str[i].unicode();
- if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {
- uint low = str[i+1].unicode();
- if (low >= 0xdc00 && low < 0xe000) {
- uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
- ++i;
- }
- }
- return uc;
-}
-
-#define FM_SMOOTH 1
-
-
-class Q_PACKED QPFGlyphMetrics {
-
-public:
- quint8 linestep;
- quint8 width;
- quint8 height;
- quint8 flags;
-
- qint8 bearingx; // Difference from pen position to glyph's left bbox
- quint8 advance; // Difference between pen positions
- qint8 bearingy; // Used for putting characters on baseline
-
- qint8 reserved; // Do not use
-
- // Flags:
- // RendererOwnsData - the renderer is responsible for glyph data
- // memory deletion otherwise QPFGlyphTree must
- // delete [] the data when the glyph is deleted.
- enum Flags { RendererOwnsData=0x01 };
-};
-
-class QPFGlyph {
-public:
- QPFGlyph() { metrics=0; data=0; }
- QPFGlyph(QPFGlyphMetrics* m, uchar* d) :
- metrics(m), data(d) { }
- ~QPFGlyph() {}
-
- QPFGlyphMetrics* metrics;
- uchar* data;
-};
-
-struct Q_PACKED QPFFontMetrics{
- qint8 ascent,descent;
- qint8 leftbearing,rightbearing;
- quint8 maxwidth;
- qint8 leading;
- quint8 flags;
- quint8 underlinepos;
- quint8 underlinewidth;
- quint8 reserved3;
-};
-
-
-class QPFGlyphTree {
-public:
- /* reads in a tree like this:
-
- A-Z
- / \
- 0-9 a-z
-
- etc.
-
- */
- glyph_t min,max;
- QPFGlyphTree* less;
- QPFGlyphTree* more;
- QPFGlyph* glyph;
-public:
-#ifdef QT_USE_MMAP
- QPFGlyphTree(uchar*& data)
- {
- read(data);
- }
-#else
- QPFGlyphTree(QIODevice& f)
- {
- read(f);
- }
-#endif
-
- ~QPFGlyphTree()
- {
- // NOTE: does not delete glyph[*].metrics or .data.
- // the caller does this (only they know who owns
- // the data). See clear().
- delete less;
- delete more;
- delete [] glyph;
- }
-
- bool inFont(glyph_t g) const
- {
- if ( g < min ) {
- if ( !less )
- return false;
- return less->inFont(g);
- } else if ( g > max ) {
- if ( !more )
- return false;
- return more->inFont(g);
- }
- return true;
- }
-
- QPFGlyph* get(glyph_t g)
- {
- if ( g < min ) {
- if ( !less )
- return 0;
- return less->get(g);
- } else if ( g > max ) {
- if ( !more )
- return 0;
- return more->get(g);
- }
- return &glyph[g - min];
- }
- int totalChars() const
- {
- if ( !this ) return 0;
- return max-min+1 + less->totalChars() + more->totalChars();
- }
- int weight() const
- {
- if ( !this ) return 0;
- return 1 + less->weight() + more->weight();
- }
-
- void dump(int indent=0)
- {
- for (int i=0; i<indent; i++) printf(" ");
- printf("%d..%d",min,max);
- //if ( indent == 0 )
- printf(" (total %d)",totalChars());
- printf("\n");
- if ( less ) less->dump(indent+1);
- if ( more ) more->dump(indent+1);
- }
-
-private:
- QPFGlyphTree()
- {
- }
-
-#ifdef QT_USE_MMAP
- void read(uchar*& data)
- {
- // All node data first
- readNode(data);
- // Then all non-video data
- readMetrics(data);
- // Then all video data
- readData(data);
- }
-#else
- void read(QIODevice& f)
- {
- // All node data first
- readNode(f);
- // Then all non-video data
- readMetrics(f);
- // Then all video data
- readData(f);
- }
-#endif
-
-#ifdef QT_USE_MMAP
- void readNode(uchar*& data)
- {
- uchar rw = *data++;
- uchar cl = *data++;
- min = (rw << 8) | cl;
- rw = *data++;
- cl = *data++;
- max = (rw << 8) | cl;
- int flags = *data++;
- if ( flags & 1 )
- less = new QPFGlyphTree;
- else
- less = 0;
- if ( flags & 2 )
- more = new QPFGlyphTree;
- else
- more = 0;
- int n = max-min+1;
- glyph = new QPFGlyph[n];
-
- if ( less )
- less->readNode(data);
- if ( more )
- more->readNode(data);
- }
-#else
- void readNode(QIODevice& f)
- {
- char rw;
- char cl;
- f.getChar(&rw);
- f.getChar(&cl);
- min = (rw << 8) | cl;
- f.getChar(&rw);
- f.getChar(&cl);
- max = (rw << 8) | cl;
- char flags;
- f.getChar(&flags);
- if ( flags & 1 )
- less = new QPFGlyphTree;
- else
- less = 0;
- if ( flags & 2 )
- more = new QPFGlyphTree;
- else
- more = 0;
- int n = max-min+1;
- glyph = new QPFGlyph[n];
-
- if ( less )
- less->readNode(f);
- if ( more )
- more->readNode(f);
- }
-#endif
-
-#ifdef QT_USE_MMAP
- void readMetrics(uchar*& data)
- {
- int n = max-min+1;
- for (int i=0; i<n; i++) {
- glyph[i].metrics = (QPFGlyphMetrics*)data;
- data += sizeof(QPFGlyphMetrics);
- }
- if ( less )
- less->readMetrics(data);
- if ( more )
- more->readMetrics(data);
- }
-#else
- void readMetrics(QIODevice& f)
- {
- int n = max-min+1;
- for (int i=0; i<n; i++) {
- glyph[i].metrics = new QPFGlyphMetrics;
- f.read((char*)glyph[i].metrics, sizeof(QPFGlyphMetrics));
- }
- if ( less )
- less->readMetrics(f);
- if ( more )
- more->readMetrics(f);
- }
-#endif
-
-#ifdef QT_USE_MMAP
- void readData(uchar*& data)
- {
- int n = max-min+1;
- for (int i=0; i<n; i++) {
- QSize s( glyph[i].metrics->width, glyph[i].metrics->height );
- //######### s = qt_screen->mapToDevice( s );
- uint datasize = glyph[i].metrics->linestep * s.height();
- glyph[i].data = data; data += datasize;
- }
- if ( less )
- less->readData(data);
- if ( more )
- more->readData(data);
- }
-#else
- void readData(QIODevice& f)
- {
- int n = max-min+1;
- for (int i=0; i<n; i++) {
- QSize s( glyph[i].metrics->width, glyph[i].metrics->height );
- //############### s = qt_screen->mapToDevice( s );
- uint datasize = glyph[i].metrics->linestep * s.height();
- glyph[i].data = new uchar[datasize]; // ### deleted?
- f.read((char*)glyph[i].data, datasize);
- }
- if ( less )
- less->readData(f);
- if ( more )
- more->readData(f);
- }
-#endif
-
-};
-
-class QFontEngineQPF1Data
-{
-public:
- QPFFontMetrics fm;
- QPFGlyphTree *tree;
- void *mmapStart;
- size_t mmapLength;
-};
-
-#if defined(Q_OS_INTEGRITY)
-static void *qt_mmap(void *start, size_t length, int /*prot*/, int /*flags*/, int fd, off_t offset)
-{
- // INTEGRITY cannot mmap local files - load it into a local buffer
- if (::lseek(fd, offset, SEEK_SET) == -1) {
-# if defined(DEBUG_FONTENGINE)
- perror("lseek failed");
-# endif
- }
- void *buf = malloc(length);
- if (::read(fd, buf, length) != (ssize_t)length) {
-# if defined(DEBUG_FONTENGINE)
- perror("read failed");
-# endif
- }
-
- return buf;
-}
-#else
-static inline void *qt_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
-{
- return mmap(start, length, prot, flags, fd, offset);
-}
-#endif
-
-
-
-QFontEngineQPF1::QFontEngineQPF1(const QFontDef&, const QString &fn)
-{
- cache_cost = 1;
-
- int f = QT_OPEN( QFile::encodeName(fn), O_RDONLY, 0);
- Q_ASSERT(f>=0);
- QT_STATBUF st;
- if ( QT_FSTAT( f, &st ) )
- qFatal("Failed to stat %s",QFile::encodeName(fn).data());
- uchar* data = (uchar*)qt_mmap( 0, // any address
- st.st_size, // whole file
- PROT_READ, // read-only memory
-#if defined(Q_OS_INTEGRITY)
- 0,
-#elif !defined(Q_OS_SOLARIS) && !defined(Q_OS_QNX4) && !defined(Q_OS_VXWORKS)
- MAP_FILE | MAP_PRIVATE, // swap-backed map from file
-#else
- MAP_PRIVATE,
-#endif
- f, 0 ); // from offset 0 of f
-#if !defined(MAP_FAILED) && (defined(Q_OS_QNX4) || defined(Q_OS_INTEGRITY))
-#define MAP_FAILED ((void *)-1)
-#endif
- if ( !data || data == (uchar*)MAP_FAILED )
- qFatal("Failed to mmap %s",QFile::encodeName(fn).data());
- QT_CLOSE(f);
-
- d = new QFontEngineQPF1Data;
- d->mmapStart = data;
- d->mmapLength = st.st_size;
- memcpy(reinterpret_cast<char*>(&d->fm),data,sizeof(d->fm));
-
- data += sizeof(d->fm);
- d->tree = new QPFGlyphTree(data);
- glyphFormat = (d->fm.flags & FM_SMOOTH) ? QFontEngineGlyphCache::Raster_A8
- : QFontEngineGlyphCache::Raster_Mono;
-#if 0
- qDebug() << "font file" << fn
- << "ascent" << d->fm.ascent << "descent" << d->fm.descent
- << "leftbearing" << d->fm.leftbearing
- << "rightbearing" << d->fm.rightbearing
- << "maxwidth" << d->fm.maxwidth
- << "leading" << d->fm.leading
- << "flags" << d->fm.flags
- << "underlinepos" << d->fm.underlinepos
- << "underlinewidth" << d->fm.underlinewidth;
-#endif
-}
-
-QFontEngineQPF1::~QFontEngineQPF1()
-{
- if (d->mmapStart)
- munmap(d->mmapStart, d->mmapLength);
- delete d->tree;
- delete d;
-}
-
-
-bool QFontEngineQPF1::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
-{
- if(*nglyphs < len) {
- *nglyphs = len;
- return false;
- }
- *nglyphs = 0;
-
- bool mirrored = flags & QTextEngine::RightToLeft;
- for(int i = 0; i < len; i++) {
- unsigned int uc = getChar(str, i, len);
- if (mirrored)
- uc = QChar::mirroredChar(uc);
- glyphs->glyphs[*nglyphs] = uc < 0x10000 ? uc : 0;
- ++*nglyphs;
- }
-
- glyphs->numGlyphs = *nglyphs;
-
- if (flags & QTextEngine::GlyphIndicesOnly)
- return true;
-
- recalcAdvances(glyphs, flags);
-
- return true;
-}
-
-void QFontEngineQPF1::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags) const
-{
- for(int i = 0; i < glyphs->numGlyphs; i++) {
- QPFGlyph *glyph = d->tree->get(glyphs->glyphs[i]);
-
- glyphs->advances_x[i] = glyph ? glyph->metrics->advance : 0;
- glyphs->advances_y[i] = 0;
-
- if (!glyph)
- glyphs->glyphs[i] = 0;
- }
-}
-
-void QFontEngineQPF1::draw(QPaintEngine *p, qreal _x, qreal _y, const QTextItemInt &si)
-{
- QPaintEngineState *pState = p->state;
- QRasterPaintEngine *paintEngine = static_cast<QRasterPaintEngine*>(p);
-
- QTransform matrix = pState->transform();
- matrix.translate(_x, _y);
- QFixed x = QFixed::fromReal(matrix.dx());
- QFixed y = QFixed::fromReal(matrix.dy());
-
- QVarLengthArray<QFixedPoint> positions;
- QVarLengthArray<glyph_t> glyphs;
- getGlyphPositions(si.glyphs, matrix, si.flags, glyphs, positions);
- if (glyphs.size() == 0)
- return;
-
- int depth = (d->fm.flags & FM_SMOOTH) ? 8 : 1;
- for(int i = 0; i < glyphs.size(); i++) {
- const QPFGlyph *glyph = d->tree->get(glyphs[i]);
- if (!glyph)
- continue;
-
- int bpl = glyph->metrics->linestep;
-
- if(glyph->data)
- paintEngine->alphaPenBlt(glyph->data, bpl, depth,
- qRound(positions[i].x) + glyph->metrics->bearingx,
- qRound(positions[i].y) - glyph->metrics->bearingy,
- glyph->metrics->width,glyph->metrics->height);
- }
-}
-
-
-QImage QFontEngineQPF1::alphaMapForGlyph(glyph_t g)
-{
- const QPFGlyph *glyph = d->tree->get(g);
- if (!glyph)
- return QImage();
-
- int mono = !(d->fm.flags & FM_SMOOTH);
-
- const uchar *bits = glyph->data;//((const uchar *) glyph);
-
- QImage image;
- if (mono) {
- image = QImage((glyph->metrics->width+7)&~7, glyph->metrics->height, QImage::Format_Mono);
- image.setColor(0, qRgba(0, 0, 0, 0));
- image.setColor(1, qRgba(0, 0, 0, 255));
- } else {
- image = QImage(glyph->metrics->width, glyph->metrics->height, QImage::Format_Indexed8);
- for (int j=0; j<256; ++j)
- image.setColor(j, qRgba(0, 0, 0, j));
- }
- for (int i=0; i<glyph->metrics->height; ++i) {
- memcpy(image.scanLine(i), bits, glyph->metrics->linestep);
- bits += glyph->metrics->linestep;
- }
- return image;
-}
-
-
-
-void QFontEngineQPF1::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
-{
- addBitmapFontToPath(x, y, glyphs, path, flags);
-}
-
-glyph_metrics_t QFontEngineQPF1::boundingBox(const QGlyphLayout &glyphs)
-{
- if (glyphs.numGlyphs == 0)
- return glyph_metrics_t();
-
- QFixed w = 0;
- for (int i = 0; i < glyphs.numGlyphs; ++i)
- w += glyphs.effectiveAdvance(i);
- return glyph_metrics_t(0, -ascent(), w - lastRightBearing(glyphs), ascent()+descent()+1, w, 0);
-}
-
-glyph_metrics_t QFontEngineQPF1::boundingBox(glyph_t glyph)
-{
- const QPFGlyph *g = d->tree->get(glyph);
- if (!g)
- return glyph_metrics_t();
- Q_ASSERT(g);
- return glyph_metrics_t(g->metrics->bearingx, -g->metrics->bearingy,
- g->metrics->width, g->metrics->height,
- g->metrics->advance, 0);
-}
-
-QFixed QFontEngineQPF1::ascent() const
-{
- return d->fm.ascent;
-}
-
-QFixed QFontEngineQPF1::descent() const
-{
- return d->fm.descent;
-}
-
-QFixed QFontEngineQPF1::leading() const
-{
- return d->fm.leading;
-}
-
-qreal QFontEngineQPF1::maxCharWidth() const
-{
- return d->fm.maxwidth;
-}
-/*
-const char *QFontEngineQPF1::name() const
-{
- return "qt";
-}
-*/
-bool QFontEngineQPF1::canRender(const QChar *str, int len)
-{
- for(int i = 0; i < len; i++)
- if (!d->tree->inFont(str[i].unicode()))
- return false;
- return true;
-}
-
-QFontEngine::Type QFontEngineQPF1::type() const
-{
- return QPF1;
-}
-
-qreal QFontEngineQPF1::minLeftBearing() const
-{
- return d->fm.leftbearing;
-}
-
-qreal QFontEngineQPF1::minRightBearing() const
-{
- return d->fm.rightbearing;
-}
-
-QFixed QFontEngineQPF1::underlinePosition() const
-{
- return d->fm.underlinepos;
-}
-
-QFixed QFontEngineQPF1::lineThickness() const
-{
- return d->fm.underlinewidth;
-}
-
-#endif //QT_NO_QWS_QPF
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp
deleted file mode 100644
index 2bcee0157c..0000000000
--- a/src/gui/text/qfontengine_s60.cpp
+++ /dev/null
@@ -1,569 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qfontengine_s60_p.h"
-#include "qtextengine_p.h"
-#include "qendian.h"
-#include "qglobal.h"
-#include <private/qapplication_p.h>
-#include "qimage.h"
-#include <private/qt_s60_p.h>
-#include <private/qpixmap_s60_p.h>
-
-#include <e32base.h>
-#include <e32std.h>
-#include <eikenv.h>
-#include <gdi.h>
-#if defined(Q_SYMBIAN_HAS_GLYPHOUTLINE_API)
-#include <graphics/gdi/gdiplatapi.h>
-#endif // Q_SYMBIAN_HAS_GLYPHOUTLINE_API
-
-// Replication of TGetFontTableParam & friends.
-// There is unfortunately no compile time flag like SYMBIAN_FONT_TABLE_API
-// that would help us to only replicate these things for Symbian versions
-// that do not yet have the font table Api. Symbian's public SDK does
-// generally not define any usable macros.
-class QSymbianTGetFontTableParam
-{
-public:
- TUint32 iTag;
- TAny *iContent;
- TInt iLength;
-};
-const TUid QSymbianKFontGetFontTable = {0x102872C1};
-const TUid QSymbianKFontReleaseFontTable = {0x2002AC24};
-
-QT_BEGIN_NAMESPACE
-
-QSymbianTypeFaceExtras::QSymbianTypeFaceExtras(CFont* cFont, COpenFont *openFont)
- : m_cFont(cFont)
- , m_symbolCMap(false)
- , m_openFont(openFont)
-{
- if (!symbianFontTableApiAvailable()) {
- TAny *trueTypeExtension = NULL;
- m_openFont->ExtendedInterface(KUidOpenFontTrueTypeExtension, trueTypeExtension);
- m_trueTypeExtension = static_cast<MOpenFontTrueTypeExtension*>(trueTypeExtension);
- Q_ASSERT(m_trueTypeExtension);
- }
-}
-
-QSymbianTypeFaceExtras::~QSymbianTypeFaceExtras()
-{
- if (symbianFontTableApiAvailable())
- S60->screenDevice()->ReleaseFont(m_cFont);
-}
-
-QByteArray QSymbianTypeFaceExtras::getSfntTable(uint tag) const
-{
- if (symbianFontTableApiAvailable()) {
- QSymbianTGetFontTableParam fontTableParams = { tag, 0, 0 };
- if (m_cFont->ExtendedFunction(QSymbianKFontGetFontTable, &fontTableParams) == KErrNone) {
- const char* const fontTableContent =
- static_cast<const char *>(fontTableParams.iContent);
- const QByteArray fontTable(fontTableContent, fontTableParams.iLength);
- m_cFont->ExtendedFunction(QSymbianKFontReleaseFontTable, &fontTableParams);
- return fontTable;
- }
- return QByteArray();
- } else {
- Q_ASSERT(m_trueTypeExtension->HasTrueTypeTable(tag));
- TInt error = KErrNone;
- TInt tableByteLength = 0;
- TAny *table = m_trueTypeExtension->GetTrueTypeTable(error, tag, &tableByteLength);
- Q_CHECK_PTR(table);
- const QByteArray result(static_cast<const char*>(table), tableByteLength);
- m_trueTypeExtension->ReleaseTrueTypeTable(table);
- return result;
- }
-}
-
-bool QSymbianTypeFaceExtras::getSfntTableData(uint tag, uchar *buffer, uint *length) const
-{
- bool result = true;
- if (symbianFontTableApiAvailable()) {
- QSymbianTGetFontTableParam fontTableParams = { tag, 0, 0 };
- if (m_cFont->ExtendedFunction(QSymbianKFontGetFontTable, &fontTableParams) == KErrNone) {
- if (*length > 0 && *length < fontTableParams.iLength) {
- result = false; // Caller did not allocate enough memory
- } else {
- *length = fontTableParams.iLength;
- if (buffer)
- memcpy(buffer, fontTableParams.iContent, fontTableParams.iLength);
- }
- m_cFont->ExtendedFunction(QSymbianKFontReleaseFontTable, &fontTableParams);
- } else {
- result = false;
- }
- } else {
- if (!m_trueTypeExtension->HasTrueTypeTable(tag))
- return false;
-
- TInt error = KErrNone;
- TInt tableByteLength;
- TAny *table = m_trueTypeExtension->GetTrueTypeTable(error, tag, &tableByteLength);
- Q_CHECK_PTR(table);
-
- if (error != KErrNone) {
- return false;
- } else if (*length > 0 && *length < tableByteLength) {
- result = false; // Caller did not allocate enough memory
- } else {
- *length = tableByteLength;
- if (buffer)
- memcpy(buffer, table, tableByteLength);
- }
-
- m_trueTypeExtension->ReleaseTrueTypeTable(table);
- }
- return result;
-}
-
-const uchar *QSymbianTypeFaceExtras::cmap() const
-{
- if (m_cmapTable.isNull()) {
- const QByteArray cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p'));
- int size = 0;
- const uchar *cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *>
- (cmapTable.constData()), cmapTable.size(), &m_symbolCMap, &size);
- m_cmapTable = QByteArray(reinterpret_cast<const char *>(cmap), size);
- }
- return reinterpret_cast<const uchar *>(m_cmapTable.constData());
-}
-
-bool QSymbianTypeFaceExtras::isSymbolCMap() const
-{
- return m_symbolCMap;
-}
-
-CFont *QSymbianTypeFaceExtras::fontOwner() const
-{
- return m_cFont;
-}
-
-QFixed QSymbianTypeFaceExtras::unitsPerEm() const
-{
- if (m_unitsPerEm.value() != 0)
- return m_unitsPerEm;
- const QByteArray head = getSfntTable(MAKE_TAG('h', 'e', 'a', 'd'));
- const int unitsPerEmOffset = 18;
- if (head.size() > unitsPerEmOffset + sizeof(quint16)) {
- const uchar* tableData = reinterpret_cast<const uchar*>(head.constData());
- const uchar* unitsPerEm = tableData + unitsPerEmOffset;
- m_unitsPerEm = qFromBigEndian<quint16>(unitsPerEm);
- } else {
- // Bitmap font? Corrupt font?
- // We return -1 and let the QFontEngineS60 return the pixel size.
- m_unitsPerEm = -1;
- }
- return m_unitsPerEm;
-}
-
-bool QSymbianTypeFaceExtras::symbianFontTableApiAvailable()
-{
- enum FontTableApiAvailability {
- Unknown,
- Available,
- Unavailable
- };
- static FontTableApiAvailability availability =
- QSysInfo::symbianVersion() < QSysInfo::SV_SF_3 ?
- Unavailable : Unknown;
- if (availability == Unknown) {
- // Actually, we should ask CFeatureDiscovery::IsFeatureSupportedL()
- // with FfFontTable here. But since at the time of writing, the
- // FfFontTable flag check either gave false positives or false
- // negatives. Here comes an implicit check via CFont::ExtendedFunction.
- QSymbianTGetFontTableParam fontTableParams = {
- MAKE_TAG('O', 'S', '/', '2'), 0, 0 };
- QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
- CFont *font;
- const TInt getFontErr = S60->screenDevice()->GetNearestFontInTwips(font, TFontSpec());
- Q_ASSERT(getFontErr == KErrNone);
- if (font->ExtendedFunction(QSymbianKFontGetFontTable, &fontTableParams) == KErrNone) {
- font->ExtendedFunction(QSymbianKFontReleaseFontTable, &fontTableParams);
- availability = Available;
- } else {
- availability = Unavailable;
- }
- S60->screenDevice()->ReleaseFont(font);
- lock.relock();
- }
- return availability == Available;
-}
-
-// duplicated from qfontengine_xyz.cpp
-static inline unsigned int getChar(const QChar *str, int &i, const int len)
-{
- unsigned int uc = str[i].unicode();
- if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {
- uint low = str[i+1].unicode();
- if (low >= 0xdc00 && low < 0xe000) {
- uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
- ++i;
- }
- }
- return uc;
-}
-
-extern QString qt_symbian_fontNameWithAppFontMarker(const QString &fontName); // qfontdatabase_s60.cpp
-
-CFont *QFontEngineS60::fontWithSize(qreal size) const
-{
- CFont *result = 0;
- const QString family = qt_symbian_fontNameWithAppFontMarker(QFontEngine::fontDef.family);
- TFontSpec fontSpec(qt_QString2TPtrC(family), TInt(size));
- fontSpec.iFontStyle.SetBitmapType(EAntiAliasedGlyphBitmap);
- fontSpec.iFontStyle.SetPosture(QFontEngine::fontDef.style == QFont::StyleNormal?EPostureUpright:EPostureItalic);
- fontSpec.iFontStyle.SetStrokeWeight(QFontEngine::fontDef.weight > QFont::Normal?EStrokeWeightBold:EStrokeWeightNormal);
- const TInt errorCode = S60->screenDevice()->GetNearestFontToDesignHeightInPixels(result, fontSpec);
- Q_ASSERT(result && (errorCode == 0));
- return result;
-}
-
-void QFontEngineS60::setFontScale(qreal scale)
-{
- if (qFuzzyCompare(scale, qreal(1))) {
- if (!m_originalFont)
- m_originalFont = fontWithSize(m_originalFontSizeInPixels);
- m_activeFont = m_originalFont;
- } else {
- const qreal scaledFontSizeInPixels = m_originalFontSizeInPixels * scale;
- if (!m_scaledFont ||
- (TInt(scaledFontSizeInPixels) != TInt(m_scaledFontSizeInPixels))) {
- releaseFont(m_scaledFont);
- m_scaledFontSizeInPixels = scaledFontSizeInPixels;
- m_scaledFont = fontWithSize(m_scaledFontSizeInPixels);
- }
- m_activeFont = m_scaledFont;
- }
-}
-
-void QFontEngineS60::releaseFont(CFont *&font)
-{
- if (font) {
- S60->screenDevice()->ReleaseFont(font);
- font = 0;
- }
-}
-
-QFontEngineS60::QFontEngineS60(const QFontDef &request, const QSymbianTypeFaceExtras *extras)
- : m_extras(extras)
- , m_originalFont(0)
- , m_originalFontSizeInPixels((request.pixelSize >= 0)?
- request.pixelSize:pointsToPixels(request.pointSize))
- , m_scaledFont(0)
- , m_scaledFontSizeInPixels(0)
- , m_activeFont(0)
-{
- QFontEngine::fontDef = request;
- setFontScale(1.0);
- cache_cost = sizeof(QFontEngineS60);
-}
-
-QFontEngineS60::~QFontEngineS60()
-{
- releaseFont(m_originalFont);
- releaseFont(m_scaledFont);
-}
-
-QFixed QFontEngineS60::emSquareSize() const
-{
- const QFixed unitsPerEm = m_extras->unitsPerEm();
- return unitsPerEm.toInt() == -1 ?
- QFixed::fromReal(m_originalFontSizeInPixels) : unitsPerEm;
-}
-
-bool QFontEngineS60::stringToCMap(const QChar *characters, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
-{
- if (*nglyphs < len) {
- *nglyphs = len;
- return false;
- }
-
- HB_Glyph *g = glyphs->glyphs;
- const unsigned char* cmap = m_extras->cmap();
- const bool isRtl = (flags & QTextEngine::RightToLeft);
- for (int i = 0; i < len; ++i) {
- const unsigned int uc = getChar(characters, i, len);
- *g++ = QFontEngine::getTrueTypeGlyphIndex(cmap,
- (isRtl && !m_extras->isSymbolCMap()) ? QChar::mirroredChar(uc) : uc);
- }
-
- glyphs->numGlyphs = g - glyphs->glyphs;
- *nglyphs = glyphs->numGlyphs;
-
- if (flags & QTextEngine::GlyphIndicesOnly)
- return true;
-
- recalcAdvances(glyphs, flags);
- return true;
-}
-
-void QFontEngineS60::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
-{
- Q_UNUSED(flags);
- TOpenFontCharMetrics metrics;
- const TUint8 *glyphBitmapBytes;
- TSize glyphBitmapSize;
- for (int i = 0; i < glyphs->numGlyphs; i++) {
- getCharacterData(glyphs->glyphs[i], metrics, glyphBitmapBytes, glyphBitmapSize);
- glyphs->advances_x[i] = metrics.HorizAdvance();
- glyphs->advances_y[i] = 0;
- }
-}
-
-#ifdef Q_SYMBIAN_HAS_GLYPHOUTLINE_API
-static bool parseGlyphPathData(const char *dataStr, const char *dataEnd, QPainterPath &path,
- qreal fontPixelSize, const QPointF &offset, bool hinted);
-#endif //Q_SYMBIAN_HAS_GLYPHOUTLINE_API
-
-void QFontEngineS60::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions,
- int nglyphs, QPainterPath *path,
- QTextItem::RenderFlags flags)
-{
-#ifdef Q_SYMBIAN_HAS_GLYPHOUTLINE_API
- Q_UNUSED(flags)
- RGlyphOutlineIterator iterator;
- const TInt error = iterator.Open(*m_activeFont, glyphs, nglyphs);
- if (KErrNone != error)
- return;
- const qreal fontSizeInPixels = qreal(m_activeFont->HeightInPixels());
- int count = 0;
- do {
- const TUint8* outlineUint8 = iterator.Outline();
- const char* const outlineChar = reinterpret_cast<const char*>(outlineUint8);
- const char* const outlineEnd = outlineChar + iterator.OutlineLength();
- parseGlyphPathData(outlineChar, outlineEnd, *path, fontSizeInPixels,
- positions[count++].toPointF(), false);
- } while(KErrNone == iterator.Next() && count <= nglyphs);
- iterator.Close();
-#else // Q_SYMBIAN_HAS_GLYPHOUTLINE_API
- QFontEngine::addGlyphsToPath(glyphs, positions, nglyphs, path, flags);
-#endif //Q_SYMBIAN_HAS_GLYPHOUTLINE_API
-}
-
-QImage QFontEngineS60::alphaMapForGlyph(glyph_t glyph)
-{
- // Note: On some Symbian versions (apparently <= Symbian^1), this
- // function will return gray values 0x00, 0x10 ... 0xe0, 0xf0 due
- // to a bug. The glyphs are nowhere perfectly opaque.
- // This has been fixed for Symbian^3.
-
- TOpenFontCharMetrics metrics;
- const TUint8 *glyphBitmapBytes;
- TSize glyphBitmapSize;
- getCharacterData(glyph, metrics, glyphBitmapBytes, glyphBitmapSize);
- QImage result(glyphBitmapBytes, glyphBitmapSize.iWidth, glyphBitmapSize.iHeight, glyphBitmapSize.iWidth, QImage::Format_Indexed8);
- result.setColorTable(grayPalette());
- return result;
-}
-
-glyph_metrics_t QFontEngineS60::boundingBox(const QGlyphLayout &glyphs)
-{
- if (glyphs.numGlyphs == 0)
- return glyph_metrics_t();
-
- QFixed w = 0;
- for (int i = 0; i < glyphs.numGlyphs; ++i)
- w += glyphs.effectiveAdvance(i);
-
- return glyph_metrics_t(0, -ascent(), w - lastRightBearing(glyphs), ascent()+descent()+1, w, 0);
-}
-
-glyph_metrics_t QFontEngineS60::boundingBox_const(glyph_t glyph) const
-{
- TOpenFontCharMetrics metrics;
- const TUint8 *glyphBitmapBytes;
- TSize glyphBitmapSize;
- getCharacterData(glyph, metrics, glyphBitmapBytes, glyphBitmapSize);
- const glyph_metrics_t result(
- metrics.HorizBearingX(),
- -metrics.HorizBearingY(),
- metrics.Width(),
- metrics.Height(),
- metrics.HorizAdvance(),
- 0
- );
- return result;
-}
-
-glyph_metrics_t QFontEngineS60::boundingBox(glyph_t glyph)
-{
- return boundingBox_const(glyph);
-}
-
-QFixed QFontEngineS60::ascent() const
-{
- // Workaround for QTBUG-8013
- // Stroke based fonts may return an incorrect FontMaxAscent of 0.
- const QFixed ascent = m_originalFont->FontMaxAscent();
- return (ascent > 0) ? ascent : QFixed::fromReal(m_originalFontSizeInPixels) - descent();
-}
-
-QFixed QFontEngineS60::descent() const
-{
- return m_originalFont->FontMaxDescent();
-}
-
-QFixed QFontEngineS60::leading() const
-{
- return 0;
-}
-
-qreal QFontEngineS60::maxCharWidth() const
-{
- return m_originalFont->MaxCharWidthInPixels();
-}
-
-const char *QFontEngineS60::name() const
-{
- return "QFontEngineS60";
-}
-
-bool QFontEngineS60::canRender(const QChar *string, int len)
-{
- const unsigned char *cmap = m_extras->cmap();
- for (int i = 0; i < len; ++i) {
- const unsigned int uc = getChar(string, i, len);
- if (QFontEngine::getTrueTypeGlyphIndex(cmap, uc) == 0)
- return false;
- }
- return true;
-}
-
-QByteArray QFontEngineS60::getSfntTable(uint tag) const
-{
- return m_extras->getSfntTable(tag);
-}
-
-bool QFontEngineS60::getSfntTableData(uint tag, uchar *buffer, uint *length) const
-{
- return m_extras->getSfntTableData(tag, buffer, length);
-}
-
-QFontEngine::Type QFontEngineS60::type() const
-{
- return QFontEngine::S60FontEngine;
-}
-
-void QFontEngineS60::getCharacterData(glyph_t glyph, TOpenFontCharMetrics& metrics, const TUint8*& bitmap, TSize& bitmapSize) const
-{
- // Setting the most significant bit tells GetCharacterData
- // that 'code' is a Glyph ID, rather than a UTF-16 value
- const TUint specialCode = (TUint)glyph | 0x80000000;
-
- const CFont::TCharacterDataAvailability availability =
- m_activeFont->GetCharacterData(specialCode, metrics, bitmap, bitmapSize);
- const glyph_t fallbackGlyph = '?';
- if (availability != CFont::EAllCharacterData) {
- const CFont::TCharacterDataAvailability fallbackAvailability =
- m_activeFont->GetCharacterData(fallbackGlyph, metrics, bitmap, bitmapSize);
- Q_ASSERT(fallbackAvailability == CFont::EAllCharacterData);
- }
-}
-
-#ifdef Q_SYMBIAN_HAS_GLYPHOUTLINE_API
-static inline void skipSpacesAndComma(const char* &str, const char* const strEnd)
-{
- while (str <= strEnd && (*str == ' ' || *str == ','))
- ++str;
-}
-
-static bool parseGlyphPathData(const char *svgPath, const char *svgPathEnd, QPainterPath &path,
- qreal fontPixelSize, const QPointF &offset, bool hinted)
-{
- Q_UNUSED(hinted)
- QPointF p1, p2, firstSubPathPoint;
- qreal *elementValues[] =
- {&p1.rx(), &p1.ry(), &p2.rx(), &p2.ry()};
- const int unitsPerEm = 2048; // See: http://en.wikipedia.org/wiki/Em_%28typography%29
- const qreal resizeFactor = fontPixelSize / unitsPerEm;
-
- while (svgPath < svgPathEnd) {
- skipSpacesAndComma(svgPath, svgPathEnd);
- const char pathElem = *svgPath++;
- skipSpacesAndComma(svgPath, svgPathEnd);
-
- if (pathElem != 'Z') {
- char *endStr = 0;
- int elementValuesCount = 0;
- for (int i = 0; i < 4; ++i) { // 4 = size of elementValues[]
- qreal coordinateValue = strtod(svgPath, &endStr);
- if (svgPath == endStr)
- break;
- if (i % 2) // Flip vertically
- coordinateValue = -coordinateValue;
- *elementValues[i] = coordinateValue * resizeFactor;
- elementValuesCount++;
- svgPath = endStr;
- skipSpacesAndComma(svgPath, svgPathEnd);
- }
- p1 += offset;
- if (elementValuesCount == 2)
- p2 = firstSubPathPoint;
- else
- p2 += offset;
- }
-
- switch (pathElem) {
- case 'M':
- firstSubPathPoint = p1;
- path.moveTo(p1);
- break;
- case 'Z':
- path.closeSubpath();
- break;
- case 'L':
- path.lineTo(p1);
- break;
- case 'Q':
- path.quadTo(p1, p2);
- break;
- default:
- return false;
- }
- }
- return true;
-}
-#endif // Q_SYMBIAN_HAS_GLYPHOUTLINE_API
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfontengine_s60_p.h b/src/gui/text/qfontengine_s60_p.h
deleted file mode 100644
index c4fa9d16fe..0000000000
--- a/src/gui/text/qfontengine_s60_p.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFONTENGINE_S60_P_H
-#define QFONTENGINE_S60_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qconfig.h"
-#include <private/qfontengine_p.h>
-#include "qsize.h"
-#include <openfont.h>
-
-// The glyph outline code is intentionally disabled. It will be reactivated as
-// soon as the glyph outline API is backported from Symbian(^4) to Symbian(^3).
-#if 0
-#define Q_SYMBIAN_HAS_GLYPHOUTLINE_API
-#endif
-
-class CFont;
-
-QT_BEGIN_NAMESPACE
-
-// ..gives us access to truetype tables
-class QSymbianTypeFaceExtras
-{
-public:
- QSymbianTypeFaceExtras(CFont* cFont, COpenFont *openFont = 0);
- ~QSymbianTypeFaceExtras();
-
- QByteArray getSfntTable(uint tag) const;
- bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
- const uchar *cmap() const;
- CFont *fontOwner() const;
- bool isSymbolCMap() const;
- QFixed unitsPerEm() const;
- static bool symbianFontTableApiAvailable();
-
-private:
- CFont* m_cFont;
- mutable bool m_symbolCMap;
- mutable QByteArray m_cmapTable;
- mutable QFixed m_unitsPerEm;
-
- // m_openFont and m_openFont are used if Symbian does not provide
- // the Font Table API
- COpenFont *m_openFont;
- mutable MOpenFontTrueTypeExtension *m_trueTypeExtension;
-};
-
-class QFontEngineS60 : public QFontEngine
-{
-public:
- QFontEngineS60(const QFontDef &fontDef, const QSymbianTypeFaceExtras *extras);
- ~QFontEngineS60();
-
- QFixed emSquareSize() const;
- bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
- void recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const;
-
- void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
- QPainterPath *path, QTextItem::RenderFlags flags);
-
- QImage alphaMapForGlyph(glyph_t glyph);
-
- glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
- glyph_metrics_t boundingBox_const(glyph_t glyph) const; // Const correctnes quirk.
- glyph_metrics_t boundingBox(glyph_t glyph);
-
- QFixed ascent() const;
- QFixed descent() const;
- QFixed leading() const;
- qreal maxCharWidth() const;
- qreal minLeftBearing() const { return 0; }
- qreal minRightBearing() const { return 0; }
-
- QByteArray getSfntTable(uint tag) const;
- bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
-
- static qreal pixelsToPoints(qreal pixels, Qt::Orientation orientation = Qt::Horizontal);
- static qreal pointsToPixels(qreal points, Qt::Orientation orientation = Qt::Horizontal);
-
- const char *name() const;
-
- bool canRender(const QChar *string, int len);
-
- Type type() const;
-
- void getCharacterData(glyph_t glyph, TOpenFontCharMetrics& metrics, const TUint8*& bitmap, TSize& bitmapSize) const;
- void setFontScale(qreal scale);
-
-private:
- friend class QFontPrivate;
- friend class QSymbianVGFontGlyphCache;
-
- QFixed glyphAdvance(HB_Glyph glyph) const;
- CFont *fontWithSize(qreal size) const;
- static void releaseFont(CFont *&font);
-
- const QSymbianTypeFaceExtras *m_extras;
- CFont* m_originalFont;
- const qreal m_originalFontSizeInPixels;
- CFont* m_scaledFont;
- qreal m_scaledFontSizeInPixels;
- CFont* m_activeFont;
-};
-
-class QFontEngineMultiS60 : public QFontEngineMulti
-{
-public:
- QFontEngineMultiS60(QFontEngine *first, int script, const QStringList &fallbackFamilies);
- void loadEngine(int at);
-
- int m_script;
- QStringList m_fallbackFamilies;
-};
-
-QT_END_NAMESPACE
-
-#endif // QFONTENGINE_S60_P_H
diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp
deleted file mode 100644
index aef2145e5e..0000000000
--- a/src/gui/text/qfontengine_win.cpp
+++ /dev/null
@@ -1,1339 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#if _WIN32_WINNT < 0x0500
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0500
-#endif
-
-#include "qfontengine_p.h"
-#include "qtextengine_p.h"
-#include <qglobal.h>
-#include "qt_windows.h"
-#include <private/qapplication_p.h>
-
-#include <private/qsystemlibrary_p.h>
-#include <qpaintdevice.h>
-#include <qpainter.h>
-#include <limits.h>
-
-#include <qendian.h>
-#include <qmath.h>
-#include <qthreadstorage.h>
-
-#include <private/qunicodetables_p.h>
-#include <qbitmap.h>
-
-#include <private/qpainter_p.h>
-#include "qpaintengine.h"
-#include "qvarlengtharray.h"
-#include <private/qpaintengine_raster_p.h>
-#include <private/qnativeimage_p.h>
-
-#if defined(Q_WS_WINCE)
-#include "qguifunctions_wince.h"
-#endif
-
-//### mingw needed define
-#ifndef TT_PRIM_CSPLINE
-#define TT_PRIM_CSPLINE 3
-#endif
-
-#ifdef MAKE_TAG
-#undef MAKE_TAG
-#endif
-// GetFontData expects the tags in little endian ;(
-#define MAKE_TAG(ch1, ch2, ch3, ch4) (\
- (((quint32)(ch4)) << 24) | \
- (((quint32)(ch3)) << 16) | \
- (((quint32)(ch2)) << 8) | \
- ((quint32)(ch1)) \
- )
-
-// common DC for all fonts
-
-QT_BEGIN_NAMESPACE
-
-class QtHDC
-{
- HDC _hdc;
-public:
- QtHDC()
- {
- HDC displayDC = GetDC(0);
- _hdc = CreateCompatibleDC(displayDC);
- ReleaseDC(0, displayDC);
- }
- ~QtHDC()
- {
- if (_hdc)
- DeleteDC(_hdc);
- }
- HDC hdc() const
- {
- return _hdc;
- }
-};
-
-#ifndef QT_NO_THREAD
-Q_GLOBAL_STATIC(QThreadStorage<QtHDC *>, local_shared_dc)
-HDC shared_dc()
-{
- QtHDC *&hdc = local_shared_dc()->localData();
- if (!hdc)
- hdc = new QtHDC;
- return hdc->hdc();
-}
-#else
-HDC shared_dc()
-{
- return 0;
-}
-#endif
-
-#ifndef Q_WS_WINCE
-typedef BOOL (WINAPI *PtrGetCharWidthI)(HDC, UINT, UINT, LPWORD, LPINT);
-static PtrGetCharWidthI ptrGetCharWidthI = 0;
-static bool resolvedGetCharWidthI = false;
-
-static void resolveGetCharWidthI()
-{
- if (resolvedGetCharWidthI)
- return;
- resolvedGetCharWidthI = true;
- ptrGetCharWidthI = (PtrGetCharWidthI)QSystemLibrary::resolve(QLatin1String("gdi32"), "GetCharWidthI");
-}
-#endif // !defined(Q_WS_WINCE)
-
-// defined in qtextengine_win.cpp
-typedef void *SCRIPT_CACHE;
-typedef HRESULT (WINAPI *fScriptFreeCache)(SCRIPT_CACHE *);
-extern fScriptFreeCache ScriptFreeCache;
-
-static inline quint32 getUInt(unsigned char *p)
-{
- quint32 val;
- val = *p++ << 24;
- val |= *p++ << 16;
- val |= *p++ << 8;
- val |= *p;
-
- return val;
-}
-
-static inline quint16 getUShort(unsigned char *p)
-{
- quint16 val;
- val = *p++ << 8;
- val |= *p;
-
- return val;
-}
-
-// general font engine
-
-QFixed QFontEngineWin::lineThickness() const
-{
- if(lineWidth > 0)
- return lineWidth;
-
- return QFontEngine::lineThickness();
-}
-
-static OUTLINETEXTMETRIC *getOutlineTextMetric(HDC hdc)
-{
- int size;
- size = GetOutlineTextMetrics(hdc, 0, 0);
- OUTLINETEXTMETRIC *otm = (OUTLINETEXTMETRIC *)malloc(size);
- GetOutlineTextMetrics(hdc, size, otm);
- return otm;
-}
-
-void QFontEngineWin::getCMap()
-{
- ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE);
- HDC hdc = shared_dc();
- SelectObject(hdc, hfont);
- bool symb = false;
- if (ttf) {
- cmapTable = getSfntTable(qbswap<quint32>(MAKE_TAG('c', 'm', 'a', 'p')));
- int size = 0;
- cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()),
- cmapTable.size(), &symb, &size);
- }
- if (!cmap) {
- ttf = false;
- symb = false;
- }
- symbol = symb;
- designToDevice = 1;
- _faceId.index = 0;
- if(cmap) {
- OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc);
- designToDevice = QFixed((int)otm->otmEMSquare)/int(otm->otmTextMetrics.tmHeight);
- unitsPerEm = otm->otmEMSquare;
- x_height = (int)otm->otmsXHeight;
- loadKerningPairs(designToDevice);
- _faceId.filename = QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpFullName)).toLatin1();
- lineWidth = otm->otmsUnderscoreSize;
- fsType = otm->otmfsType;
- free(otm);
- } else {
- unitsPerEm = tm.tmHeight;
- }
-}
-
-
-inline unsigned int getChar(const QChar *str, int &i, const int len)
-{
- unsigned int uc = str[i].unicode();
- if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {
- uint low = str[i+1].unicode();
- if (low >= 0xdc00 && low < 0xe000) {
- uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
- ++i;
- }
- }
- return uc;
-}
-
-int QFontEngineWin::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout *glyphs, bool mirrored) const
-{
- int i = 0;
- int glyph_pos = 0;
- if (mirrored) {
-#if defined(Q_WS_WINCE)
- {
-#else
- if (symbol) {
- for (; i < numChars; ++i, ++glyph_pos) {
- unsigned int uc = getChar(str, i, numChars);
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
- if (!glyphs->glyphs[glyph_pos] && uc < 0x100)
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
- }
- } else if (ttf) {
- for (; i < numChars; ++i, ++glyph_pos) {
- unsigned int uc = getChar(str, i, numChars);
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, QChar::mirroredChar(uc));
- }
- } else {
-#endif
- wchar_t first = tm.tmFirstChar;
- wchar_t last = tm.tmLastChar;
-
- for (; i < numChars; ++i, ++glyph_pos) {
- uint ucs = QChar::mirroredChar(getChar(str, i, numChars));
- if (
-#ifdef Q_WS_WINCE
- tm.tmFirstChar > 60000 || // see line 375
-#endif
- ucs >= first && ucs <= last)
- glyphs->glyphs[glyph_pos] = ucs;
- else
- glyphs->glyphs[glyph_pos] = 0;
- }
- }
- } else {
-#if defined(Q_WS_WINCE)
- {
-#else
- if (symbol) {
- for (; i < numChars; ++i, ++glyph_pos) {
- unsigned int uc = getChar(str, i, numChars);
- glyphs->glyphs[i] = getTrueTypeGlyphIndex(cmap, uc);
- if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
- }
- } else if (ttf) {
- for (; i < numChars; ++i, ++glyph_pos) {
- unsigned int uc = getChar(str, i, numChars);
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
- }
- } else {
-#endif
- wchar_t first = tm.tmFirstChar;
- wchar_t last = tm.tmLastChar;
-
- for (; i < numChars; ++i, ++glyph_pos) {
- uint uc = getChar(str, i, numChars);
- if (
-#ifdef Q_WS_WINCE
- tm.tmFirstChar > 60000 || // see comment in QFontEngineWin
-#endif
- uc >= first && uc <= last)
- glyphs->glyphs[glyph_pos] = uc;
- else
- glyphs->glyphs[glyph_pos] = 0;
- }
- }
- }
- glyphs->numGlyphs = glyph_pos;
- return glyph_pos;
-}
-
-
-QFontEngineWin::QFontEngineWin(const QString &name, HFONT _hfont, bool stockFont, LOGFONT lf)
-{
- //qDebug("regular windows font engine created: font='%s', size=%d", name, lf.lfHeight);
-
- _name = name;
-
- cmap = 0;
- hfont = _hfont;
- logfont = lf;
- HDC hdc = shared_dc();
- SelectObject(hdc, hfont);
- this->stockFont = stockFont;
- fontDef.pixelSize = -lf.lfHeight;
-
- lbearing = SHRT_MIN;
- rbearing = SHRT_MIN;
- synthesized_flags = -1;
- lineWidth = -1;
- x_height = -1;
-
- BOOL res = GetTextMetrics(hdc, &tm);
- fontDef.fixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH);
- if (!res) {
- qErrnoWarning("QFontEngineWin: GetTextMetrics failed");
- ZeroMemory(&tm, sizeof(TEXTMETRIC));
- }
-
- cache_cost = tm.tmHeight * tm.tmAveCharWidth * 2000;
- getCMap();
-
- widthCache = 0;
- widthCacheSize = 0;
- designAdvances = 0;
- designAdvancesSize = 0;
-
-#ifndef Q_WS_WINCE
- if (!resolvedGetCharWidthI)
- resolveGetCharWidthI();
-#endif
-}
-
-QFontEngineWin::~QFontEngineWin()
-{
- if (designAdvances)
- free(designAdvances);
-
- if (widthCache)
- free(widthCache);
-
- // make sure we aren't by accident still selected
- SelectObject(shared_dc(), (HFONT)GetStockObject(SYSTEM_FONT));
-
- if (!stockFont) {
- if (!DeleteObject(hfont))
- qErrnoWarning("QFontEngineWin: failed to delete non-stock font...");
- }
-}
-
-HGDIOBJ QFontEngineWin::selectDesignFont() const
-{
- LOGFONT f = logfont;
- f.lfHeight = unitsPerEm;
- HFONT designFont = CreateFontIndirect(&f);
- return SelectObject(shared_dc(), designFont);
-}
-
-bool QFontEngineWin::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
-{
- if (*nglyphs < len) {
- *nglyphs = len;
- return false;
- }
-
- *nglyphs = getGlyphIndexes(str, len, glyphs, flags & QTextEngine::RightToLeft);
-
- if (flags & QTextEngine::GlyphIndicesOnly)
- return true;
-
- recalcAdvances(glyphs, flags);
- return true;
-}
-
-inline void calculateTTFGlyphWidth(HDC hdc, UINT glyph, int &width)
-{
-#if defined(Q_WS_WINCE)
- GetCharWidth32(hdc, glyph, glyph, &width);
-#else
- if (ptrGetCharWidthI)
- ptrGetCharWidthI(hdc, glyph, 1, 0, &width);
-#endif
-}
-
-void QFontEngineWin::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
-{
- HGDIOBJ oldFont = 0;
- HDC hdc = shared_dc();
- if (ttf && (flags & QTextEngine::DesignMetrics)) {
- for(int i = 0; i < glyphs->numGlyphs; i++) {
- unsigned int glyph = glyphs->glyphs[i];
- if(int(glyph) >= designAdvancesSize) {
- int newSize = (glyph + 256) >> 8 << 8;
- designAdvances = q_check_ptr((QFixed *)realloc(designAdvances,
- newSize*sizeof(QFixed)));
- for(int i = designAdvancesSize; i < newSize; ++i)
- designAdvances[i] = -1000000;
- designAdvancesSize = newSize;
- }
- if (designAdvances[glyph] < -999999) {
- if (!oldFont)
- oldFont = selectDesignFont();
-
- int width = 0;
- calculateTTFGlyphWidth(hdc, glyph, width);
- designAdvances[glyph] = QFixed(width) / designToDevice;
- }
- glyphs->advances_x[i] = designAdvances[glyph];
- glyphs->advances_y[i] = 0;
- }
- if(oldFont)
- DeleteObject(SelectObject(hdc, oldFont));
- } else {
- for(int i = 0; i < glyphs->numGlyphs; i++) {
- unsigned int glyph = glyphs->glyphs[i];
-
- glyphs->advances_y[i] = 0;
-
- if (glyph >= widthCacheSize) {
- int newSize = (glyph + 256) >> 8 << 8;
- widthCache = q_check_ptr((unsigned char *)realloc(widthCache,
- newSize*sizeof(QFixed)));
- memset(widthCache + widthCacheSize, 0, newSize - widthCacheSize);
- widthCacheSize = newSize;
- }
- glyphs->advances_x[i] = widthCache[glyph];
- // font-width cache failed
- if (glyphs->advances_x[i] == 0) {
- int width = 0;
- if (!oldFont)
- oldFont = SelectObject(hdc, hfont);
-
- if (!ttf) {
- QChar ch[2] = { ushort(glyph), 0 };
- int chrLen = 1;
- if (glyph > 0xffff) {
- ch[0] = QChar::highSurrogate(glyph);
- ch[1] = QChar::lowSurrogate(glyph);
- ++chrLen;
- }
- SIZE size = {0, 0};
- GetTextExtentPoint32(hdc, (wchar_t *)ch, chrLen, &size);
- width = size.cx;
- } else {
- calculateTTFGlyphWidth(hdc, glyph, width);
- }
- glyphs->advances_x[i] = width;
- // if glyph's within cache range, store it for later
- if (width > 0 && width < 0x100)
- widthCache[glyph] = width;
- }
- }
-
- if (oldFont)
- SelectObject(hdc, oldFont);
- }
-}
-
-glyph_metrics_t QFontEngineWin::boundingBox(const QGlyphLayout &glyphs)
-{
- if (glyphs.numGlyphs == 0)
- return glyph_metrics_t();
-
- QFixed w = 0;
- for (int i = 0; i < glyphs.numGlyphs; ++i)
- w += glyphs.effectiveAdvance(i);
-
- return glyph_metrics_t(0, -tm.tmAscent, w - lastRightBearing(glyphs), tm.tmHeight, w, 0);
-}
-
-#ifndef Q_WS_WINCE
-bool QFontEngineWin::getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const
-{
- Q_ASSERT(metrics != 0);
-
- HDC hdc = shared_dc();
-
- GLYPHMETRICS gm;
- DWORD res = 0;
- MAT2 mat;
- mat.eM11.value = mat.eM22.value = 1;
- mat.eM11.fract = mat.eM22.fract = 0;
- mat.eM21.value = mat.eM12.value = 0;
- mat.eM21.fract = mat.eM12.fract = 0;
-
- if (t.type() > QTransform::TxTranslate) {
- // We need to set the transform using the HDC's world
- // matrix rather than using the MAT2 above, because the
- // results provided when transforming via MAT2 does not
- // match the glyphs that are drawn using a WorldTransform
- XFORM xform;
- xform.eM11 = t.m11();
- xform.eM12 = t.m12();
- xform.eM21 = t.m21();
- xform.eM22 = t.m22();
- xform.eDx = 0;
- xform.eDy = 0;
- SetGraphicsMode(hdc, GM_ADVANCED);
- SetWorldTransform(hdc, &xform);
- }
-
- uint format = GGO_METRICS;
- if (ttf)
- format |= GGO_GLYPH_INDEX;
- res = GetGlyphOutline(hdc, glyph, format, &gm, 0, 0, &mat);
-
- if (t.type() > QTransform::TxTranslate) {
- XFORM xform;
- xform.eM11 = xform.eM22 = 1;
- xform.eM12 = xform.eM21 = xform.eDx = xform.eDy = 0;
- SetWorldTransform(hdc, &xform);
- SetGraphicsMode(hdc, GM_COMPATIBLE);
- }
-
- if (res != GDI_ERROR) {
- *metrics = glyph_metrics_t(gm.gmptGlyphOrigin.x, -gm.gmptGlyphOrigin.y,
- (int)gm.gmBlackBoxX, (int)gm.gmBlackBoxY, gm.gmCellIncX, gm.gmCellIncY);
- return true;
- } else {
- return false;
- }
-}
-#endif
-
-glyph_metrics_t QFontEngineWin::boundingBox(glyph_t glyph, const QTransform &t)
-{
-#ifndef Q_WS_WINCE
- HDC hdc = shared_dc();
- SelectObject(hdc, hfont);
-
- glyph_metrics_t glyphMetrics;
- bool success = getOutlineMetrics(glyph, t, &glyphMetrics);
-
- if (!ttf && !success) {
- // Bitmap fonts
- wchar_t ch = glyph;
- ABCFLOAT abc;
- GetCharABCWidthsFloat(hdc, ch, ch, &abc);
- int width = qRound(abc.abcfB);
-
- return glyph_metrics_t(QFixed::fromReal(abc.abcfA), -tm.tmAscent, width, tm.tmHeight, width, 0).transformed(t);
- }
-
- return glyphMetrics;
-#else
- HDC hdc = shared_dc();
- HGDIOBJ oldFont = SelectObject(hdc, hfont);
-
- ABC abc;
- int width;
- int advance;
-#ifdef GWES_MGTT // true type fonts
- if (GetCharABCWidths(hdc, glyph, glyph, &abc)) {
- width = qAbs(abc.abcA) + abc.abcB + qAbs(abc.abcC);
- advance = abc.abcA + abc.abcB + abc.abcC;
- }
- else
-#endif
-#if defined(GWES_MGRAST) || defined(GWES_MGRAST2) // raster fonts
- if (GetCharWidth32(hdc, glyph, glyph, &width)) {
- advance = width;
- }
- else
-#endif
- { // fallback
- width = tm.tmMaxCharWidth;
- advance = width;
- }
-
- SelectObject(hdc, oldFont);
- return glyph_metrics_t(0, -tm.tmAscent, width, tm.tmHeight, advance, 0).transformed(t);
-#endif
-}
-
-QFixed QFontEngineWin::ascent() const
-{
- return tm.tmAscent;
-}
-
-QFixed QFontEngineWin::descent() const
-{
- // ### we substract 1 to even out the historical +1 in QFontMetrics's
- // ### height=asc+desc+1 equation. Fix in Qt5.
- return tm.tmDescent - 1;
-}
-
-QFixed QFontEngineWin::leading() const
-{
- return tm.tmExternalLeading;
-}
-
-
-QFixed QFontEngineWin::xHeight() const
-{
- if(x_height >= 0)
- return x_height;
- return QFontEngine::xHeight();
-}
-
-QFixed QFontEngineWin::averageCharWidth() const
-{
- return tm.tmAveCharWidth;
-}
-
-qreal QFontEngineWin::maxCharWidth() const
-{
- return tm.tmMaxCharWidth;
-}
-
-enum { max_font_count = 256 };
-static const ushort char_table[] = {
- 40,
- 67,
- 70,
- 75,
- 86,
- 88,
- 89,
- 91,
- 102,
- 114,
- 124,
- 127,
- 205,
- 645,
- 884,
- 922,
- 1070,
- 12386,
- 0
-};
-
-static const int char_table_entries = sizeof(char_table)/sizeof(ushort);
-
-#ifndef Q_CC_MINGW
-void QFontEngineWin::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rightBearing)
-{
- HDC hdc = shared_dc();
- SelectObject(hdc, hfont);
-
-#ifndef Q_WS_WINCE
- if (ttf)
-#endif
-
- {
- ABC abcWidths;
- GetCharABCWidthsI(hdc, glyph, 1, 0, &abcWidths);
- if (leftBearing)
- *leftBearing = abcWidths.abcA;
- if (rightBearing)
- *rightBearing = abcWidths.abcC;
- }
-
-#ifndef Q_WS_WINCE
- else {
- QFontEngine::getGlyphBearings(glyph, leftBearing, rightBearing);
- }
-#endif
-}
-#endif // Q_CC_MINGW
-
-qreal QFontEngineWin::minLeftBearing() const
-{
- if (lbearing == SHRT_MIN)
- minRightBearing(); // calculates both
-
- return lbearing;
-}
-
-qreal QFontEngineWin::minRightBearing() const
-{
-#ifdef Q_WS_WINCE
- if (rbearing == SHRT_MIN) {
- int ml = 0;
- int mr = 0;
- HDC hdc = shared_dc();
- SelectObject(hdc, hfont);
- if (ttf) {
- ABC *abc = 0;
- int n = tm.tmLastChar - tm.tmFirstChar;
- if (n <= max_font_count) {
- abc = new ABC[n+1];
- GetCharABCWidths(hdc, tm.tmFirstChar, tm.tmLastChar, abc);
- } else {
- abc = new ABC[char_table_entries+1];
- for(int i = 0; i < char_table_entries; i++)
- GetCharABCWidths(hdc, char_table[i], char_table[i], abc+i);
- n = char_table_entries;
- }
- ml = abc[0].abcA;
- mr = abc[0].abcC;
- for (int i = 1; i < n; i++) {
- if (abc[i].abcA + abc[i].abcB + abc[i].abcC != 0) {
- ml = qMin(ml,abc[i].abcA);
- mr = qMin(mr,abc[i].abcC);
- }
- }
- delete [] abc;
- }
- lbearing = ml;
- rbearing = mr;
- }
-
- return rbearing;
-#else
- if (rbearing == SHRT_MIN) {
- int ml = 0;
- int mr = 0;
- HDC hdc = shared_dc();
- SelectObject(hdc, hfont);
- if (ttf) {
- ABC *abc = 0;
- int n = tm.tmLastChar - tm.tmFirstChar;
- if (n <= max_font_count) {
- abc = new ABC[n+1];
- GetCharABCWidths(hdc, tm.tmFirstChar, tm.tmLastChar, abc);
- } else {
- abc = new ABC[char_table_entries+1];
- for(int i = 0; i < char_table_entries; i++)
- GetCharABCWidths(hdc, char_table[i], char_table[i], abc + i);
- n = char_table_entries;
- }
- ml = abc[0].abcA;
- mr = abc[0].abcC;
- for (int i = 1; i < n; i++) {
- if (abc[i].abcA + abc[i].abcB + abc[i].abcC != 0) {
- ml = qMin(ml,abc[i].abcA);
- mr = qMin(mr,abc[i].abcC);
- }
- }
- delete [] abc;
- } else {
- ABCFLOAT *abc = 0;
- int n = tm.tmLastChar - tm.tmFirstChar+1;
- if (n <= max_font_count) {
- abc = new ABCFLOAT[n];
- GetCharABCWidthsFloat(hdc, tm.tmFirstChar, tm.tmLastChar, abc);
- } else {
- abc = new ABCFLOAT[char_table_entries];
- for(int i = 0; i < char_table_entries; i++)
- GetCharABCWidthsFloat(hdc, char_table[i], char_table[i], abc+i);
- n = char_table_entries;
- }
- float fml = abc[0].abcfA;
- float fmr = abc[0].abcfC;
- for (int i=1; i<n; i++) {
- if (abc[i].abcfA + abc[i].abcfB + abc[i].abcfC != 0) {
- fml = qMin(fml,abc[i].abcfA);
- fmr = qMin(fmr,abc[i].abcfC);
- }
- }
- ml = int(fml - 0.9999);
- mr = int(fmr - 0.9999);
- delete [] abc;
- }
- lbearing = ml;
- rbearing = mr;
- }
-
- return rbearing;
-#endif
-}
-
-
-const char *QFontEngineWin::name() const
-{
- return 0;
-}
-
-bool QFontEngineWin::canRender(const QChar *string, int len)
-{
- if (symbol) {
- for (int i = 0; i < len; ++i) {
- unsigned int uc = getChar(string, i, len);
- if (getTrueTypeGlyphIndex(cmap, uc) == 0) {
- if (uc < 0x100) {
- if (getTrueTypeGlyphIndex(cmap, uc + 0xf000) == 0)
- return false;
- } else {
- return false;
- }
- }
- }
- } else if (ttf) {
- for (int i = 0; i < len; ++i) {
- unsigned int uc = getChar(string, i, len);
- if (getTrueTypeGlyphIndex(cmap, uc) == 0)
- return false;
- }
- } else {
- while(len--) {
- if (tm.tmFirstChar > string->unicode() || tm.tmLastChar < string->unicode())
- return false;
- }
- }
- return true;
-}
-
-QFontEngine::Type QFontEngineWin::type() const
-{
- return QFontEngine::Win;
-}
-
-static inline double qt_fixed_to_double(const FIXED &p) {
- return ((p.value << 16) + p.fract) / 65536.0;
-}
-
-static inline QPointF qt_to_qpointf(const POINTFX &pt, qreal scale) {
- return QPointF(qt_fixed_to_double(pt.x) * scale, -qt_fixed_to_double(pt.y) * scale);
-}
-
-#ifndef GGO_UNHINTED
-#define GGO_UNHINTED 0x0100
-#endif
-
-static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc,
- QPainterPath *path, bool ttf, glyph_metrics_t *metric = 0, qreal scale = 1)
-{
-#if defined(Q_WS_WINCE)
- Q_UNUSED(glyph);
- Q_UNUSED(hdc);
-#endif
- MAT2 mat;
- mat.eM11.value = mat.eM22.value = 1;
- mat.eM11.fract = mat.eM22.fract = 0;
- mat.eM21.value = mat.eM12.value = 0;
- mat.eM21.fract = mat.eM12.fract = 0;
- uint glyphFormat = GGO_NATIVE;
-
- if (ttf)
- glyphFormat |= GGO_GLYPH_INDEX;
-
- GLYPHMETRICS gMetric;
- memset(&gMetric, 0, sizeof(GLYPHMETRICS));
- int bufferSize = GDI_ERROR;
-#if !defined(Q_WS_WINCE)
- bufferSize = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat);
-#endif
- if ((DWORD)bufferSize == GDI_ERROR) {
- return false;
- }
-
- void *dataBuffer = new char[bufferSize];
- DWORD ret = GDI_ERROR;
-#if !defined(Q_WS_WINCE)
- ret = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, bufferSize, dataBuffer, &mat);
-#endif
- if (ret == GDI_ERROR) {
- delete [](char *)dataBuffer;
- return false;
- }
-
- if(metric) {
- // #### obey scale
- *metric = glyph_metrics_t(gMetric.gmptGlyphOrigin.x, -gMetric.gmptGlyphOrigin.y,
- (int)gMetric.gmBlackBoxX, (int)gMetric.gmBlackBoxY,
- gMetric.gmCellIncX, gMetric.gmCellIncY);
- }
-
- int offset = 0;
- int headerOffset = 0;
- TTPOLYGONHEADER *ttph = 0;
-
- QPointF oset = position.toPointF();
- while (headerOffset < bufferSize) {
- ttph = (TTPOLYGONHEADER*)((char *)dataBuffer + headerOffset);
-
- QPointF lastPoint(qt_to_qpointf(ttph->pfxStart, scale));
- path->moveTo(lastPoint + oset);
- offset += sizeof(TTPOLYGONHEADER);
- TTPOLYCURVE *curve;
- while (offset<int(headerOffset + ttph->cb)) {
- curve = (TTPOLYCURVE*)((char*)(dataBuffer) + offset);
- switch (curve->wType) {
- case TT_PRIM_LINE: {
- for (int i=0; i<curve->cpfx; ++i) {
- QPointF p = qt_to_qpointf(curve->apfx[i], scale) + oset;
- path->lineTo(p);
- }
- break;
- }
- case TT_PRIM_QSPLINE: {
- const QPainterPath::Element &elm = path->elementAt(path->elementCount()-1);
- QPointF prev(elm.x, elm.y);
- QPointF endPoint;
- for (int i=0; i<curve->cpfx - 1; ++i) {
- QPointF p1 = qt_to_qpointf(curve->apfx[i], scale) + oset;
- QPointF p2 = qt_to_qpointf(curve->apfx[i+1], scale) + oset;
- if (i < curve->cpfx - 2) {
- endPoint = QPointF((p1.x() + p2.x()) / 2, (p1.y() + p2.y()) / 2);
- } else {
- endPoint = p2;
- }
-
- path->quadTo(p1, endPoint);
- prev = endPoint;
- }
-
- break;
- }
- case TT_PRIM_CSPLINE: {
- for (int i=0; i<curve->cpfx; ) {
- QPointF p2 = qt_to_qpointf(curve->apfx[i++], scale) + oset;
- QPointF p3 = qt_to_qpointf(curve->apfx[i++], scale) + oset;
- QPointF p4 = qt_to_qpointf(curve->apfx[i++], scale) + oset;
- path->cubicTo(p2, p3, p4);
- }
- break;
- }
- default:
- qWarning("QFontEngineWin::addOutlineToPath, unhandled switch case");
- }
- offset += sizeof(TTPOLYCURVE) + (curve->cpfx-1) * sizeof(POINTFX);
- }
- path->closeSubpath();
- headerOffset += ttph->cb;
- }
- delete [] (char*)dataBuffer;
-
- return true;
-}
-
-void QFontEngineWin::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
- QPainterPath *path, QTextItem::RenderFlags)
-{
- LOGFONT lf = logfont;
- // The sign must be negative here to make sure we match against character height instead of
- // hinted cell height. This ensures that we get linear matching, and we need this for
- // paths since we later on apply a scaling transform to the glyph outline to get the
- // font at the correct pixel size.
- lf.lfHeight = -unitsPerEm;
- lf.lfWidth = 0;
- HFONT hf = CreateFontIndirect(&lf);
- HDC hdc = shared_dc();
- HGDIOBJ oldfont = SelectObject(hdc, hf);
-
- for(int i = 0; i < nglyphs; ++i) {
- if (!addGlyphToPath(glyphs[i], positions[i], hdc, path, ttf, /*metric*/0,
- qreal(fontDef.pixelSize) / unitsPerEm)) {
- // Some windows fonts, like "Modern", are vector stroke
- // fonts, which are reported as TMPF_VECTOR but do not
- // support GetGlyphOutline, and thus we set this bit so
- // that addOutLineToPath can check it and return safely...
- hasOutline = false;
- break;
- }
- }
- DeleteObject(SelectObject(hdc, oldfont));
-}
-
-void QFontEngineWin::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs,
- QPainterPath *path, QTextItem::RenderFlags flags)
-{
-#if !defined(Q_WS_WINCE)
- if(tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) {
- hasOutline = true;
- QFontEngine::addOutlineToPath(x, y, glyphs, path, flags);
- if (hasOutline) {
- // has_outline is set to false if addGlyphToPath gets
- // false from GetGlyphOutline, meaning its not an outline
- // font.
- return;
- }
- }
-#endif
- QFontEngine::addBitmapFontToPath(x, y, glyphs, path, flags);
-}
-
-QFontEngine::FaceId QFontEngineWin::faceId() const
-{
- return _faceId;
-}
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <qdebug.h>
-QT_END_INCLUDE_NAMESPACE
-
-int QFontEngineWin::synthesized() const
-{
- if(synthesized_flags == -1) {
- synthesized_flags = 0;
- if(ttf) {
- const DWORD HEAD = MAKE_TAG('h', 'e', 'a', 'd');
- HDC hdc = shared_dc();
- SelectObject(hdc, hfont);
- uchar data[4];
- GetFontData(hdc, HEAD, 44, &data, 4);
- USHORT macStyle = getUShort(data);
- if (tm.tmItalic && !(macStyle & 2))
- synthesized_flags = SynthesizedItalic;
- if (fontDef.stretch != 100 && ttf)
- synthesized_flags |= SynthesizedStretch;
- if (tm.tmWeight >= 500 && !(macStyle & 1))
- synthesized_flags |= SynthesizedBold;
- //qDebug() << "font is" << _name <<
- // "it=" << (macStyle & 2) << fontDef.style << "flags=" << synthesized_flags;
- }
- }
- return synthesized_flags;
-}
-
-QFixed QFontEngineWin::emSquareSize() const
-{
- return unitsPerEm;
-}
-
-QFontEngine::Properties QFontEngineWin::properties() const
-{
- LOGFONT lf = logfont;
- lf.lfHeight = unitsPerEm;
- HFONT hf = CreateFontIndirect(&lf);
- HDC hdc = shared_dc();
- HGDIOBJ oldfont = SelectObject(hdc, hf);
- OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc);
- Properties p;
- p.emSquare = unitsPerEm;
- p.italicAngle = otm->otmItalicAngle;
- p.postscriptName = QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpFamilyName)).toLatin1();
- p.postscriptName += QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpStyleName)).toLatin1();
- p.postscriptName = QFontEngine::convertToPostscriptFontFamilyName(p.postscriptName);
- p.boundingBox = QRectF(otm->otmrcFontBox.left, -otm->otmrcFontBox.top,
- otm->otmrcFontBox.right - otm->otmrcFontBox.left,
- otm->otmrcFontBox.top - otm->otmrcFontBox.bottom);
- p.ascent = otm->otmAscent;
- p.descent = -otm->otmDescent;
- p.leading = (int)otm->otmLineGap;
- p.capHeight = 0;
- p.lineWidth = otm->otmsUnderscoreSize;
- free(otm);
- DeleteObject(SelectObject(hdc, oldfont));
- return p;
-}
-
-void QFontEngineWin::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics)
-{
- LOGFONT lf = logfont;
- lf.lfHeight = unitsPerEm;
- int flags = synthesized();
- if(flags & SynthesizedItalic)
- lf.lfItalic = false;
- lf.lfWidth = 0;
- HFONT hf = CreateFontIndirect(&lf);
- HDC hdc = shared_dc();
- HGDIOBJ oldfont = SelectObject(hdc, hf);
- QFixedPoint p;
- p.x = 0;
- p.y = 0;
- addGlyphToPath(glyph, p, hdc, path, ttf, metrics);
- DeleteObject(SelectObject(hdc, oldfont));
-}
-
-bool QFontEngineWin::getSfntTableData(uint tag, uchar *buffer, uint *length) const
-{
- if (!ttf)
- return false;
- HDC hdc = shared_dc();
- SelectObject(hdc, hfont);
- DWORD t = qbswap<quint32>(tag);
- *length = GetFontData(hdc, t, 0, buffer, *length);
- return *length != GDI_ERROR;
-}
-
-#if !defined(CLEARTYPE_QUALITY)
-# define CLEARTYPE_QUALITY 5
-#endif
-
-extern bool qt_cleartype_enabled;
-
-QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin,
- const QTransform &t, QImage::Format mask_format)
-{
- Q_UNUSED(mask_format)
- glyph_metrics_t gm = boundingBox(glyph);
-
-// printf(" -> for glyph %4x\n", glyph);
-
- int gx = gm.x.toInt();
- int gy = gm.y.toInt();
- int iw = gm.width.toInt();
- int ih = gm.height.toInt();
-
- if (iw <= 0 || iw <= 0)
- return 0;
-
- bool has_transformation = t.type() > QTransform::TxTranslate;
-
-#ifndef Q_WS_WINCE
- unsigned int options = ttf ? ETO_GLYPH_INDEX : 0;
- XFORM xform;
-
- if (has_transformation) {
- xform.eM11 = t.m11();
- xform.eM12 = t.m12();
- xform.eM21 = t.m21();
- xform.eM22 = t.m22();
- xform.eDx = margin;
- xform.eDy = margin;
-
- QtHDC qthdc;
- HDC hdc = qthdc.hdc();
-
- SetGraphicsMode(hdc, GM_ADVANCED);
- SetWorldTransform(hdc, &xform);
- HGDIOBJ old_font = SelectObject(hdc, font);
-
- int ggo_options = GGO_METRICS | (ttf ? GGO_GLYPH_INDEX : 0);
- GLYPHMETRICS tgm;
- MAT2 mat;
- memset(&mat, 0, sizeof(mat));
- mat.eM11.value = mat.eM22.value = 1;
-
- if (GetGlyphOutline(hdc, glyph, ggo_options, &tgm, 0, 0, &mat) == GDI_ERROR) {
- qWarning("QWinFontEngine: unable to query transformed glyph metrics...");
- return 0;
- }
-
- iw = tgm.gmBlackBoxX;
- ih = tgm.gmBlackBoxY;
-
- xform.eDx -= tgm.gmptGlyphOrigin.x;
- xform.eDy += tgm.gmptGlyphOrigin.y;
-
- SetGraphicsMode(hdc, GM_COMPATIBLE);
- SelectObject(hdc, old_font);
- }
-#else // else winc
- unsigned int options = 0;
-#ifdef DEBUG
- Q_ASSERT(!has_transformation);
-#else
- Q_UNUSED(has_transformation);
-#endif
-#endif
-
- QNativeImage *ni = new QNativeImage(iw + 2 * margin + 4,
- ih + 2 * margin + 4,
- QNativeImage::systemFormat(), !qt_cleartype_enabled);
-
- /*If cleartype is enabled we use the standard system format even on Windows CE
- and not the special textbuffer format we have to use if cleartype is disabled*/
-
- ni->image.fill(0xffffffff);
-
- HDC hdc = ni->hdc;
-
- SelectObject(hdc, GetStockObject(NULL_BRUSH));
- SelectObject(hdc, GetStockObject(BLACK_PEN));
- SetTextColor(hdc, RGB(0,0,0));
- SetBkMode(hdc, TRANSPARENT);
- SetTextAlign(hdc, TA_BASELINE);
-
- HGDIOBJ old_font = SelectObject(hdc, font);
-
-#ifndef Q_OS_WINCE
- if (has_transformation) {
- SetGraphicsMode(hdc, GM_ADVANCED);
- SetWorldTransform(hdc, &xform);
- ExtTextOut(hdc, 0, 0, options, 0, (LPCWSTR) &glyph, 1, 0);
- } else
-#endif
- {
- ExtTextOut(hdc, -gx + margin, -gy + margin, options, 0, (LPCWSTR) &glyph, 1, 0);
- }
-
- SelectObject(hdc, old_font);
- return ni;
-}
-
-
-extern uint qt_pow_gamma[256];
-
-QImage QFontEngineWin::alphaMapForGlyph(glyph_t glyph, const QTransform &xform)
-{
- HFONT font = hfont;
- if (qt_cleartype_enabled) {
- LOGFONT lf = logfont;
- lf.lfQuality = ANTIALIASED_QUALITY;
- font = CreateFontIndirect(&lf);
- }
- QImage::Format mask_format = QNativeImage::systemFormat();
-#ifndef Q_OS_WINCE
- mask_format = QImage::Format_RGB32;
-#endif
-
- QNativeImage *mask = drawGDIGlyph(font, glyph, 0, xform, mask_format);
- if (mask == 0)
- return QImage();
-
- QImage indexed(mask->width(), mask->height(), QImage::Format_Indexed8);
-
- // ### This part is kinda pointless, but we'll crash later if we don't because some
- // code paths expects there to be colortables for index8-bit...
- QVector<QRgb> colors(256);
- for (int i=0; i<256; ++i)
- colors[i] = qRgba(0, 0, 0, i);
- indexed.setColorTable(colors);
-
- // Copy data... Cannot use QPainter here as GDI has messed up the
- // Alpha channel of the ni.image pixels...
- for (int y=0; y<mask->height(); ++y) {
- uchar *dest = indexed.scanLine(y);
- if (mask->image.format() == QImage::Format_RGB16) {
- const qint16 *src = (qint16 *) ((const QImage &) mask->image).scanLine(y);
- for (int x=0; x<mask->width(); ++x)
- dest[x] = 255 - qGray(src[x]);
- } else {
- const uint *src = (uint *) ((const QImage &) mask->image).scanLine(y);
- for (int x=0; x<mask->width(); ++x) {
-#ifdef Q_OS_WINCE
- dest[x] = 255 - qGray(src[x]);
-#else
- if (QNativeImage::systemFormat() == QImage::Format_RGB16)
- dest[x] = 255 - qGray(src[x]);
- else
- dest[x] = 255 - (qt_pow_gamma[qGray(src[x])] * 255. / 2047.);
-#endif
- }
- }
- }
-
- // Cleanup...
- delete mask;
- if (qt_cleartype_enabled) {
- DeleteObject(font);
- }
-
- return indexed;
-}
-
-#define SPI_GETFONTSMOOTHINGCONTRAST 0x200C
-#define SPI_SETFONTSMOOTHINGCONTRAST 0x200D
-
-QImage QFontEngineWin::alphaRGBMapForGlyph(glyph_t glyph, QFixed, int margin, const QTransform &t)
-{
- HFONT font = hfont;
-
- int contrast;
- SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &contrast, 0);
- SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, (void *) 1000, 0);
-
- QNativeImage *mask = drawGDIGlyph(font, glyph, margin, t, QImage::Format_RGB32);
- SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, (void *) contrast, 0);
-
- if (mask == 0)
- return QImage();
-
- // Gracefully handle the odd case when the display is 16-bit
- const QImage source = mask->image.depth() == 32
- ? mask->image
- : mask->image.convertToFormat(QImage::Format_RGB32);
-
- QImage rgbMask(mask->width(), mask->height(), QImage::Format_RGB32);
- for (int y=0; y<mask->height(); ++y) {
- uint *dest = (uint *) rgbMask.scanLine(y);
- const uint *src = (uint *) source.scanLine(y);
- for (int x=0; x<mask->width(); ++x) {
- dest[x] = 0xffffffff - (0x00ffffff & src[x]);
- }
- }
-
- delete mask;
-
- return rgbMask;
-}
-
-// From qfontdatabase_win.cpp
-extern QFontEngine *qt_load_font_engine_win(const QFontDef &request);
-QFontEngine *QFontEngineWin::cloneWithSize(qreal pixelSize) const
-{
- QFontDef request = fontDef;
- QString actualFontName = request.family;
- if (!uniqueFamilyName.isEmpty())
- request.family = uniqueFamilyName;
- request.pixelSize = pixelSize;
-
- QFontEngine *fontEngine = qt_load_font_engine_win(request);
- if (fontEngine != NULL)
- fontEngine->fontDef.family = actualFontName;
-
- return fontEngine;
-}
-
-// -------------------------------------- Multi font engine
-
-QFontEngineMultiWin::QFontEngineMultiWin(QFontEngine *first, const QStringList &fallbacks)
- : QFontEngineMulti(fallbacks.size()+1),
- fallbacks(fallbacks)
-{
- engines[0] = first;
- first->ref.ref();
- fontDef = engines[0]->fontDef;
- cache_cost = first->cache_cost;
-}
-
-void QFontEngineMultiWin::loadEngine(int at)
-{
- Q_ASSERT(at < engines.size());
- Q_ASSERT(engines.at(at) == 0);
-
- QString fam = fallbacks.at(at-1);
-
- LOGFONT lf = static_cast<QFontEngineWin *>(engines.at(0))->logfont;
- memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded
- HFONT hfont = CreateFontIndirect(&lf);
-
- bool stockFont = false;
- if (hfont == 0) {
- hfont = (HFONT)GetStockObject(ANSI_VAR_FONT);
- stockFont = true;
- }
- engines[at] = new QFontEngineWin(fam, hfont, stockFont, lf);
- engines[at]->ref.ref();
- engines[at]->fontDef = fontDef;
-
- // TODO: increase cost in QFontCache for the font engine loaded here
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfontengine_win_p.h b/src/gui/text/qfontengine_win_p.h
deleted file mode 100644
index ebcafffceb..0000000000
--- a/src/gui/text/qfontengine_win_p.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFONTENGINE_WIN_P_H
-#define QFONTENGINE_WIN_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qconfig.h>
-
-QT_BEGIN_NAMESPACE
-
-class QNativeImage;
-
-class QFontEngineWin : public QFontEngine
-{
-public:
- QFontEngineWin(const QString &name, HFONT, bool, LOGFONT);
- ~QFontEngineWin();
-
- virtual QFixed lineThickness() const;
- virtual Properties properties() const;
- virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
- virtual FaceId faceId() const;
- virtual bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
- virtual int synthesized() const;
- virtual QFixed emSquareSize() const;
-
- virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
- virtual void recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags) const;
-
- virtual void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags);
- virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
- QPainterPath *path, QTextItem::RenderFlags flags);
-
- HGDIOBJ selectDesignFont() const;
-
- virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
- virtual glyph_metrics_t boundingBox(glyph_t g) { return boundingBox(g, QTransform()); }
- virtual glyph_metrics_t boundingBox(glyph_t g, const QTransform &t);
-
-
- virtual QFixed ascent() const;
- virtual QFixed descent() const;
- virtual QFixed leading() const;
- virtual QFixed xHeight() const;
- virtual QFixed averageCharWidth() const;
- virtual qreal maxCharWidth() const;
- virtual qreal minLeftBearing() const;
- virtual qreal minRightBearing() const;
-
- virtual const char *name() const;
-
- bool canRender(const QChar *string, int len);
-
- Type type() const;
-
- virtual QImage alphaMapForGlyph(glyph_t t) { return alphaMapForGlyph(t, QTransform()); }
- virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform);
- virtual QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
-
- virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
-
-#ifndef Q_CC_MINGW
- virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
-#endif
-
- int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs, bool mirrored) const;
- void getCMap();
-
-#ifndef Q_WS_WINCE
- bool getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const;
-#endif
-
- QString _name;
- QString uniqueFamilyName;
- HFONT hfont;
- LOGFONT logfont;
- uint stockFont : 1;
- uint ttf : 1;
- uint hasOutline : 1;
- TEXTMETRIC tm;
- int lw;
- const unsigned char *cmap;
- QByteArray cmapTable;
- mutable qreal lbearing;
- mutable qreal rbearing;
- QFixed designToDevice;
- int unitsPerEm;
- QFixed x_height;
- FaceId _faceId;
-
- mutable int synthesized_flags;
- mutable QFixed lineWidth;
- mutable unsigned char *widthCache;
- mutable uint widthCacheSize;
- mutable QFixed *designAdvances;
- mutable int designAdvancesSize;
-
-private:
- QNativeImage *drawGDIGlyph(HFONT font, glyph_t, int margin, const QTransform &xform,
- QImage::Format mask_format);
-
-};
-
-class QFontEngineMultiWin : public QFontEngineMulti
-{
-public:
- QFontEngineMultiWin(QFontEngine *first, const QStringList &fallbacks);
- void loadEngine(int at);
-
- QStringList fallbacks;
-};
-
-QT_END_NAMESPACE
-
-#endif // QFONTENGINE_WIN_P_H
diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp
deleted file mode 100644
index 490866c9fe..0000000000
--- a/src/gui/text/qfontengine_x11.cpp
+++ /dev/null
@@ -1,1205 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qbitmap.h"
-
-// #define FONTENGINE_DEBUG
-
-#include <qapplication.h>
-#include <qbytearray.h>
-#include <qdebug.h>
-#include <qtextcodec.h>
-#include <qthread.h>
-
-#include "qfontdatabase.h"
-#include "qpaintdevice.h"
-#include "qpainter.h"
-#include "qvarlengtharray.h"
-#include "qwidget.h"
-#include "qsettings.h"
-#include "qfile.h"
-
-#include <private/qpaintengine_x11_p.h>
-#include "qfont.h"
-#include "qfont_p.h"
-#include "qfontengine_p.h"
-#include <qhash.h>
-
-#include <private/qpainter_p.h>
-#include <private/qunicodetables_p.h>
-
-#include <private/qt_x11_p.h>
-#include <private/qpixmap_x11_p.h>
-#include "qx11info_x11.h"
-#include "qfontengine_x11_p.h"
-
-#include <limits.h>
-
-#include <ft2build.h>
-#if defined(FT_LCD_FILTER_H)
-#include FT_LCD_FILTER_H
-#endif
-
-#if defined(FC_LCD_FILTER)
-
-#ifndef FC_LCD_FILTER_NONE
-#define FC_LCD_FILTER_NONE FC_LCD_NONE
-#endif
-
-#ifndef FC_LCD_FILTER_DEFAULT
-#define FC_LCD_FILTER_DEFAULT FC_LCD_DEFAULT
-#endif
-
-#ifndef FC_LCD_FILTER_LIGHT
-#define FC_LCD_FILTER_LIGHT FC_LCD_LIGHT
-#endif
-
-#ifndef FC_LCD_FILTER_LEGACY
-#define FC_LCD_FILTER_LEGACY FC_LCD_LEGACY
-#endif
-
-#endif
-
-QT_BEGIN_NAMESPACE
-
-
-// ------------------------------------------------------------------
-// Multi XLFD engine
-// ------------------------------------------------------------------
-
-QFontEngineMultiXLFD::QFontEngineMultiXLFD(const QFontDef &r, const QList<int> &l, int s)
- : QFontEngineMulti(l.size()), encodings(l), screen(s), request(r)
-{
- loadEngine(0);
- fontDef = engines[0]->fontDef;
-}
-
-QFontEngineMultiXLFD::~QFontEngineMultiXLFD()
-{ }
-
-void QFontEngineMultiXLFD::loadEngine(int at)
-{
- Q_ASSERT(at < engines.size());
- Q_ASSERT(engines.at(at) == 0);
- const int encoding = encodings.at(at);
- QFontEngine *fontEngine = QFontDatabase::loadXlfd(0, QUnicodeTables::Common, request, encoding);
- Q_ASSERT(fontEngine != 0);
- fontEngine->ref.ref();
- engines[at] = fontEngine;
-}
-
-// ------------------------------------------------------------------
-// Xlfd font engine
-// ------------------------------------------------------------------
-
-#ifndef QT_NO_FREETYPE
-
-static QStringList *qt_fontpath = 0;
-
-static QStringList fontPath()
-{
- if (qt_fontpath)
- return *qt_fontpath;
-
- // append qsettings fontpath
- QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
- settings.beginGroup(QLatin1String("Qt"));
-
- QStringList fontpath;
-
- int npaths;
- char** font_path;
- font_path = XGetFontPath(X11->display, &npaths);
- bool xfsconfig_read = false;
- for (int i=0; i<npaths; i++) {
- // If we're using xfs, append font paths from /etc/X11/fs/config
- // can't hurt, and chances are we'll get all fonts that way.
- if (((font_path[i])[0] != '/') && !xfsconfig_read) {
- // We're using xfs -> read its config
- bool finished = false;
- QFile f(QLatin1String("/etc/X11/fs/config"));
- if (!f.exists())
- f.setFileName(QLatin1String("/usr/X11R6/lib/X11/fs/config"));
- if (!f.exists())
- f.setFileName(QLatin1String("/usr/X11/lib/X11/fs/config"));
- if (f.exists()) {
- f.open(QIODevice::ReadOnly);
- while (f.error()==QFile::NoError && !finished) {
- QString fs = QString::fromLocal8Bit(f.readLine(1024));
- fs=fs.trimmed();
- if (fs.left(9)==QLatin1String("catalogue") && fs.contains(QLatin1Char('='))) {
- fs = fs.mid(fs.indexOf(QLatin1Char('=')) + 1).trimmed();
- bool end = false;
- while (f.error()==QFile::NoError && !end) {
- if (fs[int(fs.length())-1] == QLatin1Char(','))
- fs = fs.left(fs.length()-1);
- else
- end = true;
-
- fs = fs.left(fs.indexOf(QLatin1String(":unscaled")));
- if (fs[0] != QLatin1Char('#'))
- fontpath += fs;
- fs = QLatin1String(f.readLine(1024));
- fs = fs.trimmed();
- if (fs.isEmpty())
- end = true;
- }
- finished = true;
- }
- }
- f.close();
- }
- xfsconfig_read = true;
- } else {
- QString fs = QString::fromLocal8Bit(font_path[i]);
- fontpath += fs.left(fs.indexOf(QLatin1String(":unscaled")));
- }
- }
- XFreeFontPath(font_path);
-
- // append qsettings fontpath
- QStringList fp = settings.value(QLatin1String("fontPath")).toStringList();
- if (!fp.isEmpty())
- fontpath += fp;
-
- qt_fontpath = new QStringList(fontpath);
- return fontpath;
-}
-
-static QFontEngine::FaceId fontFile(const QByteArray &_xname, QFreetypeFace **freetype, int *synth)
-{
- *freetype = 0;
- *synth = 0;
-
- QByteArray xname = _xname.toLower();
-
- int pos = 0;
- int minus = 0;
- while (minus < 5 && (pos = xname.indexOf('-', pos + 1)))
- ++minus;
- QByteArray searchname = xname.left(pos);
- while (minus < 12 && (pos = xname.indexOf('-', pos + 1)))
- ++minus;
- QByteArray encoding = xname.mid(pos + 1);
- //qDebug("xname='%s', searchname='%s', encoding='%s'", xname.data(), searchname.data(), encoding.data());
- QStringList fontpath = fontPath();
- QFontEngine::FaceId face_id;
- face_id.index = 0;
-
- QByteArray best_mapping;
-
- for (QStringList::ConstIterator it = fontpath.constBegin(); it != fontpath.constEnd(); ++it) {
- if (!(*it).startsWith(QLatin1Char('/')))
- continue; // not a path name, a font server
- QString fontmapname;
- int num = 0;
- // search font.dir and font.scale for the right file
- while (num < 2) {
- if (num == 0)
- fontmapname = (*it) + QLatin1String("/fonts.scale");
- else
- fontmapname = (*it) + QLatin1String("/fonts.dir");
- ++num;
- //qWarning(fontmapname);
- QFile fontmap(fontmapname);
- if (!fontmap.open(QIODevice::ReadOnly))
- continue;
- while (!fontmap.atEnd()) {
- QByteArray mapping = fontmap.readLine();
- QByteArray lmapping = mapping.toLower();
-
- //qWarning(xfontname);
- //qWarning(mapping);
- if (!lmapping.contains(searchname))
- continue;
- int index = mapping.indexOf(' ');
- QByteArray ffn = mapping.mid(0,index);
- // remove bitmap formats freetype can't handle
- if (ffn.contains(".spd") || ffn.contains(".phont"))
- continue;
- bool best_match = false;
- if (!best_mapping.isEmpty()) {
- if (lmapping.contains("-0-0-0-0-")) { // scalable font
- best_match = true;
- goto found;
- }
- if (lmapping.contains(encoding) && !best_mapping.toLower().contains(encoding))
- goto found;
- continue;
- }
-
- found:
- int colon = ffn.lastIndexOf(':');
- if (colon != -1) {
- QByteArray s = ffn.left(colon);
- ffn = ffn.mid(colon + 1);
- if (s.contains("ds="))
- *synth |= QFontEngine::SynthesizedBold;
- if (s.contains("ai="))
- *synth |= QFontEngine::SynthesizedItalic;
- }
- face_id.filename = (*it).toLocal8Bit() + '/' + ffn;
- best_mapping = mapping;
- if (best_match)
- goto end;
- }
- }
- }
-end:
-// qDebug("fontfile for %s is from '%s'\n got %s synth=%d", xname.data(),
-// best_mapping.data(), face_id.filename.data(), *synth);
- *freetype = QFreetypeFace::getFace(face_id);
- if (!*freetype) {
- face_id.index = 0;
- face_id.filename = QByteArray();
- }
- return face_id;
-}
-
-#endif // QT_NO_FREETYPE
-
-// defined in qfontdatabase_x11.cpp
-extern int qt_mib_for_xlfd_encoding(const char *encoding);
-extern int qt_xlfd_encoding_id(const char *encoding);
-
-static inline XCharStruct *charStruct(XFontStruct *xfs, uint ch)
-{
- XCharStruct *xcs = 0;
- unsigned char r = ch>>8;
- unsigned char c = ch&0xff;
- if (xfs->per_char &&
- r >= xfs->min_byte1 &&
- r <= xfs->max_byte1 &&
- c >= xfs->min_char_or_byte2 &&
- c <= xfs->max_char_or_byte2) {
- xcs = xfs->per_char + ((r - xfs->min_byte1) *
- (xfs->max_char_or_byte2 -
- xfs->min_char_or_byte2 + 1)) +
- (c - xfs->min_char_or_byte2);
- if (xcs->width == 0 && xcs->ascent == 0 && xcs->descent == 0)
- xcs = 0;
- }
- return xcs;
-}
-
-QFontEngineXLFD::QFontEngineXLFD(XFontStruct *fs, const QByteArray &name, int mib)
- : _fs(fs), _name(name), _codec(0), _cmap(mib)
-{
- if (_cmap) _codec = QTextCodec::codecForMib(_cmap);
-
- cache_cost = (((fs->max_byte1 - fs->min_byte1) *
- (fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1)) +
- fs->max_char_or_byte2 - fs->min_char_or_byte2);
- cache_cost = ((fs->max_bounds.ascent + fs->max_bounds.descent) *
- (fs->max_bounds.width * cache_cost / 8));
- lbearing = SHRT_MIN;
- rbearing = SHRT_MIN;
- face_id.index = -1;
- freetype = 0;
- synth = 0;
-}
-
-QFontEngineXLFD::~QFontEngineXLFD()
-{
- XFreeFont(QX11Info::display(), _fs);
- _fs = 0;
-#ifndef QT_NO_FREETYPE
- if (freetype)
- freetype->release(face_id);
-#endif
-}
-
-bool QFontEngineXLFD::stringToCMap(const QChar *s, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
-{
- if (*nglyphs < len) {
- *nglyphs = len;
- return false;
- }
-
- // filter out surrogates, we can't handle them anyway with XLFD fonts
- QVarLengthArray<ushort> _s(len);
- QChar *str = (QChar *)_s.data();
- for (int i = 0; i < len; ++i) {
- if (i < len - 1
- && s[i].unicode() >= 0xd800 && s[i].unicode() < 0xdc00
- && s[i+1].unicode() >= 0xdc00 && s[i].unicode() < 0xe000) {
- *str = QChar();
- ++i;
- } else {
- *str = s[i];
- }
- ++str;
- }
-
- len = str - (QChar *)_s.data();
- str = (QChar *)_s.data();
-
- bool mirrored = flags & QTextEngine::RightToLeft;
- if (_codec) {
- bool haveNbsp = false;
- for (int i = 0; i < len; i++)
- if (str[i].unicode() == 0xa0) {
- haveNbsp = true;
- break;
- }
-
- QVarLengthArray<unsigned short> ch(len);
- QChar *chars = (QChar *)ch.data();
- if (haveNbsp || mirrored) {
- for (int i = 0; i < len; i++)
- chars[i] = (str[i].unicode() == 0xa0 ? 0x20 :
- (mirrored ? QChar::mirroredChar(str[i].unicode()) : str[i].unicode()));
- } else {
- for (int i = 0; i < len; i++)
- chars[i] = str[i].unicode();
- }
- QTextCodec::ConverterState state;
- state.flags = QTextCodec::ConvertInvalidToNull;
- QByteArray ba = _codec->fromUnicode(chars, len, &state);
- if (ba.length() == 2*len) {
- // double byte encoding
- const uchar *data = (const uchar *)ba.constData();
- for (int i = 0; i < len; i++) {
- glyphs->glyphs[i] = ((ushort)data[0] << 8) + data[1];
- data += 2;
- }
- } else {
- const uchar *data = (const uchar *)ba.constData();
- for (int i = 0; i < len; i++)
- glyphs->glyphs[i] = (ushort)data[i];
- }
- } else {
- int i = len;
- const QChar *c = str + len;
- if (mirrored) {
- while (c != str)
- glyphs->glyphs[--i] = (--c)->unicode() == 0xa0 ? 0x20 : QChar::mirroredChar(c->unicode());
- } else {
- while (c != str)
- glyphs->glyphs[--i] = (--c)->unicode() == 0xa0 ? 0x20 : c->unicode();
- }
- }
- *nglyphs = len;
- glyphs->numGlyphs = len;
-
- if (!(flags & QTextEngine::GlyphIndicesOnly))
- recalcAdvances(glyphs, flags);
- return true;
-}
-
-void QFontEngineXLFD::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags /*flags*/) const
-{
- int i = glyphs->numGlyphs;
- XCharStruct *xcs;
- // inlined for better performance
- if (!_fs->per_char) {
- xcs = &_fs->min_bounds;
- while (i != 0) {
- --i;
- const unsigned char r = glyphs->glyphs[i] >> 8;
- const unsigned char c = glyphs->glyphs[i] & 0xff;
- if (r >= _fs->min_byte1 &&
- r <= _fs->max_byte1 &&
- c >= _fs->min_char_or_byte2 &&
- c <= _fs->max_char_or_byte2) {
- glyphs->advances_x[i] = xcs->width;
- } else {
- glyphs->glyphs[i] = 0;
- }
- }
- }
- else if (!_fs->max_byte1) {
- XCharStruct *base = _fs->per_char - _fs->min_char_or_byte2;
- while (i != 0) {
- unsigned int gl = glyphs->glyphs[--i];
- xcs = (gl >= _fs->min_char_or_byte2 && gl <= _fs->max_char_or_byte2) ?
- base + gl : 0;
- if (!xcs || (!xcs->width && !xcs->ascent && !xcs->descent)) {
- glyphs->glyphs[i] = 0;
- } else {
- glyphs->advances_x[i] = xcs->width;
- }
- }
- }
- else {
- while (i != 0) {
- xcs = charStruct(_fs, glyphs->glyphs[--i]);
- if (!xcs) {
- glyphs->glyphs[i] = 0;
- } else {
- glyphs->advances_x[i] = xcs->width;
- }
- }
- }
-}
-
-glyph_metrics_t QFontEngineXLFD::boundingBox(const QGlyphLayout &glyphs)
-{
- int i;
-
- glyph_metrics_t overall;
- // initialize with line height, we get the same behaviour on all platforms
- overall.y = -ascent();
- overall.height = ascent() + descent() + 1;
- QFixed ymax;
- QFixed xmax;
- for (i = 0; i < glyphs.numGlyphs; i++) {
- XCharStruct *xcs = charStruct(_fs, glyphs.glyphs[i]);
- if (xcs) {
- QFixed x = overall.xoff + glyphs.offsets[i].x + xcs->lbearing;
- QFixed y = overall.yoff + glyphs.offsets[i].y - xcs->ascent;
- overall.x = qMin(overall.x, x);
- overall.y = qMin(overall.y, y);
- // XCharStruct::rbearing is defined as distance from left edge to rightmost pixel
- xmax = qMax(xmax, overall.xoff + glyphs.offsets[i].x + xcs->rbearing);
- ymax = qMax(ymax, y + xcs->ascent + xcs->descent);
- overall.xoff += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
- } else {
- QFixed size = _fs->ascent;
- overall.x = qMin(overall.x, overall.xoff);
- overall.y = qMin(overall.y, overall.yoff - size);
- ymax = qMax(ymax, overall.yoff);
- overall.xoff += size;
- xmax = qMax(xmax, overall.xoff);
- }
- }
- overall.height = qMax(overall.height, ymax - overall.y);
- overall.width = xmax - overall.x;
-
- return overall;
-}
-
-glyph_metrics_t QFontEngineXLFD::boundingBox(glyph_t glyph)
-{
- glyph_metrics_t gm;
- XCharStruct *xcs = charStruct(_fs, glyph);
- if (xcs) {
- // XCharStruct::rbearing is defined as distance from left edge to rightmost pixel
- // XCharStruct::width is defined as the advance
- gm = glyph_metrics_t(xcs->lbearing, -xcs->ascent, xcs->rbearing- xcs->lbearing, xcs->ascent + xcs->descent,
- xcs->width, 0);
- } else {
- QFixed size = ascent();
- gm = glyph_metrics_t(0, size, size, size, size, 0);
- }
- return gm;
-}
-
-QFixed QFontEngineXLFD::ascent() const
-{
- return _fs->ascent;
-}
-
-QFixed QFontEngineXLFD::descent() const
-{
- return (_fs->descent-1);
-}
-
-QFixed QFontEngineXLFD::leading() const
-{
- QFixed l = QFixed(qMin<int>(_fs->ascent, _fs->max_bounds.ascent)
- + qMin<int>(_fs->descent, _fs->max_bounds.descent)) * QFixed::fromReal(0.15);
- return l.ceil();
-}
-
-qreal QFontEngineXLFD::maxCharWidth() const
-{
- return _fs->max_bounds.width;
-}
-
-
-// Loads the font for the specified script
-static inline int maxIndex(XFontStruct *f) {
- return (((f->max_byte1 - f->min_byte1) *
- (f->max_char_or_byte2 - f->min_char_or_byte2 + 1)) +
- f->max_char_or_byte2 - f->min_char_or_byte2);
-}
-
-qreal QFontEngineXLFD::minLeftBearing() const
-{
- if (lbearing == SHRT_MIN) {
- if (_fs->per_char) {
- XCharStruct *cs = _fs->per_char;
- int nc = maxIndex(_fs) + 1;
- int mx = cs->lbearing;
-
- for (int c = 1; c < nc; c++) {
- // ignore the bearings for characters whose ink is
- // completely outside the normal bounding box
- if ((cs[c].lbearing <= 0 && cs[c].rbearing <= 0) ||
- (cs[c].lbearing >= cs[c].width && cs[c].rbearing >= cs[c].width))
- continue;
-
- int nmx = cs[c].lbearing;
-
- if (nmx < mx)
- mx = nmx;
- }
-
- ((QFontEngineXLFD *)this)->lbearing = mx;
- } else
- ((QFontEngineXLFD *)this)->lbearing = _fs->min_bounds.lbearing;
- }
- return lbearing;
-}
-
-qreal QFontEngineXLFD::minRightBearing() const
-{
- if (rbearing == SHRT_MIN) {
- if (_fs->per_char) {
- XCharStruct *cs = _fs->per_char;
- int nc = maxIndex(_fs) + 1;
- int mx = cs->rbearing;
-
- for (int c = 1; c < nc; c++) {
- // ignore the bearings for characters whose ink is
- // completely outside the normal bounding box
- if ((cs[c].lbearing <= 0 && cs[c].rbearing <= 0) ||
- (cs[c].lbearing >= cs[c].width && cs[c].rbearing >= cs[c].width))
- continue;
-
- int nmx = cs[c].rbearing;
-
- if (nmx < mx)
- mx = nmx;
- }
-
- ((QFontEngineXLFD *)this)->rbearing = mx;
- } else
- ((QFontEngineXLFD *)this)->rbearing = _fs->min_bounds.rbearing;
- }
- return rbearing;
-}
-
-const char *QFontEngineXLFD::name() const
-{
- return _name;
-}
-
-bool QFontEngineXLFD::canRender(const QChar *string, int len)
-{
- QVarLengthGlyphLayoutArray glyphs(len);
- int nglyphs = len;
- if (stringToCMap(string, len, &glyphs, &nglyphs, 0) == false) {
- glyphs.resize(nglyphs);
- stringToCMap(string, len, &glyphs, &nglyphs, 0);
- }
-
- bool allExist = true;
- for (int i = 0; i < nglyphs; i++) {
- if (!glyphs.glyphs[i] || !charStruct(_fs, glyphs.glyphs[i])) {
- allExist = false;
- break;
- }
- }
-
- return allExist;
-}
-
-QBitmap QFontEngineXLFD::bitmapForGlyphs(const QGlyphLayout &glyphs, const glyph_metrics_t &metrics, QTextItem::RenderFlags flags)
-{
- int w = metrics.width.toInt();
- int h = metrics.height.toInt();
- if (w <= 0 || h <= 0)
- return QBitmap();
-
- QPixmapData *data = new QX11PixmapData(QPixmapData::BitmapType);
- data->resize(w, h);
- QPixmap bm(data);
- QPainter p(&bm);
- p.fillRect(0, 0, w, h, Qt::color0);
- p.setPen(Qt::color1);
-
- QTextItemInt item;
- item.flags = flags;
- item.ascent = -metrics.y;
- item.descent = metrics.height - item.ascent;
- item.width = metrics.width;
- item.chars = 0;
- item.num_chars = 0;
- item.logClusters = 0;
- item.glyphs = glyphs;
- item.fontEngine = this;
- item.f = 0;
-
- p.drawTextItem(QPointF(-metrics.x.toReal(), item.ascent.toReal()), item);
- p.end();
-
- return QBitmap(bm);
-}
-
-void QFontEngineXLFD::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
-{
- // cannot use QFontEngine::addBitmapFontToPath(), since we don't
- // have direct access to the glyph bitmaps, so we have to draw
- // onto a QBitmap, then convert to QImage, then to path
- glyph_metrics_t metrics = boundingBox(glyphs);
-
- QImage image = bitmapForGlyphs(glyphs, metrics, flags).toImage();
- if (image.isNull())
- return;
-
- image = image.convertToFormat(QImage::Format_Mono);
- const uchar *image_data = image.bits();
- uint bpl = image.bytesPerLine();
- // from qfontengine.cpp
- extern void qt_addBitmapToPath(qreal x0, qreal y0, const uchar *image_data,
- int bpl, int w, int h, QPainterPath *path);
- qt_addBitmapToPath(x, y + metrics.y.toReal(), image_data, bpl, image.width(), image.height(), path);
-}
-
-QFontEngine::FaceId QFontEngineXLFD::faceId() const
-{
-#ifndef QT_NO_FREETYPE
- if (face_id.index == -1) {
- face_id = fontFile(_name, &freetype, &synth);
- if (_codec)
- face_id.encoding = _codec->mibEnum();
- if (freetype) {
- const_cast<QFontEngineXLFD *>(this)->fsType = freetype->fsType();
- } else {
- face_id.index = 0;
- face_id.filename = '-' + QFontEngine::properties().postscriptName;
- }
- }
-#endif
-
- return face_id;
-}
-
-QFontEngine::Properties QFontEngineXLFD::properties() const
-{
- if (face_id.index == -1)
- (void)faceId();
-
-#ifndef QT_NO_FREETYPE
- if (freetype)
- return freetype->properties();
-#endif
- return QFontEngine::properties();
-}
-
-void QFontEngineXLFD::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics)
-{
- if (face_id.index == -1)
- (void)faceId();
-#ifndef QT_NO_FREETYPE
- if (!freetype)
-#endif
- {
- QFontEngine::getUnscaledGlyph(glyph, path, metrics);
- return;
- }
-
-#ifndef QT_NO_FREETYPE
- freetype->lock();
-
- FT_Face face = freetype->face;
- FT_Set_Char_Size(face, face->units_per_EM << 6, face->units_per_EM << 6, 0, 0);
- freetype->xsize = face->units_per_EM << 6;
- freetype->ysize = face->units_per_EM << 6;
- FT_Set_Transform(face, 0, 0);
- glyph = glyphIndexToFreetypeGlyphIndex(glyph);
- FT_Load_Glyph(face, glyph, FT_LOAD_NO_BITMAP);
-
- int left = face->glyph->metrics.horiBearingX;
- int right = face->glyph->metrics.horiBearingX + face->glyph->metrics.width;
- int top = face->glyph->metrics.horiBearingY;
- int bottom = face->glyph->metrics.horiBearingY - face->glyph->metrics.height;
-
- QFixedPoint p;
- p.x = 0;
- p.y = 0;
- metrics->width = QFixed::fromFixed(right-left);
- metrics->height = QFixed::fromFixed(top-bottom);
- metrics->x = QFixed::fromFixed(left);
- metrics->y = QFixed::fromFixed(-top);
- metrics->xoff = QFixed::fromFixed(face->glyph->advance.x);
-
- if (!FT_IS_SCALABLE(freetype->face))
- QFreetypeFace::addBitmapToPath(face->glyph, p, path);
- else
- QFreetypeFace::addGlyphToPath(face, face->glyph, p, path, face->units_per_EM << 6, face->units_per_EM << 6);
-
- FT_Set_Transform(face, &freetype->matrix, 0);
- freetype->unlock();
-#endif // QT_NO_FREETYPE
-}
-
-
-bool QFontEngineXLFD::getSfntTableData(uint tag, uchar *buffer, uint *length) const
-{
-#ifndef QT_NO_FREETYPE
- if (face_id.index == -1)
- (void)faceId();
- if (!freetype)
- return false;
- return freetype->getSfntTable(tag, buffer, length);
-#else
- Q_UNUSED(tag);
- Q_UNUSED(buffer);
- Q_UNUSED(length);
- return false;
-#endif
-}
-
-int QFontEngineXLFD::synthesized() const
-{
- return synth;
-}
-
-QImage QFontEngineXLFD::alphaMapForGlyph(glyph_t glyph)
-{
- glyph_metrics_t metrics = boundingBox(glyph);
-
-/*
- printf("a) w=%.2f, h=%.2f, xoff=%.2f, yoff=%.2f, x=%.2f, y=%.2f\n",
- metrics.width.toReal(),
- metrics.height.toReal(),
- metrics.xoff.toReal(),
- metrics.yoff.toReal(),
- metrics.x.toReal(),
- metrics.y.toReal());
-*/
-
- QGlyphLayoutArray<1> glyphs;
- glyphs.glyphs[0] = glyph;
-
- QImage image = bitmapForGlyphs(glyphs, metrics).toImage();
-//image.save(QString::fromLatin1("x11cache-%1.png").arg((int)glyph));
-
- image = image.convertToFormat(QImage::Format_Indexed8);
- QVector<QRgb> colors(256);
- for (int i = 0; i < 256; ++i)
- colors[i] = qRgba(0, 0, 0, i);
- image.setColorTable(colors);
-
- int width = image.width();
- int height = image.height();
- for (int y = 0; y < height; ++y) {
- uchar *bits = image.scanLine(y);
- for (int x = 0; x < width; ++x)
- bits[x] = ~(bits[x]-1);
- }
-
- return image;
-}
-
-#ifndef QT_NO_FREETYPE
-
-FT_Face QFontEngineXLFD::non_locked_face() const
-{
- return freetype ? freetype->face : 0;
-}
-
-uint QFontEngineXLFD::toUnicode(glyph_t g) const
-{
- if (_codec) {
- QTextCodec::ConverterState state;
- state.flags = QTextCodec::ConvertInvalidToNull;
- uchar data[2];
- int l = 1;
- if (g > 255) {
- data[0] = (g >> 8);
- data[1] = (g & 255);
- l = 2;
- } else {
- data[0] = g;
- }
- QString s = _codec->toUnicode((char *)data, l, &state);
- Q_ASSERT(s.length() == 1);
- g = s.at(0).unicode();
- }
- return g;
-}
-
-glyph_t QFontEngineXLFD::glyphIndexToFreetypeGlyphIndex(glyph_t g) const
-{
- return FT_Get_Char_Index(freetype->face, toUnicode(g));
-}
-#endif
-
-#ifndef QT_NO_FONTCONFIG
-
-// ------------------------------------------------------------------
-// Multi FT engine
-// ------------------------------------------------------------------
-
-static QFontEngine *engineForPattern(FcPattern *match, const QFontDef &request, int screen)
-{
- QFontEngineX11FT *engine = new QFontEngineX11FT(match, request, screen);
- if (!engine->invalid())
- return engine;
-
- delete engine;
- QFontEngine *fe = new QFontEngineBox(request.pixelSize);
- fe->fontDef = request;
- return fe;
-}
-
-QFontEngineMultiFT::QFontEngineMultiFT(QFontEngine *fe, FcPattern *matchedPattern, FcPattern *p, int s, const QFontDef &req)
- : QFontEngineMulti(2), request(req), pattern(p), fontSet(0), screen(s)
-{
- firstEnginePattern = FcPatternDuplicate(matchedPattern);
- engines[0] = fe;
- engines.at(0)->ref.ref();
- fontDef = engines[0]->fontDef;
- cache_cost = 100;
- firstFontIndex = 1;
-}
-
-QFontEngineMultiFT::~QFontEngineMultiFT()
-{
- extern QMutex *qt_fontdatabase_mutex();
- QMutexLocker locker(qt_fontdatabase_mutex());
-
- FcPatternDestroy(pattern);
- if (firstEnginePattern)
- FcPatternDestroy(firstEnginePattern);
- if (fontSet)
- FcFontSetDestroy(fontSet);
-}
-
-
-void QFontEngineMultiFT::loadEngine(int at)
-{
- extern QMutex *qt_fontdatabase_mutex();
- QMutexLocker locker(qt_fontdatabase_mutex());
-
- extern QFontDef qt_FcPatternToQFontDef(FcPattern *pattern, const QFontDef &);
- extern FcFontSet *qt_fontSetForPattern(FcPattern *pattern, const QFontDef &request);
-
- Q_ASSERT(at > 0);
- if (!fontSet) {
- fontSet = qt_fontSetForPattern(pattern, request);
-
- // it may happen that the fontset of fallbacks consists of only one font. In this case we
- // have to fall back to the box fontengine as we cannot render the glyph.
- if (fontSet->nfont == 1 && at == 1 && engines.size() == 2) {
- Q_ASSERT(engines.at(at) == 0);
- QFontEngine *fe = new QFontEngineBox(request.pixelSize);
- fe->fontDef = request;
- engines[at] = fe;
- return;
- }
-
- if (firstEnginePattern) {
-
- if (!FcPatternEqual(firstEnginePattern, fontSet->fonts[0]))
- firstFontIndex = 0;
-
- FcPatternDestroy(firstEnginePattern);
- firstEnginePattern = 0;
- }
-
- engines.resize(fontSet->nfont + 1 - firstFontIndex);
- }
- Q_ASSERT(at < engines.size());
- Q_ASSERT(engines.at(at) == 0);
-
- FcPattern *match = FcFontRenderPrepare(NULL, pattern, fontSet->fonts[at + firstFontIndex - 1]);
- QFontDef fontDef = qt_FcPatternToQFontDef(match, this->request);
-
- // note: we use -1 for the script to make sure that we keep real
- // FT engines separate from Multi engines in the font cache
- QFontCache::Key key(fontDef, -1, screen);
- QFontEngine *fontEngine = QFontCache::instance()->findEngine(key);
- if (!fontEngine) {
- fontEngine = engineForPattern(match, request, screen);
- QFontCache::instance()->insertEngine(key, fontEngine);
- }
- FcPatternDestroy(match);
- fontEngine->ref.ref();
- engines[at] = fontEngine;
-}
-
-// ------------------------------------------------------------------
-// X11 FT engine
-// ------------------------------------------------------------------
-
-
-
-Q_GUI_EXPORT void qt_x11ft_convert_pattern(FcPattern *pattern, QByteArray *file_name, int *index, bool *antialias)
-{
- FcChar8 *fileName;
- FcPatternGetString(pattern, FC_FILE, 0, &fileName);
- *file_name = (const char *)fileName;
- if (!FcPatternGetInteger(pattern, FC_INDEX, 0, index))
- index = 0;
- FcBool b;
- if (FcPatternGetBool(pattern, FC_ANTIALIAS, 0, &b) == FcResultMatch)
- *antialias = b;
-}
-
-
-QFontEngineX11FT::QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int screen)
- : QFontEngineFT(fd)
-{
-// FcPatternPrint(pattern);
-
- bool antialias = X11->fc_antialias;
- QByteArray file_name;
- int face_index;
- qt_x11ft_convert_pattern(pattern, &file_name, &face_index, &antialias);
- QFontEngine::FaceId face_id;
- face_id.filename = file_name;
- face_id.index = face_index;
-
- canUploadGlyphsToServer = QApplication::testAttribute(Qt::AA_X11InitThreads) || (qApp->thread() == QThread::currentThread());
-
- subpixelType = Subpixel_None;
- if (antialias) {
- int subpixel = X11->display ? X11->screens[screen].subpixel : FC_RGBA_UNKNOWN;
- if (subpixel == FC_RGBA_UNKNOWN)
- (void) FcPatternGetInteger(pattern, FC_RGBA, 0, &subpixel);
- if (!antialias || subpixel == FC_RGBA_UNKNOWN)
- subpixel = FC_RGBA_NONE;
-
- switch (subpixel) {
- case FC_RGBA_NONE: subpixelType = Subpixel_None; break;
- case FC_RGBA_RGB: subpixelType = Subpixel_RGB; break;
- case FC_RGBA_BGR: subpixelType = Subpixel_BGR; break;
- case FC_RGBA_VRGB: subpixelType = Subpixel_VRGB; break;
- case FC_RGBA_VBGR: subpixelType = Subpixel_VBGR; break;
- default: break;
- }
- }
-
- if (fd.hintingPreference != QFont::PreferDefaultHinting) {
- switch (fd.hintingPreference) {
- case QFont::PreferNoHinting:
- default_hint_style = HintNone;
- break;
- case QFont::PreferVerticalHinting:
- default_hint_style = HintLight;
- break;
- case QFont::PreferFullHinting:
- default:
- default_hint_style = HintFull;
- break;
- }
- }
-#ifdef FC_HINT_STYLE
- else {
- int hint_style = 0;
- // Try to use Xft.hintstyle from XDefaults first if running in GNOME, to match
- // the behavior of cairo
- if (X11->fc_hint_style > -1 && X11->desktopEnvironment == DE_GNOME)
- hint_style = X11->fc_hint_style;
- else if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch
- && X11->fc_hint_style > -1)
- hint_style = X11->fc_hint_style;
-
- switch (hint_style) {
- case FC_HINT_NONE:
- default_hint_style = HintNone;
- break;
- case FC_HINT_SLIGHT:
- default_hint_style = HintLight;
- break;
- case FC_HINT_MEDIUM:
- default_hint_style = HintMedium;
- break;
- default:
- default_hint_style = HintFull;
- break;
- }
- }
-#endif
-
-#if defined(FC_AUTOHINT) && defined(FT_LOAD_FORCE_AUTOHINT)
- {
- bool autohint = false;
-
- FcBool b;
- if (FcPatternGetBool(pattern, FC_AUTOHINT, 0, &b) == FcResultMatch)
- autohint = b;
-
- if (autohint)
- default_load_flags |= FT_LOAD_FORCE_AUTOHINT;
- }
-#endif
-
-#if defined(FC_LCD_FILTER) && defined(FT_LCD_FILTER_H)
- {
- int filter = FC_LCD_FILTER_NONE;
- if (FcPatternGetInteger(pattern, FC_LCD_FILTER, 0, &filter) == FcResultMatch) {
- switch (filter) {
- case FC_LCD_FILTER_NONE:
- lcdFilterType = FT_LCD_FILTER_NONE;
- break;
- case FC_LCD_FILTER_DEFAULT:
- lcdFilterType = FT_LCD_FILTER_DEFAULT;
- break;
- case FC_LCD_FILTER_LIGHT:
- lcdFilterType = FT_LCD_FILTER_LIGHT;
- break;
- case FC_LCD_FILTER_LEGACY:
- lcdFilterType = FT_LCD_FILTER_LEGACY;
- break;
- default:
- // new unknown lcd filter type?!
- break;
- }
- }
- }
-#endif
-
-#ifdef FC_EMBEDDED_BITMAP
- {
- FcBool b;
- if (FcPatternGetBool(pattern, FC_EMBEDDED_BITMAP, 0, &b) == FcResultMatch)
- embeddedbitmap = b;
- }
-#endif
-
- GlyphFormat defaultFormat = Format_None;
-
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- int format = PictStandardA8;
- if (!antialias)
- format = PictStandardA1;
- else if (subpixelType == Subpixel_RGB
- || subpixelType == Subpixel_BGR
- || subpixelType == Subpixel_VRGB
- || subpixelType == Subpixel_VBGR)
- format = PictStandardARGB32;
- xglyph_format = format;
-
- if (subpixelType != QFontEngineFT::Subpixel_None)
- defaultFormat = Format_A32;
- else if (antialias)
- defaultFormat = Format_A8;
- else
- defaultFormat = Format_Mono;
- }
-#endif
-
- if (!init(face_id, antialias, defaultFormat))
- return;
-
- if (!freetype->charset) {
- FcCharSet *cs;
- FcPatternGetCharSet (pattern, FC_CHARSET, 0, &cs);
- freetype->charset = FcCharSetCopy(cs);
- }
-}
-
-QFontEngineX11FT::~QFontEngineX11FT()
-{
- freeGlyphSets();
-}
-
-unsigned long QFontEngineX11FT::allocateServerGlyphSet()
-{
-#ifndef QT_NO_XRENDER
- if (!canUploadGlyphsToServer || !X11->use_xrender)
- return 0;
- return XRenderCreateGlyphSet(X11->display, XRenderFindStandardFormat(X11->display, xglyph_format));
-#else
- return 0;
-#endif
-}
-
-void QFontEngineX11FT::freeServerGlyphSet(unsigned long id)
-{
-#ifndef QT_NO_XRENDER
- if (!id)
- return;
- XRenderFreeGlyphSet(X11->display, id);
-#endif
-}
-
-bool QFontEngineX11FT::uploadGlyphToServer(QGlyphSet *set, uint glyphid, Glyph *g, GlyphInfo *info, int glyphDataSize) const
-{
-#ifndef QT_NO_XRENDER
- if (!canUploadGlyphsToServer)
- return false;
- if (g->format == Format_Mono) {
- /*
- * swap bit order around; FreeType is always MSBFirst
- */
- if (BitmapBitOrder(X11->display) != MSBFirst) {
- unsigned char *line = g->data;
- int i = glyphDataSize;
- while (i--) {
- unsigned char c;
- c = *line;
- c = ((c << 1) & 0xaa) | ((c >> 1) & 0x55);
- c = ((c << 2) & 0xcc) | ((c >> 2) & 0x33);
- c = ((c << 4) & 0xf0) | ((c >> 4) & 0x0f);
- *line++ = c;
- }
- }
- }
-
- ::Glyph xglyph = glyphid;
- XRenderAddGlyphs (X11->display, set->id, &xglyph, info, 1, (const char *)g->data, glyphDataSize);
- delete [] g->data;
- g->data = 0;
- g->format = Format_None;
- g->uploadedToServer = true;
- return true;
-#else
- return false;
-#endif
-}
-
-QFontEngine *QFontEngineX11FT::cloneWithSize(qreal pixelSize) const
-{
- QFontDef fontDef;
- fontDef.pixelSize = pixelSize;
- QFontEngineX11FT *fe = new QFontEngineX11FT(fontDef);
- if (!fe->initFromFontEngine(this)) {
- delete fe;
- return 0;
- } else {
-#ifndef QT_NO_XRENDER
- fe->xglyph_format = xglyph_format;
-#endif
- return fe;
- }
-}
-
-#endif // QT_NO_FONTCONFIG
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfontengine_x11_p.h b/src/gui/text/qfontengine_x11_p.h
deleted file mode 100644
index 1c0bcada11..0000000000
--- a/src/gui/text/qfontengine_x11_p.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFONTENGINE_X11_P_H
-#define QFONTENGINE_X11_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-#include <private/qt_x11_p.h>
-
-#include <private/qfontengine_ft_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QFreetypeFace;
-
-// --------------------------------------------------------------------------
-
-class QFontEngineMultiXLFD : public QFontEngineMulti
-{
-public:
- QFontEngineMultiXLFD(const QFontDef &r, const QList<int> &l, int s);
- ~QFontEngineMultiXLFD();
-
- void loadEngine(int at);
-
-private:
- QList<int> encodings;
- int screen;
- QFontDef request;
-};
-
-/**
- * \internal The font engine for X Logical Font Description (XLFD) fonts, which is for X11 systems without freetype.
- */
-class QFontEngineXLFD : public QFontEngine
-{
-public:
- QFontEngineXLFD(XFontStruct *f, const QByteArray &name, int mib);
- ~QFontEngineXLFD();
-
- virtual QFontEngine::FaceId faceId() const;
- QFontEngine::Properties properties() const;
- virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
- virtual bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
- virtual int synthesized() const;
-
- virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
- QTextEngine::ShaperFlags flags) const;
- virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
-
- virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
- virtual glyph_metrics_t boundingBox(glyph_t glyph);
-
- virtual void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags);
- virtual QFixed ascent() const;
- virtual QFixed descent() const;
- virtual QFixed leading() const;
- virtual qreal maxCharWidth() const;
- virtual qreal minLeftBearing() const;
- virtual qreal minRightBearing() const;
- virtual QImage alphaMapForGlyph(glyph_t);
-
- virtual inline Type type() const
- { return QFontEngine::XLFD; }
-
- virtual bool canRender(const QChar *string, int len);
- virtual const char *name() const;
-
- inline XFontStruct *fontStruct() const
- { return _fs; }
-
-#ifndef QT_NO_FREETYPE
- FT_Face non_locked_face() const;
- glyph_t glyphIndexToFreetypeGlyphIndex(glyph_t g) const;
-#endif
- uint toUnicode(glyph_t g) const;
-
-private:
- QBitmap bitmapForGlyphs(const QGlyphLayout &glyphs, const glyph_metrics_t &metrics, QTextItem::RenderFlags flags = 0);
-
- XFontStruct *_fs;
- QByteArray _name;
- QTextCodec *_codec;
- int _cmap;
- int lbearing, rbearing;
- mutable QFontEngine::FaceId face_id;
- mutable QFreetypeFace *freetype;
- mutable int synth;
-};
-
-#ifndef QT_NO_FONTCONFIG
-
-class Q_GUI_EXPORT QFontEngineMultiFT : public QFontEngineMulti
-{
-public:
- QFontEngineMultiFT(QFontEngine *fe, FcPattern *firstEnginePattern, FcPattern *p, int s, const QFontDef &request);
- ~QFontEngineMultiFT();
-
- void loadEngine(int at);
-
-private:
- QFontDef request;
- FcPattern *pattern;
- FcPattern *firstEnginePattern;
- FcFontSet *fontSet;
- int screen;
- int firstFontIndex; // first font in fontset
-};
-
-class Q_GUI_EXPORT QFontEngineX11FT : public QFontEngineFT
-{
-public:
- explicit QFontEngineX11FT(const QFontDef &fontDef) : QFontEngineFT(fontDef) {}
- explicit QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int screen);
- ~QFontEngineX11FT();
-
- QFontEngine *cloneWithSize(qreal pixelSize) const;
-
-#ifndef QT_NO_XRENDER
- int xglyph_format;
-#endif
-
-protected:
- virtual bool uploadGlyphToServer(QGlyphSet *set, uint glyphid, Glyph *g, GlyphInfo *info, int glyphDataSize) const;
- virtual unsigned long allocateServerGlyphSet();
- virtual void freeServerGlyphSet(unsigned long id);
-};
-
-#endif // QT_NO_FONTCONFIG
-
-QT_END_NAMESPACE
-
-#endif // QFONTENGINE_X11_P_H
diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h
index a23bb34e0d..f21e820556 100644
--- a/src/gui/text/qfontmetrics.h
+++ b/src/gui/text/qfontmetrics.h
@@ -120,15 +120,6 @@ public:
bool operator==(const QFontMetrics &other) const;
inline bool operator !=(const QFontMetrics &other) const { return !operator==(other); }
-#ifdef QT3_SUPPORT
- inline QRect boundingRect(const QString &text, int len) const
- { return boundingRect(text.left(len)); }
- inline QRect boundingRect(int x, int y, int w, int h, int flags, const QString& str, int len,
- int tabstops=0, int *tabarray=0) const
- { return boundingRect(QRect(x, y, w, h), flags, str.left(len), tabstops, tabarray); }
- inline QSize size(int flags, const QString& str, int len, int tabstops=0, int *tabarray=0) const
- { return size(flags, str.left(len), tabstops, tabarray); }
-#endif
private:
#if defined(Q_WS_MAC)
friend class QFontPrivate;
diff --git a/src/gui/text/qfontsubset.cpp b/src/gui/text/qfontsubset.cpp
index ccb1f247da..dc2a14a52a 100644
--- a/src/gui/text/qfontsubset.cpp
+++ b/src/gui/text/qfontsubset.cpp
@@ -57,8 +57,6 @@
#include FT_FREETYPE_H
#endif
-#ifndef QT_NO_PRINTER
-
QT_BEGIN_NAMESPACE
static const char * const agl =
@@ -1493,251 +1491,4 @@ QByteArray QFontSubset::toTruetype() const
return bindFont(tables);
}
-// ------------------ Type 1 generation ---------------------------
-
-// needs at least 6 bytes of space in tmp
-static const char *encodeNumber(int num, char *tmp)
-{
- const char *ret = tmp;
- if(num >= -107 && num <= 107) {
- QPdf::toHex((uchar)(num + 139), tmp);
- tmp += 2;
- } else if (num > 107 && num <= 1131) {
- num -= 108;
- QPdf::toHex((uchar)((num >> 8) + 247), tmp);
- tmp += 2;
- QPdf::toHex((uchar)(num & 0xff), tmp);
- tmp += 2;
- } else if(num < - 107 && num >= -1131) {
- num += 108;
- num = -num;
- QPdf::toHex((uchar)((num >> 8) + 251), tmp);
- tmp += 2;
- QPdf::toHex((uchar)(num & 0xff), tmp);
- tmp += 2;
- } else {
- *tmp++ = 'f';
- *tmp++ = 'f';
- QPdf::toHex((uchar)(num >> 24), tmp);
- tmp += 2;
- QPdf::toHex((uchar)(num >> 16), tmp);
- tmp += 2;
- QPdf::toHex((uchar)(num >> 8), tmp);
- tmp += 2;
- QPdf::toHex((uchar)(num >> 0), tmp);
- tmp += 2;
- }
- *tmp = 0;
-// qDebug("encodeNumber: %d -> '%s'", num, ret);
- return ret;
-}
-
-static QByteArray charString(const QPainterPath &path, qreal advance, qreal lsb, qreal ppem)
-{
- // the charstring commands we need
- const char *hsbw = "0D";
- const char *closepath = "09";
- const char *moveto[3] = { "16", "04", "15" };
- const char *lineto[3] = { "06", "07", "05" };
- const char *rcurveto = "08";
- const char *endchar = "0E";
-
- enum { horizontal = 1, vertical = 2 };
-
- char tmp[16];
-
- qreal factor = 1000./ppem;
-
- int lsb_i = qRound(lsb*factor);
- int advance_i = qRound(advance*factor);
-// qDebug("--- charstring");
-
- // first of all add lsb and width to the charstring using the hsbw command
- QByteArray charstring;
- charstring += encodeNumber(lsb_i, tmp);
- charstring += encodeNumber(advance_i, tmp);
- charstring += hsbw;
-
- // add the path
- int xl = lsb_i;
- int yl = 0;
- bool openpath = false;
- for (int i = 0; i < path.elementCount(); ++i) {
- const QPainterPath::Element &elm = path.elementAt(i);
- int x = qRound(elm.x*factor);
- int y = -qRound(elm.y*factor);
- int dx = x - xl;
- int dy = y - yl;
- if (elm.type == QPainterPath::MoveToElement && openpath) {
-// qDebug("closepath %s", closepath);
- charstring += closepath;
- }
- if (elm.type == QPainterPath::MoveToElement ||
- elm.type == QPainterPath::LineToElement) {
- int type = -1;
- if (dx || !dy) {
- charstring += encodeNumber(dx, tmp);
- type += horizontal;
-// qDebug("horizontal");
- }
- if (dy) {
- charstring += encodeNumber(dy, tmp);
- type += vertical;
-// qDebug("vertical");
- }
-// qDebug("moveto/lineto %s", (elm.type == QPainterPath::MoveToElement ? moveto[type] : lineto[type]));
- charstring += (elm.type == QPainterPath::MoveToElement ? moveto[type] : lineto[type]);
- openpath = true;
- xl = x;
- yl = y;
- } else {
- Q_ASSERT(elm.type == QPainterPath::CurveToElement);
- const QPainterPath::Element &elm2 = path.elementAt(++i);
- const QPainterPath::Element &elm3 = path.elementAt(++i);
- int x2 = qRound(elm2.x*factor);
- int y2 = -qRound(elm2.y*factor);
- int x3 = qRound(elm3.x*factor);
- int y3 = -qRound(elm3.y*factor);
- charstring += encodeNumber(dx, tmp);
- charstring += encodeNumber(dy, tmp);
- charstring += encodeNumber(x2 - x, tmp);
- charstring += encodeNumber(y2 - y, tmp);
- charstring += encodeNumber(x3 - x2, tmp);
- charstring += encodeNumber(y3 - y2, tmp);
- charstring += rcurveto;
- openpath = true;
- xl = x3;
- yl = y3;
-// qDebug("rcurveto");
- }
- }
- if (openpath)
- charstring += closepath;
- charstring += endchar;
- if (charstring.length() > 240) {
- int pos = 240;
- while (pos < charstring.length()) {
- charstring.insert(pos, '\n');
- pos += 241;
- }
- }
- return charstring;
-}
-
-#ifndef QT_NO_FREETYPE
-static const char *helvetica_styles[4] = {
- "Helvetica",
- "Helvetica-Bold",
- "Helvetica-Oblique",
- "Helvetica-BoldOblique"
-};
-static const char *times_styles[4] = {
- "Times-Regular",
- "Times-Bold",
- "Times-Italic",
- "Times-BoldItalic"
-};
-static const char *courier_styles[4] = {
- "Courier",
- "Courier-Bold",
- "Courier-Oblique",
- "Courier-BoldOblique"
-};
-#endif
-
-QByteArray QFontSubset::toType1() const
-{
- QFontEngine::Properties properties = fontEngine->properties();
- QVector<int> reverseMap = getReverseMap();
-
- QByteArray font;
- QPdf::ByteStream s(&font);
-
- QByteArray id = QByteArray::number(object_id);
- QByteArray psname = properties.postscriptName;
- psname.replace(' ', "");
-
- standard_font = false;
-
-#ifndef QT_NO_FREETYPE
- FT_Face face = ft_face(fontEngine);
- if (face && !FT_IS_SCALABLE(face)) {
- int style = 0;
- if (fontEngine->fontDef.style)
- style += 2;
- if (fontEngine->fontDef.weight >= QFont::Bold)
- style++;
- if (fontEngine->fontDef.family.contains(QLatin1String("Helvetica"))) {
- psname = helvetica_styles[style];
- standard_font = true;
- } else if (fontEngine->fontDef.family.contains(QLatin1String("Times"))) {
- psname = times_styles[style];
- standard_font = true;
- } else if (fontEngine->fontDef.family.contains(QLatin1String("Courier"))) {
- psname = courier_styles[style];
- standard_font = true;
- }
- }
-#endif
- s << "/F" << id << "-Base\n";
- if (standard_font) {
- s << '/' << psname << " findfont\n"
- "0 dict copy dup /NumGlyphs 0 put dup /CMap 256 array put def\n";
- } else {
- s << "<<\n";
- if(!psname.isEmpty())
- s << "/FontName /" << psname << '\n';
- s << "/FontInfo <</FsType " << (int)fontEngine->fsType << ">>\n"
- "/FontType 1\n"
- "/PaintType 0\n"
- "/FontMatrix [.001 0 0 .001 0 0]\n"
- "/FontBBox { 0 0 0 0 }\n"
- "/Private <<\n"
- "/password 5839\n"
- "/MinFeature {16 16}\n"
- "/BlueValues []\n"
- "/lenIV -1\n"
- ">>\n"
- "/CharStrings << >>\n"
- "/NumGlyphs 0\n"
- "/CMap 256 array\n"
- ">> def\n";
- }
- s << type1AddedGlyphs();
- downloaded_glyphs = glyph_indices.size();
-
- return font;
-}
-
-QByteArray QFontSubset::type1AddedGlyphs() const
-{
- if (downloaded_glyphs == glyph_indices.size())
- return QByteArray();
-
- QFontEngine::Properties properties = fontEngine->properties();
- QVector<int> reverseMap = getReverseMap();
- QByteArray glyphs;
- QPdf::ByteStream s(&glyphs);
-
- int nGlyphs = glyph_indices.size();
- QByteArray id = QByteArray::number(object_id);
-
- s << 'F' << id << "-Base [\n";
- for (int i = downloaded_glyphs; i < nGlyphs; ++i) {
- glyph_t g = glyph_indices.at(i);
- QPainterPath path;
- glyph_metrics_t metric;
- fontEngine->getUnscaledGlyph(g, &path, &metric);
- QByteArray charstring = charString(path, metric.xoff.toReal(), metric.x.toReal(),
- properties.emSquare.toReal());
- s << glyphName(i, reverseMap);
- if (!standard_font)
- s << "\n<" << charstring << ">\n";
- }
- s << (standard_font ? "] T1AddMapping\n" : "] T1AddGlyphs\n");
- return glyphs;
-}
-
QT_END_NAMESPACE
-
-#endif // QT_NO_PRINTER
diff --git a/src/gui/text/qfontsubset_p.h b/src/gui/text/qfontsubset_p.h
index 7b9b47486c..a99236f4cc 100644
--- a/src/gui/text/qfontsubset_p.h
+++ b/src/gui/text/qfontsubset_p.h
@@ -55,8 +55,6 @@
#include "private/qfontengine_p.h"
-#ifndef QT_NO_PRINTER
-
QT_BEGIN_NAMESPACE
class QFontSubset
@@ -71,8 +69,6 @@ public:
}
QByteArray toTruetype() const;
- QByteArray toType1() const;
- QByteArray type1AddedGlyphs() const;
QByteArray widthArray() const;
QByteArray createToUnicodeMap() const;
QVector<int> getReverseMap() const;
@@ -94,6 +90,4 @@ public:
QT_END_NAMESPACE
-#endif // QT_NO_PRINTER
-
#endif // QFONTSUBSET_P_H
diff --git a/src/gui/text/qlinecontrol.cpp b/src/gui/text/qlinecontrol.cpp
new file mode 100644
index 0000000000..36c064ee40
--- /dev/null
+++ b/src/gui/text/qlinecontrol.cpp
@@ -0,0 +1,1711 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// ###
+#define QT_NO_ACCESSIBILITY
+#define QT_NO_IM
+
+#include "qlinecontrol_p.h"
+
+#ifndef QT_NO_LINEEDIT
+
+#include "qclipboard.h"
+#ifndef QT_NO_ACCESSIBILITY
+#include "qaccessible.h"
+#endif
+#ifndef QT_NO_IM
+#include "qinputcontext.h"
+#include "qlist.h"
+#endif
+#include "qguiapplication.h"
+
+QT_BEGIN_NAMESPACE
+
+// ### these should come from the application
+const int startDragDistance = 10;
+const int cursorFlashTime = 2000;
+const int textCursorWidth = 1;
+const bool fullWidthSelection = true;
+
+/*!
+ \internal
+
+ Updates the display text based of the current edit text
+ If the text has changed will emit displayTextChanged()
+*/
+void QLineControl::updateDisplayText(bool forceUpdate)
+{
+ QString orig = m_textLayout.text();
+ QString str;
+ if (m_echoMode == NoEcho)
+ str = QString::fromLatin1("");
+ else
+ str = m_text;
+
+ if (m_echoMode == Password || (m_echoMode == PasswordEchoOnEdit
+ && !m_passwordEchoEditing))
+ str.fill(m_passwordCharacter);
+
+ // replace certain non-printable characters with spaces (to avoid
+ // drawing boxes when using fonts that don't have glyphs for such
+ // characters)
+ QChar* uc = str.data();
+ for (int i = 0; i < (int)str.length(); ++i) {
+ if ((uc[i] < 0x20 && uc[i] != 0x09)
+ || uc[i] == QChar::LineSeparator
+ || uc[i] == QChar::ParagraphSeparator
+ || uc[i] == QChar::ObjectReplacementCharacter)
+ uc[i] = QChar(0x0020);
+ }
+
+ m_textLayout.setText(str);
+
+ QTextOption option;
+ option.setTextDirection(m_layoutDirection);
+ option.setFlags(QTextOption::IncludeTrailingSpaces);
+ m_textLayout.setTextOption(option);
+
+ m_textLayout.beginLayout();
+ QTextLine l = m_textLayout.createLine();
+ m_textLayout.endLayout();
+ m_ascent = qRound(l.ascent());
+
+ if (str != orig || forceUpdate)
+ emit displayTextChanged(str);
+}
+
+#ifndef QT_NO_CLIPBOARD
+/*!
+ \internal
+
+ Copies the currently selected text into the clipboard using the given
+ \a mode.
+
+ \note If the echo mode is set to a mode other than Normal then copy
+ will not work. This is to prevent using copy as a method of bypassing
+ password features of the line control.
+*/
+void QLineControl::copy(QClipboard::Mode mode) const
+{
+ QString t = selectedText();
+ if (!t.isEmpty() && m_echoMode == Normal) {
+ disconnect(QGuiApplication::clipboard(), SIGNAL(selectionChanged()), this, 0);
+ QGuiApplication::clipboard()->setText(t, mode);
+ connect(QGuiApplication::clipboard(), SIGNAL(selectionChanged()),
+ this, SLOT(_q_clipboardChanged()));
+ }
+}
+
+/*!
+ \internal
+
+ Inserts the text stored in the application clipboard into the line
+ control.
+
+ \sa insert()
+*/
+void QLineControl::paste(QClipboard::Mode clipboardMode)
+{
+ QString clip = QGuiApplication::clipboard()->text(clipboardMode);
+ if (!clip.isEmpty() || hasSelectedText()) {
+ separate(); //make it a separate undo/redo command
+ insert(clip);
+ separate();
+ }
+}
+
+#endif // !QT_NO_CLIPBOARD
+
+/*!
+ \internal
+
+ Handles the behavior for the backspace key or function.
+ Removes the current selection if there is a selection, otherwise
+ removes the character prior to the cursor position.
+
+ \sa del()
+*/
+void QLineControl::backspace()
+{
+ int priorState = m_undoState;
+ if (hasSelectedText()) {
+ removeSelectedText();
+ } else if (m_cursor) {
+ --m_cursor;
+ if (m_maskData)
+ m_cursor = prevMaskBlank(m_cursor);
+ QChar uc = m_text.at(m_cursor);
+ if (m_cursor > 0 && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) {
+ // second half of a surrogate, check if we have the first half as well,
+ // if yes delete both at once
+ uc = m_text.at(m_cursor - 1);
+ if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) {
+ internalDelete(true);
+ --m_cursor;
+ }
+ }
+ internalDelete(true);
+ }
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Handles the behavior for the delete key or function.
+ Removes the current selection if there is a selection, otherwise
+ removes the character after the cursor position.
+
+ \sa del()
+*/
+void QLineControl::del()
+{
+ int priorState = m_undoState;
+ if (hasSelectedText()) {
+ removeSelectedText();
+ } else {
+ int n = m_textLayout.nextCursorPosition(m_cursor) - m_cursor;
+ while (n--)
+ internalDelete();
+ }
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Inserts the given \a newText at the current cursor position.
+ If there is any selected text it is removed prior to insertion of
+ the new text.
+*/
+void QLineControl::insert(const QString &newText)
+{
+ int priorState = m_undoState;
+ removeSelectedText();
+ internalInsert(newText);
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Clears the line control text.
+*/
+void QLineControl::clear()
+{
+ int priorState = m_undoState;
+ m_selstart = 0;
+ m_selend = m_text.length();
+ removeSelectedText();
+ separate();
+ finishChange(priorState, /*update*/false, /*edited*/false);
+}
+
+/*!
+ \internal
+
+ Sets \a length characters from the given \a start position as selected.
+ The given \a start position must be within the current text for
+ the line control. If \a length characters cannot be selected, then
+ the selection will extend to the end of the current text.
+*/
+void QLineControl::setSelection(int start, int length)
+{
+ if(start < 0 || start > (int)m_text.length()){
+ qWarning("QLineControl::setSelection: Invalid start position");
+ return;
+ }
+
+ if (length > 0) {
+ if (start == m_selstart && start + length == m_selend)
+ return;
+ m_selstart = start;
+ m_selend = qMin(start + length, (int)m_text.length());
+ m_cursor = m_selend;
+ } else if (length < 0){
+ if (start == m_selend && start + length == m_selstart)
+ return;
+ m_selstart = qMax(start + length, 0);
+ m_selend = start;
+ m_cursor = m_selstart;
+ } else if (m_selstart != m_selend) {
+ m_selstart = 0;
+ m_selend = 0;
+ m_cursor = start;
+ } else {
+ m_cursor = start;
+ emitCursorPositionChanged();
+ return;
+ }
+ emit selectionChanged();
+ emitCursorPositionChanged();
+}
+
+void QLineControl::_q_clipboardChanged()
+{
+}
+
+void QLineControl::_q_deleteSelected()
+{
+ if (!hasSelectedText())
+ return;
+
+ int priorState = m_undoState;
+ emit resetInputContext();
+ removeSelectedText();
+ separate();
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Initializes the line control with a starting text value of \a txt.
+*/
+void QLineControl::init(const QString &txt)
+{
+ m_text = txt;
+ updateDisplayText();
+ m_cursor = m_text.length();
+}
+
+/*!
+ \internal
+
+ Sets the password echo editing to \a editing. If password echo editing
+ is true, then the text of the password is displayed even if the echo
+ mode is set to QLineEdit::PasswordEchoOnEdit. Password echoing editing
+ does not affect other echo modes.
+*/
+void QLineControl::updatePasswordEchoEditing(bool editing)
+{
+ m_passwordEchoEditing = editing;
+ updateDisplayText();
+}
+
+/*!
+ \internal
+
+ Returns the cursor position of the given \a x pixel value in relation
+ to the displayed text. The given \a betweenOrOn specified what kind
+ of cursor position is requested.
+*/
+int QLineControl::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const
+{
+ return m_textLayout.lineAt(0).xToCursor(x, betweenOrOn);
+}
+
+/*!
+ \internal
+
+ Returns the bounds of the current cursor, as defined as a
+ between characters cursor.
+*/
+QRect QLineControl::cursorRect() const
+{
+ QTextLine l = m_textLayout.lineAt(0);
+ int c = m_cursor;
+ if (m_preeditCursor != -1)
+ c += m_preeditCursor;
+ int cix = qRound(l.cursorToX(c));
+ int w = m_cursorWidth;
+ int ch = l.height() + 1;
+
+ return QRect(cix-5, 0, w+9, ch);
+}
+
+/*!
+ \internal
+
+ Fixes the current text so that it is valid given any set validators.
+
+ Returns true if the text was changed. Otherwise returns false.
+*/
+bool QLineControl::fixup() // this function assumes that validate currently returns != Acceptable
+{
+#ifndef QT_NO_VALIDATOR
+ if (m_validator) {
+ QString textCopy = m_text;
+ int cursorCopy = m_cursor;
+ m_validator->fixup(textCopy);
+ if (m_validator->validate(textCopy, cursorCopy) == QValidator::Acceptable) {
+ if (textCopy != m_text || cursorCopy != m_cursor)
+ internalSetText(textCopy, cursorCopy);
+ return true;
+ }
+ }
+#endif
+ return false;
+}
+
+/*!
+ \internal
+
+ Moves the cursor to the given position \a pos. If \a mark is true will
+ adjust the currently selected text.
+*/
+void QLineControl::moveCursor(int pos, bool mark)
+{
+ if (pos != m_cursor) {
+ separate();
+ if (m_maskData)
+ pos = pos > m_cursor ? nextMaskBlank(pos) : prevMaskBlank(pos);
+ }
+ if (mark) {
+ int anchor;
+ if (m_selend > m_selstart && m_cursor == m_selstart)
+ anchor = m_selend;
+ else if (m_selend > m_selstart && m_cursor == m_selend)
+ anchor = m_selstart;
+ else
+ anchor = m_cursor;
+ m_selstart = qMin(anchor, pos);
+ m_selend = qMax(anchor, pos);
+ updateDisplayText();
+ } else {
+ internalDeselect();
+ }
+ m_cursor = pos;
+ if (mark || m_selDirty) {
+ m_selDirty = false;
+ emit selectionChanged();
+ }
+ emitCursorPositionChanged();
+}
+
+/*!
+ \internal
+
+ Applies the given input method event \a event to the text of the line
+ control
+*/
+void QLineControl::processInputMethodEvent(QInputMethodEvent *event)
+{
+ int priorState = 0;
+ bool isGettingInput = !event->commitString().isEmpty()
+ || event->preeditString() != preeditAreaText()
+ || event->replacementLength() > 0;
+ bool cursorPositionChanged = false;
+
+ if (isGettingInput) {
+ // If any text is being input, remove selected text.
+ priorState = m_undoState;
+ if (echoMode() == PasswordEchoOnEdit && !passwordEchoEditing()) {
+ updatePasswordEchoEditing(true);
+ m_selstart = 0;
+ m_selend = m_text.length();
+ }
+ removeSelectedText();
+ }
+
+ int c = m_cursor; // cursor position after insertion of commit string
+ if (event->replacementStart() <= 0)
+ c += event->commitString().length() - qMin(-event->replacementStart(), event->replacementLength());
+
+ m_cursor += event->replacementStart();
+ if (m_cursor < 0)
+ m_cursor = 0;
+
+ // insert commit string
+ if (event->replacementLength()) {
+ m_selstart = m_cursor;
+ m_selend = m_selstart + event->replacementLength();
+ removeSelectedText();
+ }
+ if (!event->commitString().isEmpty()) {
+ internalInsert(event->commitString());
+ cursorPositionChanged = true;
+ }
+
+ m_cursor = qBound(0, c, m_text.length());
+
+ for (int i = 0; i < event->attributes().size(); ++i) {
+ const QInputMethodEvent::Attribute &a = event->attributes().at(i);
+ if (a.type == QInputMethodEvent::Selection) {
+ m_cursor = qBound(0, a.start + a.length, m_text.length());
+ if (a.length) {
+ m_selstart = qMax(0, qMin(a.start, m_text.length()));
+ m_selend = m_cursor;
+ if (m_selend < m_selstart) {
+ qSwap(m_selstart, m_selend);
+ }
+ } else {
+ m_selstart = m_selend = 0;
+ }
+ cursorPositionChanged = true;
+ }
+ }
+#ifndef QT_NO_IM
+ setPreeditArea(m_cursor, event->preeditString());
+#endif //QT_NO_IM
+ const int oldPreeditCursor = m_preeditCursor;
+ m_preeditCursor = event->preeditString().length();
+ m_hideCursor = false;
+ QList<QTextLayout::FormatRange> formats;
+ for (int i = 0; i < event->attributes().size(); ++i) {
+ const QInputMethodEvent::Attribute &a = event->attributes().at(i);
+ if (a.type == QInputMethodEvent::Cursor) {
+ m_preeditCursor = a.start;
+ m_hideCursor = !a.length;
+ } else if (a.type == QInputMethodEvent::TextFormat) {
+ QTextCharFormat f = qvariant_cast<QTextFormat>(a.value).toCharFormat();
+ if (f.isValid()) {
+ QTextLayout::FormatRange o;
+ o.start = a.start + m_cursor;
+ o.length = a.length;
+ o.format = f;
+ formats.append(o);
+ }
+ }
+ }
+ m_textLayout.setAdditionalFormats(formats);
+ updateDisplayText(/*force*/ true);
+ if (cursorPositionChanged)
+ emitCursorPositionChanged();
+ else if (m_preeditCursor != oldPreeditCursor)
+ emit updateMicroFocus();
+ if (isGettingInput)
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Draws the display text for the line control using the given
+ \a painter, \a clip, and \a offset. Which aspects of the display text
+ are drawn is specified by the given \a flags.
+
+ If the flags contain DrawSelections, then the selection or input mask
+ backgrounds and foregrounds will be applied before drawing the text.
+
+ If the flags contain DrawCursor a cursor of the current cursorWidth()
+ will be drawn after drawing the text.
+
+ The display text will only be drawn if the flags contain DrawText
+*/
+void QLineControl::draw(QPainter *painter, const QPoint &offset, const QRect &clip, int flags)
+{
+ QVector<QTextLayout::FormatRange> selections;
+ if (flags & DrawSelections) {
+ QTextLayout::FormatRange o;
+ if (m_selstart < m_selend) {
+ o.start = m_selstart;
+ o.length = m_selend - m_selstart;
+ o.format.setBackground(m_palette.brush(QPalette::Highlight));
+ o.format.setForeground(m_palette.brush(QPalette::HighlightedText));
+ } else {
+ // mask selection
+ if(!m_blinkPeriod || m_blinkStatus){
+ o.start = m_cursor;
+ o.length = 1;
+ o.format.setBackground(m_palette.brush(QPalette::Text));
+ o.format.setForeground(m_palette.brush(QPalette::Window));
+ }
+ }
+ selections.append(o);
+ }
+
+ if (flags & DrawText)
+ m_textLayout.draw(painter, offset, selections, clip);
+
+ if (flags & DrawCursor){
+ int cursor = m_cursor;
+ if (m_preeditCursor != -1)
+ cursor += m_preeditCursor;
+ if (!m_hideCursor && (!m_blinkPeriod || m_blinkStatus))
+ m_textLayout.drawCursor(painter, offset, cursor, m_cursorWidth);
+ }
+}
+
+/*!
+ \internal
+
+ Sets the selection to cover the word at the given cursor position.
+ The word boundaries are defined by the behavior of QTextLayout::SkipWords
+ cursor mode.
+*/
+void QLineControl::selectWordAtPos(int cursor)
+{
+ int next = cursor + 1;
+ if(next > end())
+ --next;
+ int c = m_textLayout.previousCursorPosition(next, QTextLayout::SkipWords);
+ moveCursor(c, false);
+ // ## text layout should support end of words.
+ int end = m_textLayout.nextCursorPosition(c, QTextLayout::SkipWords);
+ while (end > cursor && m_text[end-1].isSpace())
+ --end;
+ moveCursor(end, true);
+}
+
+/*!
+ \internal
+
+ Completes a change to the line control text. If the change is not valid
+ will undo the line control state back to the given \a validateFromState.
+
+ If \a edited is true and the change is valid, will emit textEdited() in
+ addition to textChanged(). Otherwise only emits textChanged() on a valid
+ change.
+
+ The \a update value is currently unused.
+*/
+bool QLineControl::finishChange(int validateFromState, bool update, bool edited)
+{
+ Q_UNUSED(update)
+ bool lineDirty = m_selDirty;
+ if (m_textDirty) {
+ // do validation
+ bool wasValidInput = m_validInput;
+ m_validInput = true;
+#ifndef QT_NO_VALIDATOR
+ if (m_validator) {
+ m_validInput = false;
+ QString textCopy = m_text;
+ int cursorCopy = m_cursor;
+ m_validInput = (m_validator->validate(textCopy, cursorCopy) != QValidator::Invalid);
+ if (m_validInput) {
+ if (m_text != textCopy) {
+ internalSetText(textCopy, cursorCopy);
+ return true;
+ }
+ m_cursor = cursorCopy;
+ }
+ }
+#endif
+ if (validateFromState >= 0 && wasValidInput && !m_validInput) {
+ if (m_transactions.count())
+ return false;
+ internalUndo(validateFromState);
+ m_history.resize(m_undoState);
+ if (m_modifiedState > m_undoState)
+ m_modifiedState = -1;
+ m_validInput = true;
+ m_textDirty = false;
+ }
+ updateDisplayText();
+ lineDirty |= m_textDirty;
+ if (m_textDirty) {
+ m_textDirty = false;
+ QString actualText = text();
+ if (edited)
+ emit textEdited(actualText);
+ emit textChanged(actualText);
+ }
+ }
+ if (m_selDirty) {
+ m_selDirty = false;
+ emit selectionChanged();
+ }
+ emitCursorPositionChanged();
+ return true;
+}
+
+/*!
+ \internal
+
+ An internal function for setting the text of the line control.
+*/
+void QLineControl::internalSetText(const QString &txt, int pos, bool edited)
+{
+ internalDeselect();
+ emit resetInputContext();
+ QString oldText = m_text;
+ if (m_maskData) {
+ m_text = maskString(0, txt, true);
+ m_text += clearString(m_text.length(), m_maxLength - m_text.length());
+ } else {
+ m_text = txt.isEmpty() ? txt : txt.left(m_maxLength);
+ }
+ m_history.clear();
+ m_modifiedState = m_undoState = 0;
+ m_cursor = (pos < 0 || pos > m_text.length()) ? m_text.length() : pos;
+ m_textDirty = (oldText != m_text);
+
+#ifdef QT_NO_ACCESSIBILITY
+ Q_UNUSED(edited)
+#else
+ bool changed = finishChange(-1, true, edited);
+ if (changed)
+ QAccessible::updateAccessibility(parent(), 0, QAccessible::TextUpdated);
+#endif
+}
+
+
+/*!
+ \internal
+
+ Adds the given \a command to the undo history
+ of the line control. Does not apply the command.
+*/
+void QLineControl::addCommand(const Command &cmd)
+{
+ if (m_separator && m_undoState && m_history[m_undoState - 1].type != Separator) {
+ m_history.resize(m_undoState + 2);
+ m_history[m_undoState++] = Command(Separator, m_cursor, 0, m_selstart, m_selend);
+ } else {
+ m_history.resize(m_undoState + 1);
+ }
+ m_separator = false;
+ m_history[m_undoState++] = cmd;
+}
+
+/*!
+ \internal
+
+ Inserts the given string \a s into the line
+ control.
+
+ Also adds the appropriate commands into the undo history.
+ This function does not call finishChange(), and may leave the text
+ in an invalid state.
+*/
+void QLineControl::internalInsert(const QString &s)
+{
+ if (hasSelectedText())
+ addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
+ if (m_maskData) {
+ QString ms = maskString(m_cursor, s);
+ for (int i = 0; i < (int) ms.length(); ++i) {
+ addCommand (Command(DeleteSelection, m_cursor + i, m_text.at(m_cursor + i), -1, -1));
+ addCommand(Command(Insert, m_cursor + i, ms.at(i), -1, -1));
+ }
+ m_text.replace(m_cursor, ms.length(), ms);
+ m_cursor += ms.length();
+ m_cursor = nextMaskBlank(m_cursor);
+ m_textDirty = true;
+ } else {
+ int remaining = m_maxLength - m_text.length();
+ if (remaining != 0) {
+ m_text.insert(m_cursor, s.left(remaining));
+ for (int i = 0; i < (int) s.left(remaining).length(); ++i)
+ addCommand(Command(Insert, m_cursor++, s.at(i), -1, -1));
+ m_textDirty = true;
+ }
+ }
+}
+
+/*!
+ \internal
+
+ deletes a single character from the current text. If \a wasBackspace,
+ the character prior to the cursor is removed. Otherwise the character
+ after the cursor is removed.
+
+ Also adds the appropriate commands into the undo history.
+ This function does not call finishChange(), and may leave the text
+ in an invalid state.
+*/
+void QLineControl::internalDelete(bool wasBackspace)
+{
+ if (m_cursor < (int) m_text.length()) {
+ if (hasSelectedText())
+ addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
+ addCommand(Command((CommandType)((m_maskData ? 2 : 0) + (wasBackspace ? Remove : Delete)),
+ m_cursor, m_text.at(m_cursor), -1, -1));
+ if (m_maskData) {
+ m_text.replace(m_cursor, 1, clearString(m_cursor, 1));
+ addCommand(Command(Insert, m_cursor, m_text.at(m_cursor), -1, -1));
+ } else {
+ m_text.remove(m_cursor, 1);
+ }
+ m_textDirty = true;
+ }
+}
+
+/*!
+ \internal
+
+ removes the currently selected text from the line control.
+
+ Also adds the appropriate commands into the undo history.
+ This function does not call finishChange(), and may leave the text
+ in an invalid state.
+*/
+void QLineControl::removeSelectedText()
+{
+ if (m_selstart < m_selend && m_selend <= (int) m_text.length()) {
+ separate();
+ int i ;
+ addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
+ if (m_selstart <= m_cursor && m_cursor < m_selend) {
+ // cursor is within the selection. Split up the commands
+ // to be able to restore the correct cursor position
+ for (i = m_cursor; i >= m_selstart; --i)
+ addCommand (Command(DeleteSelection, i, m_text.at(i), -1, 1));
+ for (i = m_selend - 1; i > m_cursor; --i)
+ addCommand (Command(DeleteSelection, i - m_cursor + m_selstart - 1, m_text.at(i), -1, -1));
+ } else {
+ for (i = m_selend-1; i >= m_selstart; --i)
+ addCommand (Command(RemoveSelection, i, m_text.at(i), -1, -1));
+ }
+ if (m_maskData) {
+ m_text.replace(m_selstart, m_selend - m_selstart, clearString(m_selstart, m_selend - m_selstart));
+ for (int i = 0; i < m_selend - m_selstart; ++i)
+ addCommand(Command(Insert, m_selstart + i, m_text.at(m_selstart + i), -1, -1));
+ } else {
+ m_text.remove(m_selstart, m_selend - m_selstart);
+ }
+ if (m_cursor > m_selstart)
+ m_cursor -= qMin(m_cursor, m_selend) - m_selstart;
+ internalDeselect();
+ m_textDirty = true;
+ }
+}
+
+/*!
+ \internal
+
+ Parses the input mask specified by \a maskFields to generate
+ the mask data used to handle input masks.
+*/
+void QLineControl::parseInputMask(const QString &maskFields)
+{
+ int delimiter = maskFields.indexOf(QLatin1Char(';'));
+ if (maskFields.isEmpty() || delimiter == 0) {
+ if (m_maskData) {
+ delete [] m_maskData;
+ m_maskData = 0;
+ m_maxLength = 32767;
+ internalSetText(QString());
+ }
+ return;
+ }
+
+ if (delimiter == -1) {
+ m_blank = QLatin1Char(' ');
+ m_inputMask = maskFields;
+ } else {
+ m_inputMask = maskFields.left(delimiter);
+ m_blank = (delimiter + 1 < maskFields.length()) ? maskFields[delimiter + 1] : QLatin1Char(' ');
+ }
+
+ // calculate m_maxLength / m_maskData length
+ m_maxLength = 0;
+ QChar c = 0;
+ for (int i=0; i<m_inputMask.length(); i++) {
+ c = m_inputMask.at(i);
+ if (i > 0 && m_inputMask.at(i-1) == QLatin1Char('\\')) {
+ m_maxLength++;
+ continue;
+ }
+ if (c != QLatin1Char('\\') && c != QLatin1Char('!') &&
+ c != QLatin1Char('<') && c != QLatin1Char('>') &&
+ c != QLatin1Char('{') && c != QLatin1Char('}') &&
+ c != QLatin1Char('[') && c != QLatin1Char(']'))
+ m_maxLength++;
+ }
+
+ delete [] m_maskData;
+ m_maskData = new MaskInputData[m_maxLength];
+
+ MaskInputData::Casemode m = MaskInputData::NoCaseMode;
+ c = 0;
+ bool s;
+ bool escape = false;
+ int index = 0;
+ for (int i = 0; i < m_inputMask.length(); i++) {
+ c = m_inputMask.at(i);
+ if (escape) {
+ s = true;
+ m_maskData[index].maskChar = c;
+ m_maskData[index].separator = s;
+ m_maskData[index].caseMode = m;
+ index++;
+ escape = false;
+ } else if (c == QLatin1Char('<')) {
+ m = MaskInputData::Lower;
+ } else if (c == QLatin1Char('>')) {
+ m = MaskInputData::Upper;
+ } else if (c == QLatin1Char('!')) {
+ m = MaskInputData::NoCaseMode;
+ } else if (c != QLatin1Char('{') && c != QLatin1Char('}') && c != QLatin1Char('[') && c != QLatin1Char(']')) {
+ switch (c.unicode()) {
+ case 'A':
+ case 'a':
+ case 'N':
+ case 'n':
+ case 'X':
+ case 'x':
+ case '9':
+ case '0':
+ case 'D':
+ case 'd':
+ case '#':
+ case 'H':
+ case 'h':
+ case 'B':
+ case 'b':
+ s = false;
+ break;
+ case '\\':
+ escape = true;
+ default:
+ s = true;
+ break;
+ }
+
+ if (!escape) {
+ m_maskData[index].maskChar = c;
+ m_maskData[index].separator = s;
+ m_maskData[index].caseMode = m;
+ index++;
+ }
+ }
+ }
+ internalSetText(m_text);
+}
+
+
+/*!
+ \internal
+
+ checks if the key is valid compared to the inputMask
+*/
+bool QLineControl::isValidInput(QChar key, QChar mask) const
+{
+ switch (mask.unicode()) {
+ case 'A':
+ if (key.isLetter())
+ return true;
+ break;
+ case 'a':
+ if (key.isLetter() || key == m_blank)
+ return true;
+ break;
+ case 'N':
+ if (key.isLetterOrNumber())
+ return true;
+ break;
+ case 'n':
+ if (key.isLetterOrNumber() || key == m_blank)
+ return true;
+ break;
+ case 'X':
+ if (key.isPrint())
+ return true;
+ break;
+ case 'x':
+ if (key.isPrint() || key == m_blank)
+ return true;
+ break;
+ case '9':
+ if (key.isNumber())
+ return true;
+ break;
+ case '0':
+ if (key.isNumber() || key == m_blank)
+ return true;
+ break;
+ case 'D':
+ if (key.isNumber() && key.digitValue() > 0)
+ return true;
+ break;
+ case 'd':
+ if ((key.isNumber() && key.digitValue() > 0) || key == m_blank)
+ return true;
+ break;
+ case '#':
+ if (key.isNumber() || key == QLatin1Char('+') || key == QLatin1Char('-') || key == m_blank)
+ return true;
+ break;
+ case 'B':
+ if (key == QLatin1Char('0') || key == QLatin1Char('1'))
+ return true;
+ break;
+ case 'b':
+ if (key == QLatin1Char('0') || key == QLatin1Char('1') || key == m_blank)
+ return true;
+ break;
+ case 'H':
+ if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')))
+ return true;
+ break;
+ case 'h':
+ if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')) || key == m_blank)
+ return true;
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+/*!
+ \internal
+
+ Returns true if the given text \a str is valid for any
+ validator or input mask set for the line control.
+
+ Otherwise returns false
+*/
+bool QLineControl::hasAcceptableInput(const QString &str) const
+{
+#ifndef QT_NO_VALIDATOR
+ QString textCopy = str;
+ int cursorCopy = m_cursor;
+ if (m_validator && m_validator->validate(textCopy, cursorCopy)
+ != QValidator::Acceptable)
+ return false;
+#endif
+
+ if (!m_maskData)
+ return true;
+
+ if (str.length() != m_maxLength)
+ return false;
+
+ for (int i=0; i < m_maxLength; ++i) {
+ if (m_maskData[i].separator) {
+ if (str.at(i) != m_maskData[i].maskChar)
+ return false;
+ } else {
+ if (!isValidInput(str.at(i), m_maskData[i].maskChar))
+ return false;
+ }
+ }
+ return true;
+}
+
+/*!
+ \internal
+
+ Applies the inputMask on \a str starting from position \a pos in the mask. \a clear
+ specifies from where characters should be gotten when a separator is met in \a str - true means
+ that blanks will be used, false that previous input is used.
+ Calling this when no inputMask is set is undefined.
+*/
+QString QLineControl::maskString(uint pos, const QString &str, bool clear) const
+{
+ if (pos >= (uint)m_maxLength)
+ return QString::fromLatin1("");
+
+ QString fill;
+ fill = clear ? clearString(0, m_maxLength) : m_text;
+
+ int strIndex = 0;
+ QString s = QString::fromLatin1("");
+ int i = pos;
+ while (i < m_maxLength) {
+ if (strIndex < str.length()) {
+ if (m_maskData[i].separator) {
+ s += m_maskData[i].maskChar;
+ if (str[(int)strIndex] == m_maskData[i].maskChar)
+ strIndex++;
+ ++i;
+ } else {
+ if (isValidInput(str[(int)strIndex], m_maskData[i].maskChar)) {
+ switch (m_maskData[i].caseMode) {
+ case MaskInputData::Upper:
+ s += str[(int)strIndex].toUpper();
+ break;
+ case MaskInputData::Lower:
+ s += str[(int)strIndex].toLower();
+ break;
+ default:
+ s += str[(int)strIndex];
+ }
+ ++i;
+ } else {
+ // search for separator first
+ int n = findInMask(i, true, true, str[(int)strIndex]);
+ if (n != -1) {
+ if (str.length() != 1 || i == 0 || (i > 0 && (!m_maskData[i-1].separator || m_maskData[i-1].maskChar != str[(int)strIndex]))) {
+ s += fill.mid(i, n-i+1);
+ i = n + 1; // update i to find + 1
+ }
+ } else {
+ // search for valid m_blank if not
+ n = findInMask(i, true, false, str[(int)strIndex]);
+ if (n != -1) {
+ s += fill.mid(i, n-i);
+ switch (m_maskData[n].caseMode) {
+ case MaskInputData::Upper:
+ s += str[(int)strIndex].toUpper();
+ break;
+ case MaskInputData::Lower:
+ s += str[(int)strIndex].toLower();
+ break;
+ default:
+ s += str[(int)strIndex];
+ }
+ i = n + 1; // updates i to find + 1
+ }
+ }
+ }
+ ++strIndex;
+ }
+ } else
+ break;
+ }
+
+ return s;
+}
+
+
+
+/*!
+ \internal
+
+ Returns a "cleared" string with only separators and blank chars.
+ Calling this when no inputMask is set is undefined.
+*/
+QString QLineControl::clearString(uint pos, uint len) const
+{
+ if (pos >= (uint)m_maxLength)
+ return QString();
+
+ QString s;
+ int end = qMin((uint)m_maxLength, pos + len);
+ for (int i = pos; i < end; ++i)
+ if (m_maskData[i].separator)
+ s += m_maskData[i].maskChar;
+ else
+ s += m_blank;
+
+ return s;
+}
+
+/*!
+ \internal
+
+ Strips blank parts of the input in a QLineControl when an inputMask is set,
+ separators are still included. Typically "127.0__.0__.1__" becomes "127.0.0.1".
+*/
+QString QLineControl::stripString(const QString &str) const
+{
+ if (!m_maskData)
+ return str;
+
+ QString s;
+ int end = qMin(m_maxLength, (int)str.length());
+ for (int i = 0; i < end; ++i)
+ if (m_maskData[i].separator)
+ s += m_maskData[i].maskChar;
+ else
+ if (str[i] != m_blank)
+ s += str[i];
+
+ return s;
+}
+
+/*!
+ \internal
+ searches forward/backward in m_maskData for either a separator or a m_blank
+*/
+int QLineControl::findInMask(int pos, bool forward, bool findSeparator, QChar searchChar) const
+{
+ if (pos >= m_maxLength || pos < 0)
+ return -1;
+
+ int end = forward ? m_maxLength : -1;
+ int step = forward ? 1 : -1;
+ int i = pos;
+
+ while (i != end) {
+ if (findSeparator) {
+ if (m_maskData[i].separator && m_maskData[i].maskChar == searchChar)
+ return i;
+ } else {
+ if (!m_maskData[i].separator) {
+ if (searchChar.isNull())
+ return i;
+ else if (isValidInput(searchChar, m_maskData[i].maskChar))
+ return i;
+ }
+ }
+ i += step;
+ }
+ return -1;
+}
+
+void QLineControl::internalUndo(int until)
+{
+ if (!isUndoAvailable())
+ return;
+ internalDeselect();
+ while (m_undoState && m_undoState > until) {
+ Command& cmd = m_history[--m_undoState];
+ switch (cmd.type) {
+ case Insert:
+ m_text.remove(cmd.pos, 1);
+ m_cursor = cmd.pos;
+ break;
+ case SetSelection:
+ m_selstart = cmd.selStart;
+ m_selend = cmd.selEnd;
+ m_cursor = cmd.pos;
+ break;
+ case Remove:
+ case RemoveSelection:
+ m_text.insert(cmd.pos, cmd.uc);
+ m_cursor = cmd.pos + 1;
+ break;
+ case Delete:
+ case DeleteSelection:
+ m_text.insert(cmd.pos, cmd.uc);
+ m_cursor = cmd.pos;
+ break;
+ case Separator:
+ continue;
+ }
+ if (until < 0 && m_undoState) {
+ Command& next = m_history[m_undoState-1];
+ if (next.type != cmd.type && next.type < RemoveSelection
+ && (cmd.type < RemoveSelection || next.type == Separator))
+ break;
+ }
+ }
+ m_textDirty = true;
+ emitCursorPositionChanged();
+}
+
+void QLineControl::internalRedo()
+{
+ if (!isRedoAvailable())
+ return;
+ internalDeselect();
+ while (m_undoState < (int)m_history.size()) {
+ Command& cmd = m_history[m_undoState++];
+ switch (cmd.type) {
+ case Insert:
+ m_text.insert(cmd.pos, cmd.uc);
+ m_cursor = cmd.pos + 1;
+ break;
+ case SetSelection:
+ m_selstart = cmd.selStart;
+ m_selend = cmd.selEnd;
+ m_cursor = cmd.pos;
+ break;
+ case Remove:
+ case Delete:
+ case RemoveSelection:
+ case DeleteSelection:
+ m_text.remove(cmd.pos, 1);
+ m_selstart = cmd.selStart;
+ m_selend = cmd.selEnd;
+ m_cursor = cmd.pos;
+ break;
+ case Separator:
+ m_selstart = cmd.selStart;
+ m_selend = cmd.selEnd;
+ m_cursor = cmd.pos;
+ break;
+ }
+ if (m_undoState < (int)m_history.size()) {
+ Command& next = m_history[m_undoState];
+ if (next.type != cmd.type && cmd.type < RemoveSelection && next.type != Separator
+ && (next.type < RemoveSelection || cmd.type == Separator))
+ break;
+ }
+ }
+ m_textDirty = true;
+ emitCursorPositionChanged();
+}
+
+/*!
+ \internal
+
+ If the current cursor position differs from the last emitted cursor
+ position, emits cursorPositionChanged().
+*/
+void QLineControl::emitCursorPositionChanged()
+{
+ if (m_cursor != m_lastCursorPos) {
+ const int oldLast = m_lastCursorPos;
+ m_lastCursorPos = m_cursor;
+ cursorPositionChanged(oldLast, m_cursor);
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(parent(), 0, QAccessible::TextCaretMoved);
+#endif
+ }
+}
+
+
+void QLineControl::setCursorBlinkPeriod(int msec)
+{
+ if (msec == m_blinkPeriod)
+ return;
+ if (m_blinkTimer) {
+ killTimer(m_blinkTimer);
+ }
+ if (msec) {
+ m_blinkTimer = startTimer(msec / 2);
+ m_blinkStatus = 1;
+ } else {
+ m_blinkTimer = 0;
+ if (m_blinkStatus == 1)
+ emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect());
+ }
+ m_blinkPeriod = msec;
+}
+
+void QLineControl::resetCursorBlinkTimer()
+{
+ if (m_blinkPeriod == 0 || m_blinkTimer == 0)
+ return;
+ killTimer(m_blinkTimer);
+ m_blinkTimer = startTimer(m_blinkPeriod / 2);
+ m_blinkStatus = 1;
+}
+
+void QLineControl::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() == m_blinkTimer) {
+ m_blinkStatus = !m_blinkStatus;
+ emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect());
+ } else if (event->timerId() == m_deleteAllTimer) {
+ killTimer(m_deleteAllTimer);
+ m_deleteAllTimer = 0;
+ clear();
+ } else if (event->timerId() == m_tripleClickTimer) {
+ killTimer(m_tripleClickTimer);
+ m_tripleClickTimer = 0;
+ }
+}
+
+bool QLineControl::processEvent(QEvent* ev)
+{
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QGuiApplication::keypadNavigationEnabled()) {
+ if ((ev->type() == QEvent::KeyPress) || (ev->type() == QEvent::KeyRelease)) {
+ QKeyEvent *ke = (QKeyEvent *)ev;
+ if (ke->key() == Qt::Key_Back) {
+ if (ke->isAutoRepeat()) {
+ // Swallow it. We don't want back keys running amok.
+ ke->accept();
+ return true;
+ }
+ if ((ev->type() == QEvent::KeyRelease)
+ && !isReadOnly()
+ && m_deleteAllTimer) {
+ killTimer(m_deleteAllTimer);
+ m_deleteAllTimer = 0;
+ backspace();
+ ke->accept();
+ return true;
+ }
+ }
+ }
+ }
+#endif
+ switch(ev->type()){
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ processMouseEvent(static_cast<QMouseEvent*>(ev)); break;
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ processKeyEvent(static_cast<QKeyEvent*>(ev)); break;
+ case QEvent::InputMethod:
+ processInputMethodEvent(static_cast<QInputMethodEvent*>(ev)); break;
+#ifndef QT_NO_SHORTCUT
+ case QEvent::ShortcutOverride:{
+ if (isReadOnly())
+ return false;
+ QKeyEvent* ke = static_cast<QKeyEvent*>(ev);
+ if (ke == QKeySequence::Copy
+ || ke == QKeySequence::Paste
+ || ke == QKeySequence::Cut
+ || ke == QKeySequence::Redo
+ || ke == QKeySequence::Undo
+ || ke == QKeySequence::MoveToNextWord
+ || ke == QKeySequence::MoveToPreviousWord
+ || ke == QKeySequence::MoveToStartOfDocument
+ || ke == QKeySequence::MoveToEndOfDocument
+ || ke == QKeySequence::SelectNextWord
+ || ke == QKeySequence::SelectPreviousWord
+ || ke == QKeySequence::SelectStartOfLine
+ || ke == QKeySequence::SelectEndOfLine
+ || ke == QKeySequence::SelectStartOfBlock
+ || ke == QKeySequence::SelectEndOfBlock
+ || ke == QKeySequence::SelectStartOfDocument
+ || ke == QKeySequence::SelectAll
+ || ke == QKeySequence::SelectEndOfDocument) {
+ ke->accept();
+ } else if (ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier
+ || ke->modifiers() == Qt::KeypadModifier) {
+ if (ke->key() < Qt::Key_Escape) {
+ ke->accept();
+ } else {
+ switch (ke->key()) {
+ case Qt::Key_Delete:
+ case Qt::Key_Home:
+ case Qt::Key_End:
+ case Qt::Key_Backspace:
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ ke->accept();
+ default:
+ break;
+ }
+ }
+ }
+ }
+#endif
+ default:
+ return false;
+ }
+ return true;
+}
+
+void QLineControl::processMouseEvent(QMouseEvent* ev)
+{
+
+ switch (ev->type()) {
+ case QEvent::MouseButtonPress:{
+ if (m_tripleClickTimer
+ && (ev->pos() - m_tripleClick).manhattanLength()
+ < startDragDistance) {
+ selectAll();
+ return;
+ }
+ if (ev->button() == Qt::RightButton)
+ return;
+
+ bool mark = ev->modifiers() & Qt::ShiftModifier;
+ int cursor = xToPos(ev->pos().x());
+ moveCursor(cursor, mark);
+ break;
+ }
+ case QEvent::MouseButtonDblClick:
+ if (ev->button() == Qt::LeftButton) {
+ selectWordAtPos(xToPos(ev->pos().x()));
+ if (m_tripleClickTimer)
+ killTimer(m_tripleClickTimer);
+ m_tripleClickTimer = startTimer(QGuiApplication::doubleClickInterval());
+ m_tripleClick = ev->pos();
+ }
+ break;
+ case QEvent::MouseButtonRelease:
+#ifndef QT_NO_CLIPBOARD
+ if (QGuiApplication::clipboard()->supportsSelection()) {
+ if (ev->button() == Qt::LeftButton) {
+ copy(QClipboard::Selection);
+ } else if (!isReadOnly() && ev->button() == Qt::MidButton) {
+ deselect();
+ insert(QGuiApplication::clipboard()->text(QClipboard::Selection));
+ }
+ }
+#endif
+ break;
+ case QEvent::MouseMove:
+ if (ev->buttons() & Qt::LeftButton) {
+ moveCursor(xToPos(ev->pos().x()), true);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void QLineControl::processKeyEvent(QKeyEvent* event)
+{
+ bool inlineCompletionAccepted = false;
+
+ if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
+ if (hasAcceptableInput() || fixup()) {
+ emit accepted();
+ emit editingFinished();
+ }
+ if (inlineCompletionAccepted)
+ event->accept();
+ else
+ event->ignore();
+ return;
+ }
+
+ if (echoMode() == PasswordEchoOnEdit
+ && !passwordEchoEditing()
+ && !isReadOnly()
+ && !event->text().isEmpty()
+#ifdef QT_KEYPAD_NAVIGATION
+ && event->key() != Qt::Key_Select
+ && event->key() != Qt::Key_Up
+ && event->key() != Qt::Key_Down
+ && event->key() != Qt::Key_Back
+#endif
+ && !(event->modifiers() & Qt::ControlModifier)) {
+ // Clear the edit and reset to normal echo mode while editing; the
+ // echo mode switches back when the edit loses focus
+ // ### resets current content. dubious code; you can
+ // navigate with keys up, down, back, and select(?), but if you press
+ // "left" or "right" it clears?
+ updatePasswordEchoEditing(true);
+ clear();
+ }
+
+ bool unknown = false;
+ bool visual = cursorMoveStyle() == Qt::VisualMoveStyle;
+
+ if (false) {
+ }
+#ifndef QT_NO_SHORTCUT
+ else if (event == QKeySequence::Undo) {
+ if (!isReadOnly())
+ undo();
+ }
+ else if (event == QKeySequence::Redo) {
+ if (!isReadOnly())
+ redo();
+ }
+ else if (event == QKeySequence::SelectAll) {
+ selectAll();
+ }
+#ifndef QT_NO_CLIPBOARD
+ else if (event == QKeySequence::Copy) {
+ copy();
+ }
+ else if (event == QKeySequence::Paste) {
+ if (!isReadOnly()) {
+ QClipboard::Mode mode = QClipboard::Clipboard;
+#ifdef Q_WS_X11
+ if (event->modifiers() == (Qt::CTRL | Qt::SHIFT) && event->key() == Qt::Key_Insert)
+ mode = QClipboard::Selection;
+#endif
+ paste(mode);
+ }
+ }
+ else if (event == QKeySequence::Cut) {
+ if (!isReadOnly()) {
+ copy();
+ del();
+ }
+ }
+ else if (event == QKeySequence::DeleteEndOfLine) {
+ if (!isReadOnly()) {
+ setSelection(cursor(), end());
+ copy();
+ del();
+ }
+ }
+#endif //QT_NO_CLIPBOARD
+ else if (event == QKeySequence::MoveToStartOfLine || event == QKeySequence::MoveToStartOfBlock) {
+ home(0);
+ }
+ else if (event == QKeySequence::MoveToEndOfLine || event == QKeySequence::MoveToEndOfBlock) {
+ end(0);
+ }
+ else if (event == QKeySequence::SelectStartOfLine || event == QKeySequence::SelectStartOfBlock) {
+ home(1);
+ }
+ else if (event == QKeySequence::SelectEndOfLine || event == QKeySequence::SelectEndOfBlock) {
+ end(1);
+ }
+ else if (event == QKeySequence::MoveToNextChar) {
+#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER)
+ if (hasSelectedText()) {
+#else
+ if (hasSelectedText() && m_completer
+ && m_completer->completionMode() == QCompleter::InlineCompletion) {
+#endif
+ moveCursor(selectionEnd(), false);
+ } else {
+ cursorForward(0, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1));
+ }
+ }
+ else if (event == QKeySequence::SelectNextChar) {
+ cursorForward(1, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1));
+ }
+ else if (event == QKeySequence::MoveToPreviousChar) {
+#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER)
+ if (hasSelectedText()) {
+#else
+ if (hasSelectedText() && m_completer
+ && m_completer->completionMode() == QCompleter::InlineCompletion) {
+#endif
+ moveCursor(selectionStart(), false);
+ } else {
+ cursorForward(0, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1));
+ }
+ }
+ else if (event == QKeySequence::SelectPreviousChar) {
+ cursorForward(1, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1));
+ }
+ else if (event == QKeySequence::MoveToNextWord) {
+ if (echoMode() == Normal)
+ layoutDirection() == Qt::LeftToRight ? cursorWordForward(0) : cursorWordBackward(0);
+ else
+ layoutDirection() == Qt::LeftToRight ? end(0) : home(0);
+ }
+ else if (event == QKeySequence::MoveToPreviousWord) {
+ if (echoMode() == Normal)
+ layoutDirection() == Qt::LeftToRight ? cursorWordBackward(0) : cursorWordForward(0);
+ else if (!isReadOnly()) {
+ layoutDirection() == Qt::LeftToRight ? home(0) : end(0);
+ }
+ }
+ else if (event == QKeySequence::SelectNextWord) {
+ if (echoMode() == Normal)
+ layoutDirection() == Qt::LeftToRight ? cursorWordForward(1) : cursorWordBackward(1);
+ else
+ layoutDirection() == Qt::LeftToRight ? end(1) : home(1);
+ }
+ else if (event == QKeySequence::SelectPreviousWord) {
+ if (echoMode() == Normal)
+ layoutDirection() == Qt::LeftToRight ? cursorWordBackward(1) : cursorWordForward(1);
+ else
+ layoutDirection() == Qt::LeftToRight ? home(1) : end(1);
+ }
+ else if (event == QKeySequence::Delete) {
+ if (!isReadOnly())
+ del();
+ }
+ else if (event == QKeySequence::DeleteEndOfWord) {
+ if (!isReadOnly()) {
+ cursorWordForward(true);
+ del();
+ }
+ }
+ else if (event == QKeySequence::DeleteStartOfWord) {
+ if (!isReadOnly()) {
+ cursorWordBackward(true);
+ del();
+ }
+ }
+#endif // QT_NO_SHORTCUT
+ else {
+ bool handled = false;
+#ifdef Q_WS_MAC
+ if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down) {
+ Qt::KeyboardModifiers myModifiers = (event->modifiers() & ~Qt::KeypadModifier);
+ if (myModifiers & Qt::ShiftModifier) {
+ if (myModifiers == (Qt::ControlModifier|Qt::ShiftModifier)
+ || myModifiers == (Qt::AltModifier|Qt::ShiftModifier)
+ || myModifiers == Qt::ShiftModifier) {
+
+ event->key() == Qt::Key_Up ? home(1) : end(1);
+ }
+ } else {
+ if ((myModifiers == Qt::ControlModifier
+ || myModifiers == Qt::AltModifier
+ || myModifiers == Qt::NoModifier)) {
+ event->key() == Qt::Key_Up ? home(0) : end(0);
+ }
+ }
+ handled = true;
+ }
+#endif
+ if (event->modifiers() & Qt::ControlModifier) {
+ switch (event->key()) {
+ case Qt::Key_Backspace:
+ if (!isReadOnly()) {
+ cursorWordBackward(true);
+ del();
+ }
+ break;
+#if defined(Q_WS_X11)
+ case Qt::Key_E:
+ end(0);
+ break;
+
+ case Qt::Key_U:
+ if (!isReadOnly()) {
+ setSelection(0, text().size());
+#ifndef QT_NO_CLIPBOARD
+ copy();
+#endif
+ del();
+ }
+ break;
+#endif
+ default:
+ if (!handled)
+ unknown = true;
+ }
+ } else { // ### check for *no* modifier
+ switch (event->key()) {
+ case Qt::Key_Backspace:
+ if (!isReadOnly()) {
+ backspace();
+ }
+ break;
+#ifdef QT_KEYPAD_NAVIGATION
+ case Qt::Key_Back:
+ if (QGuiApplication::keypadNavigationEnabled() && !event->isAutoRepeat()
+ && !isReadOnly()) {
+ if (text().length() == 0) {
+ setText(m_cancelText);
+
+ if (passwordEchoEditing())
+ updatePasswordEchoEditing(false);
+
+ emit editFocusChange(false);
+ } else if (!m_deleteAllTimer) {
+ m_deleteAllTimer = startTimer(750);
+ }
+ } else {
+ unknown = true;
+ }
+ break;
+#endif
+ default:
+ if (!handled)
+ unknown = true;
+ }
+ }
+ }
+
+ if (event->key() == Qt::Key_Direction_L || event->key() == Qt::Key_Direction_R) {
+ setLayoutDirection((event->key() == Qt::Key_Direction_L) ? Qt::LeftToRight : Qt::RightToLeft);
+ unknown = false;
+ }
+
+ if (unknown && !isReadOnly()) {
+ QString t = event->text();
+ if (!t.isEmpty() && t.at(0).isPrint()) {
+ insert(t);
+ event->accept();
+ return;
+ }
+ }
+
+ if (unknown)
+ event->ignore();
+ else
+ event->accept();
+}
+
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/text/qlinecontrol_p.h b/src/gui/text/qlinecontrol_p.h
new file mode 100644
index 0000000000..e5435c22f6
--- /dev/null
+++ b/src/gui/text/qlinecontrol_p.h
@@ -0,0 +1,455 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLINECONTROL_P_H
+#define QLINECONTROL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtCore/qglobal.h"
+
+#include "QtGui/qtextlayout.h"
+#include "QtCore/qpointer.h"
+#include "QtGui/qclipboard.h"
+#include "QtGui/qvalidator.h"
+#include "QtGui/qpalette.h"
+#include "QtGui/qguiapplication.h"
+#include "QtCore/qpoint.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class Q_GUI_EXPORT QLineControl : public QObject
+{
+ Q_OBJECT
+
+public:
+ QLineControl(const QString &txt = QString())
+ : m_cursor(0), m_preeditCursor(0), m_cursorWidth(0), m_layoutDirection(Qt::LayoutDirectionAuto),
+ m_hideCursor(false), m_separator(0), m_readOnly(0),
+ m_dragEnabled(0), m_echoMode(Normal), m_textDirty(0), m_selDirty(0),
+ m_validInput(1), m_blinkStatus(0), m_blinkPeriod(0), m_blinkTimer(0), m_deleteAllTimer(0),
+ m_ascent(0), m_maxLength(32767), m_lastCursorPos(-1),
+ m_tripleClickTimer(0), m_maskData(0), m_modifiedState(0), m_undoState(0),
+ m_selstart(0), m_selend(0), m_passwordEchoEditing(false)
+ {
+ init(txt);
+ }
+
+ enum EchoMode {
+ Normal,
+ NoEcho,
+ Password,
+ PasswordEchoOnEdit
+ };
+
+
+ ~QLineControl()
+ {
+ delete [] m_maskData;
+ }
+
+ int nextMaskBlank(int pos)
+ {
+ int c = findInMask(pos, true, false);
+ m_separator |= (c != pos);
+ return (c != -1 ? c : m_maxLength);
+ }
+
+ int prevMaskBlank(int pos)
+ {
+ int c = findInMask(pos, false, false);
+ m_separator |= (c != pos);
+ return (c != -1 ? c : 0);
+ }
+
+ bool isUndoAvailable() const { return !m_readOnly && m_undoState; }
+ bool isRedoAvailable() const { return !m_readOnly && m_undoState < (int)m_history.size(); }
+ void clearUndo() { m_history.clear(); m_modifiedState = m_undoState = 0; }
+
+ bool isModified() const { return m_modifiedState != m_undoState; }
+ void setModified(bool modified) { m_modifiedState = modified ? -1 : m_undoState; }
+
+ bool allSelected() const { return !m_text.isEmpty() && m_selstart == 0 && m_selend == (int)m_text.length(); }
+ bool hasSelectedText() const { return !m_text.isEmpty() && m_selend > m_selstart; }
+
+ int width() const { return qRound(m_textLayout.lineAt(0).width()) + 1; }
+ int height() const { return qRound(m_textLayout.lineAt(0).height()) + 1; }
+ int ascent() const { return m_ascent; }
+ qreal naturalTextWidth() const { return m_textLayout.lineAt(0).naturalTextWidth(); }
+
+ void setSelection(int start, int length);
+
+ inline QString selectedText() const { return hasSelectedText() ? m_text.mid(m_selstart, m_selend - m_selstart) : QString(); }
+ QString textBeforeSelection() const { return hasSelectedText() ? m_text.left(m_selstart) : QString(); }
+ QString textAfterSelection() const { return hasSelectedText() ? m_text.mid(m_selend) : QString(); }
+
+ int selectionStart() const { return hasSelectedText() ? m_selstart : -1; }
+ int selectionEnd() const { return hasSelectedText() ? m_selend : -1; }
+ bool inSelection(int x) const
+ {
+ if (m_selstart >= m_selend)
+ return false;
+ int pos = xToPos(x, QTextLine::CursorOnCharacter);
+ return pos >= m_selstart && pos < m_selend;
+ }
+
+ void removeSelection()
+ {
+ int priorState = m_undoState;
+ removeSelectedText();
+ finishChange(priorState);
+ }
+
+ int start() const { return 0; }
+ int end() const { return m_text.length(); }
+
+#ifndef QT_NO_CLIPBOARD
+ void copy(QClipboard::Mode mode = QClipboard::Clipboard) const;
+ void paste(QClipboard::Mode mode = QClipboard::Clipboard);
+#endif
+
+ int cursor() const{ return m_cursor; }
+ int preeditCursor() const { return m_preeditCursor; }
+
+ int cursorWidth() const { return m_cursorWidth; }
+ void setCursorWidth(int value) { m_cursorWidth = value; }
+
+ Qt::CursorMoveStyle cursorMoveStyle() const { return m_textLayout.cursorMoveStyle(); }
+ void setCursorMoveStyle(Qt::CursorMoveStyle style) { m_textLayout.setCursorMoveStyle(style); }
+
+ void moveCursor(int pos, bool mark = false);
+ void cursorForward(bool mark, int steps)
+ {
+ int c = m_cursor;
+ if (steps > 0) {
+ while (steps--)
+ c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.rightCursorPosition(c)
+ : m_textLayout.nextCursorPosition(c);
+ } else if (steps < 0) {
+ while (steps++)
+ c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.leftCursorPosition(c)
+ : m_textLayout.previousCursorPosition(c);
+ }
+ moveCursor(c, mark);
+ }
+
+ void cursorWordForward(bool mark) { moveCursor(m_textLayout.nextCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
+ void cursorWordBackward(bool mark) { moveCursor(m_textLayout.previousCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
+
+ void home(bool mark) { moveCursor(0, mark); }
+ void end(bool mark) { moveCursor(text().length(), mark); }
+
+ int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const;
+ QRect cursorRect() const;
+
+ qreal cursorToX(int cursor) const { return m_textLayout.lineAt(0).cursorToX(cursor); }
+ qreal cursorToX() const
+ {
+ int cursor = m_cursor;
+ if (m_preeditCursor != -1)
+ cursor += m_preeditCursor;
+ return cursorToX(cursor);
+ }
+
+ bool isReadOnly() const { return m_readOnly; }
+ void setReadOnly(bool enable) { m_readOnly = enable; }
+
+ QString text() const
+ {
+ QString res = m_maskData ? stripString(m_text) : m_text;
+ return (res.isNull() ? QString::fromLatin1("") : res);
+ }
+ void setText(const QString &txt) { internalSetText(txt, -1, false); }
+ QString displayText() const { return m_textLayout.text(); }
+
+ void backspace();
+ void del();
+ void deselect() { internalDeselect(); finishChange(); }
+ void selectAll() { m_selstart = m_selend = m_cursor = 0; moveCursor(m_text.length(), true); }
+
+ void insert(const QString &);
+ void clear();
+ void undo() { internalUndo(); finishChange(-1, true); }
+ void redo() { internalRedo(); finishChange(); }
+ void selectWordAtPos(int);
+
+ EchoMode echoMode() const { return EchoMode(m_echoMode); }
+ void setEchoMode(EchoMode mode)
+ {
+ m_echoMode = mode;
+ m_passwordEchoEditing = false;
+ updateDisplayText();
+ }
+
+ int maxLength() const { return m_maxLength; }
+ void setMaxLength(int maxLength)
+ {
+ if (m_maskData)
+ return;
+ m_maxLength = maxLength;
+ setText(m_text);
+ }
+
+#ifndef QT_NO_VALIDATOR
+ const QValidator *validator() const { return m_validator; }
+ void setValidator(const QValidator *v) { m_validator = const_cast<QValidator*>(v); }
+#endif
+
+ int cursorPosition() const { return m_cursor; }
+ void setCursorPosition(int pos) { if (pos <= m_text.length()) moveCursor(qMax(0, pos)); }
+
+ bool hasAcceptableInput() const { return hasAcceptableInput(m_text); }
+ bool fixup();
+
+ QString inputMask() const { return m_maskData ? m_inputMask + QLatin1Char(';') + m_blank : QString(); }
+ void setInputMask(const QString &mask)
+ {
+ parseInputMask(mask);
+ if (m_maskData)
+ moveCursor(nextMaskBlank(0));
+ }
+
+ // input methods
+#ifndef QT_NO_IM
+ bool composeMode() const { return !m_textLayout.preeditAreaText().isEmpty(); }
+ void setPreeditArea(int cursor, const QString &text) { m_textLayout.setPreeditArea(cursor, text); }
+#endif
+
+ QString preeditAreaText() const { return m_textLayout.preeditAreaText(); }
+
+ void updatePasswordEchoEditing(bool editing);
+ bool passwordEchoEditing() const { return m_passwordEchoEditing; }
+
+ QChar passwordCharacter() const { return m_passwordCharacter; }
+ void setPasswordCharacter(const QChar &character) { m_passwordCharacter = character; updateDisplayText(); }
+
+ Qt::LayoutDirection layoutDirection() const {
+ if (m_layoutDirection == Qt::LayoutDirectionAuto) {
+ if (m_text.isEmpty())
+ return QGuiApplication::keyboardInputDirection();
+ return m_text.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight;
+ }
+ return m_layoutDirection;
+ }
+ void setLayoutDirection(Qt::LayoutDirection direction)
+ {
+ if (direction != m_layoutDirection) {
+ m_layoutDirection = direction;
+ updateDisplayText();
+ }
+ }
+
+ void setFont(const QFont &font) { m_textLayout.setFont(font); updateDisplayText(); }
+
+ void processInputMethodEvent(QInputMethodEvent *event);
+ void processMouseEvent(QMouseEvent* ev);
+ void processKeyEvent(QKeyEvent* ev);
+
+ int cursorBlinkPeriod() const { return m_blinkPeriod; }
+ void setCursorBlinkPeriod(int msec);
+ void resetCursorBlinkTimer();
+
+ bool cursorBlinkStatus() const { return m_blinkStatus; }
+
+ QString cancelText() const { return m_cancelText; }
+ void setCancelText(const QString &text) { m_cancelText = text; }
+
+ const QPalette &palette() const { return m_palette; }
+ void setPalette(const QPalette &p) { m_palette = p; }
+
+ enum DrawFlags {
+ DrawText = 0x01,
+ DrawSelections = 0x02,
+ DrawCursor = 0x04,
+ DrawAll = DrawText | DrawSelections | DrawCursor
+ };
+ void draw(QPainter *, const QPoint &, const QRect &, int flags = DrawAll);
+
+ bool processEvent(QEvent *ev);
+
+ QTextLayout *textLayout()
+ {
+ return &m_textLayout;
+ }
+
+private:
+ void init(const QString &txt);
+ void removeSelectedText();
+ void internalSetText(const QString &txt, int pos = -1, bool edited = true);
+ void updateDisplayText(bool forceUpdate = false);
+
+ void internalInsert(const QString &s);
+ void internalDelete(bool wasBackspace = false);
+ void internalRemove(int pos);
+
+ inline void internalDeselect()
+ {
+ m_selDirty |= (m_selend > m_selstart);
+ m_selstart = m_selend = 0;
+ }
+
+ void internalUndo(int until = -1);
+ void internalRedo();
+
+ QString m_text;
+ QPalette m_palette;
+ int m_cursor;
+ int m_preeditCursor;
+ int m_cursorWidth;
+ Qt::LayoutDirection m_layoutDirection;
+ uint m_hideCursor : 1; // used to hide the m_cursor inside preedit areas
+ uint m_separator : 1;
+ uint m_readOnly : 1;
+ uint m_dragEnabled : 1;
+ uint m_echoMode : 2;
+ uint m_textDirty : 1;
+ uint m_selDirty : 1;
+ uint m_validInput : 1;
+ uint m_blinkStatus : 1;
+ int m_blinkPeriod; // 0 for non-blinking cursor
+ int m_blinkTimer;
+ int m_deleteAllTimer;
+ int m_ascent;
+ int m_maxLength;
+ int m_lastCursorPos;
+ QList<int> m_transactions;
+ QPoint m_tripleClick;
+ int m_tripleClickTimer;
+ QString m_cancelText;
+
+ void emitCursorPositionChanged();
+
+ bool finishChange(int validateFromState = -1, bool update = false, bool edited = true);
+
+#ifndef QT_NO_VALIDATOR
+ QPointer<QValidator> m_validator;
+#endif
+
+ struct MaskInputData {
+ enum Casemode { NoCaseMode, Upper, Lower };
+ QChar maskChar; // either the separator char or the inputmask
+ bool separator;
+ Casemode caseMode;
+ };
+ QString m_inputMask;
+ QChar m_blank;
+ MaskInputData *m_maskData;
+
+ // undo/redo handling
+ enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection, SetSelection };
+ struct Command {
+ inline Command() {}
+ inline Command(CommandType t, int p, QChar c, int ss, int se) : type(t),uc(c),pos(p),selStart(ss),selEnd(se) {}
+ uint type : 4;
+ QChar uc;
+ int pos, selStart, selEnd;
+ };
+ int m_modifiedState;
+ int m_undoState;
+ QVector<Command> m_history;
+ void addCommand(const Command& cmd);
+
+ inline void separate() { m_separator = true; }
+
+ // selection
+ int m_selstart;
+ int m_selend;
+
+ // masking
+ void parseInputMask(const QString &maskFields);
+ bool isValidInput(QChar key, QChar mask) const;
+ bool hasAcceptableInput(const QString &text) const;
+ QString maskString(uint pos, const QString &str, bool clear = false) const;
+ QString clearString(uint pos, uint len) const;
+ QString stripString(const QString &str) const;
+ int findInMask(int pos, bool forward, bool findSeparator, QChar searchChar = QChar()) const;
+
+ // complex text layout
+ QTextLayout m_textLayout;
+
+ bool m_passwordEchoEditing;
+ QChar m_passwordCharacter;
+
+Q_SIGNALS:
+ void cursorPositionChanged(int, int);
+ void selectionChanged();
+
+ void displayTextChanged(const QString &);
+ void textChanged(const QString &);
+ void textEdited(const QString &);
+
+ void resetInputContext();
+ void updateMicroFocus();
+
+ void accepted();
+ void editingFinished();
+ void updateNeeded(const QRect &);
+
+#ifdef QT_KEYPAD_NAVIGATION
+ void editFocusChange(bool);
+#endif
+protected:
+ virtual void timerEvent(QTimerEvent *event);
+
+private Q_SLOTS:
+ void _q_clipboardChanged();
+ void _q_deleteSelected();
+
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QLineControl_P_H
diff --git a/src/gui/text/qplatformfontdatabase_qpa.cpp b/src/gui/text/qplatformfontdatabase_qpa.cpp
index 059dc3e188..7ad838561b 100644
--- a/src/gui/text/qplatformfontdatabase_qpa.cpp
+++ b/src/gui/text/qplatformfontdatabase_qpa.cpp
@@ -344,6 +344,30 @@ QString QPlatformFontDatabase::fontDir() const
}
/*!
+ Returns the default system font.
+
+ \sa QGuiApplication::font()
+ \since 5.0
+*/
+
+QFont QPlatformFontDatabase::defaultFont() const
+{
+ return QFont(QLatin1String("Helvetica"));
+}
+
+/*!
+ Returns fonts for class names.
+
+ \sa QGuiApplication::font()
+ \since 5.0
+*/
+
+QHash<QByteArray, QFont> QPlatformFontDatabase::defaultFonts() const
+{
+ return QHash<QByteArray, QFont>();
+}
+
+/*!
\class QPlatformFontDatabase
\brief The QPlatformFontDatabase class makes it possible to customize how fonts
are discovered and how they are rendered
diff --git a/src/gui/text/qplatformfontdatabase_qpa.h b/src/gui/text/qplatformfontdatabase_qpa.h
index 1fb3c32fea..d34d602e43 100644
--- a/src/gui/text/qplatformfontdatabase_qpa.h
+++ b/src/gui/text/qplatformfontdatabase_qpa.h
@@ -46,6 +46,7 @@
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QList>
+#include <QtCore/QHash>
#include <QtGui/QFontDatabase>
#include <QtGui/private/qfont_p.h>
@@ -96,6 +97,9 @@ public:
virtual QString fontDir() const;
+ virtual QFont defaultFont() const;
+ virtual QHash<QByteArray, QFont> defaultFonts() const;
+
//callback
static void registerQPF2Font(const QByteArray &dataArray, void *handle);
static void registerFont(const QString &familyname, const QString &foundryname, QFont::Weight weight,
diff --git a/src/gui/text/qrawfont_mac.cpp b/src/gui/text/qrawfont_mac.cpp
deleted file mode 100644
index 40c719a1af..0000000000
--- a/src/gui/text/qrawfont_mac.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qglobal.h>
-
-#if !defined(QT_NO_RAWFONT)
-
-#include "qrawfont_p.h"
-#include "qfontengine_coretext_p.h"
-
-QT_BEGIN_NAMESPACE
-
-void QRawFontPrivate::platformCleanUp()
-{
-}
-
-extern int qt_defaultDpi();
-
-void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData,
- qreal pixelSize,
- QFont::HintingPreference hintingPreference)
-{
- // Mac OS X ignores it
- Q_UNUSED(hintingPreference);
-
- QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(NULL,
- fontData.constData(), fontData.size(), NULL);
-
- CGFontRef cgFont = CGFontCreateWithDataProvider(dataProvider);
-
- if (cgFont == NULL) {
- qWarning("QRawFont::platformLoadFromData: CGFontCreateWithDataProvider failed");
- } else {
- QFontDef def;
- def.pixelSize = pixelSize;
- def.pointSize = pixelSize * 72.0 / qt_defaultDpi();
- fontEngine = new QCoreTextFontEngine(cgFont, def);
- CFRelease(cgFont);
- fontEngine->ref.ref();
- }
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_RAWFONT
diff --git a/src/gui/text/qrawfont_qpa.cpp b/src/gui/text/qrawfont_qpa.cpp
index 6a69804fac..47815baf06 100644
--- a/src/gui/text/qrawfont_qpa.cpp
+++ b/src/gui/text/qrawfont_qpa.cpp
@@ -45,7 +45,7 @@
#include "qrawfont_p.h"
#include <QtGui/qplatformfontdatabase_qpa.h>
-#include <private/qapplication_p.h>
+#include <private/qguiapplication_p.h>
QT_BEGIN_NAMESPACE
@@ -58,7 +58,7 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, qreal pix
{
Q_ASSERT(fontEngine == 0);
- QPlatformFontDatabase *pfdb = QApplicationPrivate::platformIntegration()->fontDatabase();
+ QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
fontEngine = pfdb->fontEngine(fontData, pixelSize, hintingPreference);
if (fontEngine != 0)
fontEngine->ref.ref();
diff --git a/src/gui/text/qrawfont_win.cpp b/src/gui/text/qrawfont_win.cpp
deleted file mode 100644
index d8aa557975..0000000000
--- a/src/gui/text/qrawfont_win.cpp
+++ /dev/null
@@ -1,709 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qrawfont_p.h"
-#include <private/qsystemlibrary_p.h>
-
-#if !defined(QT_NO_DIRECTWRITE)
-# include "qfontenginedirectwrite_p.h"
-# include <dwrite.h>
-#endif
-
-#if !defined(QT_NO_RAWFONT)
-
-QT_BEGIN_NAMESPACE
-
-namespace {
-
- template<typename T>
- struct BigEndian
- {
- quint8 data[sizeof(T)];
-
- operator T() const
- {
- T littleEndian = 0;
- for (int i=0; i<sizeof(T); ++i) {
- littleEndian |= data[i] << ((sizeof(T) - i - 1) * 8);
- }
-
- return littleEndian;
- }
-
- BigEndian<T> &operator=(const T &t)
- {
- for (int i=0; i<sizeof(T); ++i) {
- data[i] = ((t >> (sizeof(T) - i - 1) * 8) & 0xff);
- }
-
- return *this;
- }
- };
-
-# pragma pack(1)
-
- // Common structure for all formats of the "name" table
- struct NameTable
- {
- BigEndian<quint16> format;
- BigEndian<quint16> count;
- BigEndian<quint16> stringOffset;
- };
-
- struct NameRecord
- {
- BigEndian<quint16> platformID;
- BigEndian<quint16> encodingID;
- BigEndian<quint16> languageID;
- BigEndian<quint16> nameID;
- BigEndian<quint16> length;
- BigEndian<quint16> offset;
- };
-
- struct OffsetSubTable
- {
- BigEndian<quint32> scalerType;
- BigEndian<quint16> numTables;
- BigEndian<quint16> searchRange;
- BigEndian<quint16> entrySelector;
- BigEndian<quint16> rangeShift;
- };
-
- struct TableDirectory
- {
- BigEndian<quint32> identifier;
- BigEndian<quint32> checkSum;
- BigEndian<quint32> offset;
- BigEndian<quint32> length;
- };
-
- struct OS2Table
- {
- BigEndian<quint16> version;
- BigEndian<qint16> avgCharWidth;
- BigEndian<quint16> weightClass;
- BigEndian<quint16> widthClass;
- BigEndian<quint16> type;
- BigEndian<qint16> subscriptXSize;
- BigEndian<qint16> subscriptYSize;
- BigEndian<qint16> subscriptXOffset;
- BigEndian<qint16> subscriptYOffset;
- BigEndian<qint16> superscriptXSize;
- BigEndian<qint16> superscriptYSize;
- BigEndian<qint16> superscriptXOffset;
- BigEndian<qint16> superscriptYOffset;
- BigEndian<qint16> strikeOutSize;
- BigEndian<qint16> strikeOutPosition;
- BigEndian<qint16> familyClass;
- quint8 panose[10];
- BigEndian<quint32> unicodeRanges[4];
- quint8 vendorID[4];
- BigEndian<quint16> selection;
- BigEndian<quint16> firstCharIndex;
- BigEndian<quint16> lastCharIndex;
- BigEndian<qint16> typoAscender;
- BigEndian<qint16> typoDescender;
- BigEndian<qint16> typoLineGap;
- BigEndian<quint16> winAscent;
- BigEndian<quint16> winDescent;
- BigEndian<quint32> codepageRanges[2];
- BigEndian<qint16> height;
- BigEndian<qint16> capHeight;
- BigEndian<quint16> defaultChar;
- BigEndian<quint16> breakChar;
- BigEndian<quint16> maxContext;
- };
-
-# pragma pack()
-
- class EmbeddedFont
- {
- public:
- EmbeddedFont(const QByteArray &fontData);
-
- QString changeFamilyName(const QString &newFamilyName);
- QByteArray data() const { return m_fontData; }
- TableDirectory *tableDirectoryEntry(const QByteArray &tagName);
- QString familyName(TableDirectory *nameTableDirectory = 0);
-
- private:
- QByteArray m_fontData;
- };
-
- EmbeddedFont::EmbeddedFont(const QByteArray &fontData) : m_fontData(fontData)
- {
- }
-
- TableDirectory *EmbeddedFont::tableDirectoryEntry(const QByteArray &tagName)
- {
- Q_ASSERT(tagName.size() == 4);
-
- const BigEndian<quint32> *tagIdPtr =
- reinterpret_cast<const BigEndian<quint32> *>(tagName.constData());
- quint32 tagId = *tagIdPtr;
-
- OffsetSubTable *offsetSubTable = reinterpret_cast<OffsetSubTable *>(m_fontData.data());
- TableDirectory *tableDirectory = reinterpret_cast<TableDirectory *>(offsetSubTable + 1);
-
- TableDirectory *nameTableDirectoryEntry = 0;
- for (int i=0; i<offsetSubTable->numTables; ++i, ++tableDirectory) {
- if (tableDirectory->identifier == tagId) {
- nameTableDirectoryEntry = tableDirectory;
- break;
- }
- }
-
- return nameTableDirectoryEntry;
- }
-
- QString EmbeddedFont::familyName(TableDirectory *nameTableDirectoryEntry)
- {
- QString name;
-
- if (nameTableDirectoryEntry == 0)
- nameTableDirectoryEntry = tableDirectoryEntry("name");
-
- if (nameTableDirectoryEntry != 0) {
- NameTable *nameTable = reinterpret_cast<NameTable *>(m_fontData.data()
- + nameTableDirectoryEntry->offset);
- NameRecord *nameRecord = reinterpret_cast<NameRecord *>(nameTable + 1);
- for (int i=0; i<nameTable->count; ++i, ++nameRecord) {
- if (nameRecord->nameID == 1
- && nameRecord->platformID == 3 // Windows
- && nameRecord->languageID == 0x0409) { // US English
- const void *ptr = reinterpret_cast<const quint8 *>(nameTable)
- + nameTable->stringOffset
- + nameRecord->offset;
-
- const BigEndian<quint16> *s = reinterpret_cast<const BigEndian<quint16> *>(ptr);
- for (int j=0; j<nameRecord->length / sizeof(quint16); ++j)
- name += QChar(s[j]);
-
- break;
- }
- }
- }
-
- return name;
- }
-
- QString EmbeddedFont::changeFamilyName(const QString &newFamilyName)
- {
- TableDirectory *nameTableDirectoryEntry = tableDirectoryEntry("name");
- if (nameTableDirectoryEntry == 0)
- return QString();
-
- QString oldFamilyName = familyName(nameTableDirectoryEntry);
-
- // Reserve size for name table header, five required name records and string
- const int requiredRecordCount = 5;
- quint16 nameIds[requiredRecordCount] = { 1, 2, 3, 4, 6 };
-
- int sizeOfHeader = sizeof(NameTable) + sizeof(NameRecord) * requiredRecordCount;
- int newFamilyNameSize = newFamilyName.size() * sizeof(quint16);
-
- const QString regularString = QString::fromLatin1("Regular");
- int regularStringSize = regularString.size() * sizeof(quint16);
-
- // Align table size of table to 32 bits (pad with 0)
- int fullSize = ((sizeOfHeader + newFamilyNameSize + regularStringSize) & ~3) + 4;
-
- QByteArray newNameTable(fullSize, char(0));
-
- {
- NameTable *nameTable = reinterpret_cast<NameTable *>(newNameTable.data());
- nameTable->count = requiredRecordCount;
- nameTable->stringOffset = sizeOfHeader;
-
- NameRecord *nameRecord = reinterpret_cast<NameRecord *>(nameTable + 1);
- for (int i=0; i<requiredRecordCount; ++i, nameRecord++) {
- nameRecord->nameID = nameIds[i];
- nameRecord->encodingID = 1;
- nameRecord->languageID = 0x0409;
- nameRecord->platformID = 3;
- nameRecord->length = newFamilyNameSize;
-
- // Special case for sub-family
- if (nameIds[i] == 4) {
- nameRecord->offset = newFamilyNameSize;
- nameRecord->length = regularStringSize;
- }
- }
-
- // nameRecord now points to string data
- BigEndian<quint16> *stringStorage = reinterpret_cast<BigEndian<quint16> *>(nameRecord);
- const quint16 *sourceString = newFamilyName.utf16();
- for (int i=0; i<newFamilyName.size(); ++i)
- stringStorage[i] = sourceString[i];
- stringStorage += newFamilyName.size();
-
- sourceString = regularString.utf16();
- for (int i=0; i<regularString.size(); ++i)
- stringStorage[i] = sourceString[i];
- }
-
- quint32 *p = reinterpret_cast<quint32 *>(newNameTable.data());
- quint32 *tableEnd = reinterpret_cast<quint32 *>(newNameTable.data() + fullSize);
-
- quint32 checkSum = 0;
- while (p < tableEnd)
- checkSum += *(p++);
-
- nameTableDirectoryEntry->checkSum = checkSum;
- nameTableDirectoryEntry->offset = m_fontData.size();
- nameTableDirectoryEntry->length = fullSize;
-
- m_fontData.append(newNameTable);
-
- return oldFamilyName;
- }
-
-#if !defined(QT_NO_DIRECTWRITE)
-
- class DirectWriteFontFileStream: public IDWriteFontFileStream
- {
- public:
- DirectWriteFontFileStream(const QByteArray &fontData)
- : m_fontData(fontData)
- , m_referenceCount(0)
- {
- }
-
- ~DirectWriteFontFileStream()
- {
- }
-
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object);
- ULONG STDMETHODCALLTYPE AddRef();
- ULONG STDMETHODCALLTYPE Release();
-
- HRESULT STDMETHODCALLTYPE ReadFileFragment(const void **fragmentStart, UINT64 fileOffset,
- UINT64 fragmentSize, OUT void **fragmentContext);
- void STDMETHODCALLTYPE ReleaseFileFragment(void *fragmentContext);
- HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64 *fileSize);
- HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64 *lastWriteTime);
-
- private:
- QByteArray m_fontData;
- ULONG m_referenceCount;
- };
-
- HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::QueryInterface(REFIID iid, void **object)
- {
- if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) {
- *object = this;
- AddRef();
- return S_OK;
- } else {
- *object = NULL;
- return E_NOINTERFACE;
- }
- }
-
- ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::AddRef()
- {
- return InterlockedIncrement(&m_referenceCount);
- }
-
- ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::Release()
- {
- ULONG newCount = InterlockedDecrement(&m_referenceCount);
- if (newCount == 0)
- delete this;
- return newCount;
- }
-
- HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::ReadFileFragment(
- const void **fragmentStart,
- UINT64 fileOffset,
- UINT64 fragmentSize,
- OUT void **fragmentContext)
- {
- *fragmentContext = NULL;
- if (fragmentSize + fileOffset <= m_fontData.size()) {
- *fragmentStart = m_fontData.data() + fileOffset;
- return S_OK;
- } else {
- *fragmentStart = NULL;
- return E_FAIL;
- }
- }
-
- void STDMETHODCALLTYPE DirectWriteFontFileStream::ReleaseFileFragment(void *)
- {
- }
-
- HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetFileSize(UINT64 *fileSize)
- {
- *fileSize = m_fontData.size();
- return S_OK;
- }
-
- HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetLastWriteTime(UINT64 *lastWriteTime)
- {
- *lastWriteTime = 0;
- return E_NOTIMPL;
- }
-
- class DirectWriteFontFileLoader: public IDWriteFontFileLoader
- {
- public:
- DirectWriteFontFileLoader() : m_referenceCount(0) {}
-
- ~DirectWriteFontFileLoader()
- {
- }
-
- inline void addKey(const void *key, const QByteArray &fontData)
- {
- Q_ASSERT(!m_fontDatas.contains(key));
- m_fontDatas.insert(key, fontData);
- }
-
- inline void removeKey(const void *key)
- {
- m_fontDatas.remove(key);
- }
-
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object);
- ULONG STDMETHODCALLTYPE AddRef();
- ULONG STDMETHODCALLTYPE Release();
-
- HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const *fontFileReferenceKey,
- UINT32 fontFileReferenceKeySize,
- OUT IDWriteFontFileStream **fontFileStream);
-
- private:
- ULONG m_referenceCount;
- QHash<const void *, QByteArray> m_fontDatas;
- };
-
- HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::QueryInterface(const IID &iid,
- void **object)
- {
- if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) {
- *object = this;
- AddRef();
- return S_OK;
- } else {
- *object = NULL;
- return E_NOINTERFACE;
- }
- }
-
- ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::AddRef()
- {
- return InterlockedIncrement(&m_referenceCount);
- }
-
- ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::Release()
- {
- ULONG newCount = InterlockedDecrement(&m_referenceCount);
- if (newCount == 0)
- delete this;
- return newCount;
- }
-
- HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::CreateStreamFromKey(
- void const *fontFileReferenceKey,
- UINT32 fontFileReferenceKeySize,
- IDWriteFontFileStream **fontFileStream)
- {
- Q_UNUSED(fontFileReferenceKeySize);
-
- if (fontFileReferenceKeySize != sizeof(const void *)) {
- qWarning("DirectWriteFontFileLoader::CreateStreamFromKey: Wrong key size");
- return E_FAIL;
- }
-
- const void *key = *reinterpret_cast<void * const *>(fontFileReferenceKey);
- *fontFileStream = NULL;
- if (!m_fontDatas.contains(key))
- return E_FAIL;
-
- QByteArray fontData = m_fontDatas.value(key);
- DirectWriteFontFileStream *stream = new DirectWriteFontFileStream(fontData);
- stream->AddRef();
- *fontFileStream = stream;
-
- return S_OK;
- }
-
- class CustomFontFileLoader
- {
- public:
- CustomFontFileLoader() : m_directWriteFactory(0), m_directWriteFontFileLoader(0)
- {
- HRESULT hres = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
- __uuidof(IDWriteFactory),
- reinterpret_cast<IUnknown **>(&m_directWriteFactory));
- if (FAILED(hres)) {
- qErrnoWarning(hres, "CustomFontFileLoader::CustomFontFileLoader: "
- "DWriteCreateFactory failed.");
- } else {
- m_directWriteFontFileLoader = new DirectWriteFontFileLoader();
- m_directWriteFactory->RegisterFontFileLoader(m_directWriteFontFileLoader);
- }
- }
-
- ~CustomFontFileLoader()
- {
- if (m_directWriteFactory != 0 && m_directWriteFontFileLoader != 0)
- m_directWriteFactory->UnregisterFontFileLoader(m_directWriteFontFileLoader);
-
- if (m_directWriteFactory != 0)
- m_directWriteFactory->Release();
- }
-
- void addKey(const void *key, const QByteArray &fontData)
- {
- if (m_directWriteFontFileLoader != 0)
- m_directWriteFontFileLoader->addKey(key, fontData);
- }
-
- void removeKey(const void *key)
- {
- if (m_directWriteFontFileLoader != 0)
- m_directWriteFontFileLoader->removeKey(key);
- }
-
- IDWriteFontFileLoader *loader() const
- {
- return m_directWriteFontFileLoader;
- }
-
- private:
- IDWriteFactory *m_directWriteFactory;
- DirectWriteFontFileLoader *m_directWriteFontFileLoader;
- };
-
-#endif
-
-} // Anonymous namespace
-
-
-// From qfontdatabase_win.cpp
-extern QFontEngine *qt_load_font_engine_win(const QFontDef &request);
-// From qfontdatabase.cpp
-extern QFont::Weight weightFromInteger(int weight);
-
-void QRawFontPrivate::platformCleanUp()
-{
- if (fontHandle != NULL) {
- if (ptrRemoveFontMemResourceEx == NULL) {
- QFunctionPointer func =
- QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx");
- ptrRemoveFontMemResourceEx =
- reinterpret_cast<QRawFontPrivate::PtrRemoveFontMemResourceEx>(func);
- }
-
- if (ptrRemoveFontMemResourceEx == NULL) {
- qWarning("QRawFont::platformCleanUp: Can't find RemoveFontMemResourceEx in gdi32");
- fontHandle = NULL;
- } else {
- ptrRemoveFontMemResourceEx(fontHandle);
- fontHandle = NULL;
- }
- }
-}
-
-void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
- qreal pixelSize,
- QFont::HintingPreference hintingPreference)
-{
- QByteArray fontData(_fontData);
- EmbeddedFont font(fontData);
-
-#if !defined(QT_NO_DIRECTWRITE)
- if (hintingPreference == QFont::PreferDefaultHinting
- || hintingPreference == QFont::PreferFullHinting)
-#endif
- {
- GUID guid;
- CoCreateGuid(&guid);
-
- QString uniqueFamilyName = QString::fromLatin1("f")
- + QString::number(guid.Data1, 36) + QLatin1Char('-')
- + QString::number(guid.Data2, 36) + QLatin1Char('-')
- + QString::number(guid.Data3, 36) + QLatin1Char('-')
- + QString::number(*reinterpret_cast<quint64 *>(guid.Data4), 36);
-
- QString actualFontName = font.changeFamilyName(uniqueFamilyName);
- if (actualFontName.isEmpty()) {
- qWarning("QRawFont::platformLoadFromData: Can't change family name of font");
- return;
- }
-
- if (ptrAddFontMemResourceEx == NULL || ptrRemoveFontMemResourceEx == NULL) {
- QFunctionPointer func =
- QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx");
- ptrRemoveFontMemResourceEx =
- reinterpret_cast<QRawFontPrivate::PtrRemoveFontMemResourceEx>(func);
-
- func = QSystemLibrary::resolve(QLatin1String("gdi32"), "AddFontMemResourceEx");
- ptrAddFontMemResourceEx =
- reinterpret_cast<QRawFontPrivate::PtrAddFontMemResourceEx>(func);
- }
-
- Q_ASSERT(fontHandle == NULL);
- if (ptrAddFontMemResourceEx != NULL && ptrRemoveFontMemResourceEx != NULL) {
- DWORD count = 0;
- fontData = font.data();
- fontHandle = ptrAddFontMemResourceEx(fontData.data(), fontData.size(), 0, &count);
-
- if (count == 0 && fontHandle != NULL) {
- ptrRemoveFontMemResourceEx(fontHandle);
- fontHandle = NULL;
- }
- }
-
- if (fontHandle == NULL) {
- qWarning("QRawFont::platformLoadFromData: AddFontMemResourceEx failed");
- } else {
- QFontDef request;
- request.family = uniqueFamilyName;
- request.pixelSize = pixelSize;
- request.styleStrategy = QFont::NoFontMerging | QFont::PreferMatch;
- request.hintingPreference = hintingPreference;
-
- fontEngine = qt_load_font_engine_win(request);
- if (request.family != fontEngine->fontDef.family) {
- qWarning("QRawFont::platformLoadFromData: Failed to load font. "
- "Got fallback instead: %s", qPrintable(fontEngine->fontDef.family));
- if (fontEngine->cache_count == 0 && fontEngine->ref == 0)
- delete fontEngine;
- fontEngine = 0;
- } else {
- Q_ASSERT(fontEngine->cache_count == 0 && fontEngine->ref == 0);
-
- // Override the generated font name
- static_cast<QFontEngineWin *>(fontEngine)->uniqueFamilyName = uniqueFamilyName;
- fontEngine->fontDef.family = actualFontName;
- fontEngine->ref.ref();
- }
- }
- }
-#if !defined(QT_NO_DIRECTWRITE)
- else {
- CustomFontFileLoader fontFileLoader;
- fontFileLoader.addKey(this, fontData);
-
- IDWriteFactory *factory = NULL;
- HRESULT hres = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
- __uuidof(IDWriteFactory),
- reinterpret_cast<IUnknown **>(&factory));
- if (FAILED(hres)) {
- qErrnoWarning(hres, "QRawFont::platformLoadFromData: DWriteCreateFactory failed");
- return;
- }
-
- IDWriteFontFile *fontFile = NULL;
- void *key = this;
-
- hres = factory->CreateCustomFontFileReference(&key, sizeof(void *),
- fontFileLoader.loader(), &fontFile);
- if (FAILED(hres)) {
- qErrnoWarning(hres, "QRawFont::platformLoadFromData: "
- "CreateCustomFontFileReference failed");
- factory->Release();
- return;
- }
-
- BOOL isSupportedFontType;
- DWRITE_FONT_FILE_TYPE fontFileType;
- DWRITE_FONT_FACE_TYPE fontFaceType;
- UINT32 numberOfFaces;
- fontFile->Analyze(&isSupportedFontType, &fontFileType, &fontFaceType, &numberOfFaces);
- if (!isSupportedFontType) {
- fontFile->Release();
- factory->Release();
- return;
- }
-
- IDWriteFontFace *directWriteFontFace = NULL;
- hres = factory->CreateFontFace(fontFaceType, 1, &fontFile, 0, DWRITE_FONT_SIMULATIONS_NONE,
- &directWriteFontFace);
- if (FAILED(hres)) {
- qErrnoWarning(hres, "QRawFont::platformLoadFromData: CreateFontFace failed");
- fontFile->Release();
- factory->Release();
- return;
- }
-
- fontFile->Release();
-
- fontEngine = new QFontEngineDirectWrite(factory, directWriteFontFace, pixelSize);
-
- // Get font family from font data
- fontEngine->fontDef.family = font.familyName();
- fontEngine->ref.ref();
-
- directWriteFontFace->Release();
- factory->Release();
- }
-#endif
-
- // Get style and weight info
- if (fontEngine != 0) {
- TableDirectory *os2TableEntry = font.tableDirectoryEntry("OS/2");
- if (os2TableEntry != 0) {
- const OS2Table *os2Table =
- reinterpret_cast<const OS2Table *>(fontData.constData()
- + os2TableEntry->offset);
-
- bool italic = os2Table->selection & 1;
- bool oblique = os2Table->selection & 128;
-
- if (italic)
- fontEngine->fontDef.style = QFont::StyleItalic;
- else if (oblique)
- fontEngine->fontDef.style = QFont::StyleOblique;
- else
- fontEngine->fontDef.style = QFont::StyleNormal;
-
- fontEngine->fontDef.weight = weightFromInteger(os2Table->weightClass);
- }
- }
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_RAWFONT
diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp
index 388be3999c..10c494dec9 100644
--- a/src/gui/text/qstatictext.cpp
+++ b/src/gui/text/qstatictext.cpp
@@ -45,8 +45,6 @@
#include <private/qfontengine_p.h>
#include <qabstracttextdocumentlayout.h>
-#include <QtGui/qapplication.h>
-
QT_BEGIN_NAMESPACE
/*!
diff --git a/src/gui/text/qsyntaxhighlighter.cpp b/src/gui/text/qsyntaxhighlighter.cpp
index 5d6c0052f4..5f1a53b556 100644
--- a/src/gui/text/qsyntaxhighlighter.cpp
+++ b/src/gui/text/qsyntaxhighlighter.cpp
@@ -50,7 +50,6 @@
#include <qtextobject.h>
#include <qtextcursor.h>
#include <qdebug.h>
-#include <qtextedit.h>
#include <qtimer.h>
QT_BEGIN_NAMESPACE
@@ -311,10 +310,19 @@ void QSyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block)
/*!
Constructs a QSyntaxHighlighter with the given \a parent.
+
+ If the parent is a QTextEdit, it installs the syntaxhighlighter on the
+ parents document. The specified QTextEdit also becomes the owner of
+ the QSyntaxHighlighter.
*/
QSyntaxHighlighter::QSyntaxHighlighter(QObject *parent)
: QObject(*new QSyntaxHighlighterPrivate, parent)
{
+ if (parent->inherits("QTextEdit")) {
+ QTextDocument *doc = qobject_cast<QTextDocument *>(parent->property("document").value<QObject *>());
+ if (doc)
+ setDocument(doc);
+ }
}
/*!
@@ -329,17 +337,6 @@ QSyntaxHighlighter::QSyntaxHighlighter(QTextDocument *parent)
}
/*!
- Constructs a QSyntaxHighlighter and installs it on \a parent 's
- QTextDocument. The specified QTextEdit also becomes the owner of
- the QSyntaxHighlighter.
-*/
-QSyntaxHighlighter::QSyntaxHighlighter(QTextEdit *parent)
- : QObject(*new QSyntaxHighlighterPrivate, parent)
-{
- setDocument(parent->document());
-}
-
-/*!
Destructor. Uninstalls this syntax highlighter from the text document.
*/
QSyntaxHighlighter::~QSyntaxHighlighter()
diff --git a/src/gui/text/qsyntaxhighlighter.h b/src/gui/text/qsyntaxhighlighter.h
index 9ee09c1f1d..1c421d1c26 100644
--- a/src/gui/text/qsyntaxhighlighter.h
+++ b/src/gui/text/qsyntaxhighlighter.h
@@ -61,7 +61,6 @@ class QTextCharFormat;
class QFont;
class QColor;
class QTextBlockUserData;
-class QTextEdit;
class Q_GUI_EXPORT QSyntaxHighlighter : public QObject
{
@@ -70,7 +69,6 @@ class Q_GUI_EXPORT QSyntaxHighlighter : public QObject
public:
QSyntaxHighlighter(QObject *parent);
QSyntaxHighlighter(QTextDocument *parent);
- QSyntaxHighlighter(QTextEdit *parent);
virtual ~QSyntaxHighlighter();
void setDocument(QTextDocument *doc);
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index c29379ed28..9ca6a24ce7 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -51,43 +51,40 @@
#include <qmime.h>
#include <qdrag.h>
#include <qclipboard.h>
-#include <qmenu.h>
-#include <qstyle.h>
#include <qtimer.h>
#include "private/qtextdocumentlayout_p.h"
#include "private/qabstracttextdocumentlayout_p.h"
-#include "private/qtextedit_p.h"
#include "qtextdocument.h"
#include "private/qtextdocument_p.h"
#include "qtextlist.h"
-#include "private/qtextcontrol_p.h"
-#include "qgraphicssceneevent.h"
-#include "qprinter.h"
#include "qtextdocumentwriter.h"
#include "private/qtextcursor_p.h"
+#include "qpagedpaintdevice.h"
+#include "private/qpagedpaintdevice_p.h"
#include <qtextformat.h>
#include <qdatetime.h>
#include <qbuffer.h>
-#include <qapplication.h>
+#include <qguiapplication.h>
#include <limits.h>
#include <qtexttable.h>
#include <qvariant.h>
#include <qurl.h>
-#include <qdesktopservices.h>
-#include <qinputcontext.h>
-#include <qtooltip.h>
-#include <qstyleoption.h>
-#include <QtGui/qlineedit.h>
-#ifndef QT_NO_SHORTCUT
-#include "private/qapplication_p.h"
-#include "private/qshortcutmap_p.h"
-#include <qkeysequence.h>
-#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1Char('\t') + QString(QKeySequence(k)) : QString())
-#else
-#define ACCEL_KEY(k) QString()
-#endif
+// ### these should come from the application
+const int startDragDistance = 10;
+const int cursorFlashTime = 2000;
+const int textCursorWidth = 1;
+const bool fullWidthSelection = true;
+
+//#ifndef QT_NO_SHORTCUT
+//#include "private/QGuiApplication_p.h"
+//#include "private/qshortcutmap_p.h"
+//#include <qkeysequence.h>
+//#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1Char('\t') + QString(QKeySequence(k)) : QString())
+//#else
+//#define ACCEL_KEY(k) QString()
+//#endif
QT_BEGIN_NAMESPACE
@@ -273,9 +270,9 @@ bool QTextControlPrivate::cursorMoveKeyEvent(QKeyEvent *e)
bool isNavigationEvent = e->key() == Qt::Key_Up || e->key() == Qt::Key_Down;
#ifdef QT_KEYPAD_NAVIGATION
- ignoreNavigationEvents = ignoreNavigationEvents || QApplication::keypadNavigationEnabled();
+ ignoreNavigationEvents = ignoreNavigationEvents || QGuiApplication::keypadNavigationEnabled();
isNavigationEvent = isNavigationEvent ||
- (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
+ (QGuiApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
&& (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right));
#else
isNavigationEvent = isNavigationEvent || e->key() == Qt::Key_Left || e->key() == Qt::Key_Right;
@@ -427,7 +424,7 @@ void QTextControlPrivate::setContent(Qt::TextFormat format, const QString &text,
doc = document;
clearDocument = false;
} else {
- palette = QApplication::palette("QTextControl");
+ palette = QGuiApplication::palette();
doc = new QTextDocument(q);
}
_q_documentLayoutChanged();
@@ -506,11 +503,11 @@ void QTextControlPrivate::startDrag()
#ifndef QT_NO_DRAGANDDROP
Q_Q(QTextControl);
mousePressed = false;
- if (!contextWidget)
+ if (!contextObject)
return;
QMimeData *data = q->createMimeDataFromSelection();
- QDrag *drag = new QDrag(contextWidget);
+ QDrag *drag = new QDrag(contextObject);
drag->setMimeData(data);
Qt::DropActions actions = Qt::CopyAction;
@@ -522,7 +519,7 @@ void QTextControlPrivate::startDrag()
action = drag->exec(actions, Qt::CopyAction);
}
- if (action == Qt::MoveAction && drag->target() != contextWidget)
+ if (action == Qt::MoveAction && drag->target() != contextObject)
cursor.removeSelectedText();
#endif
}
@@ -606,7 +603,7 @@ void QTextControlPrivate::_q_updateCurrentCharFormatAndSelection()
#ifndef QT_NO_CLIPBOARD
void QTextControlPrivate::setClipboardSelection()
{
- QClipboard *clipboard = QApplication::clipboard();
+ QClipboard *clipboard = QGuiApplication::clipboard();
if (!cursor.hasSelection() || !clipboard->supportsSelection())
return;
Q_Q(QTextControl);
@@ -638,8 +635,8 @@ void QTextControlPrivate::setBlinkingCursorEnabled(bool enable)
{
Q_Q(QTextControl);
- if (enable && QApplication::cursorFlashTime() > 0)
- cursorBlinkTimer.start(QApplication::cursorFlashTime() / 2, q);
+ if (enable && cursorFlashTime > 0)
+ cursorBlinkTimer.start(cursorFlashTime / 2, q);
else
cursorBlinkTimer.stop();
@@ -798,6 +795,18 @@ QTextControl::~QTextControl()
{
}
+void QTextControl::setView(QObject *view)
+{
+ Q_D(QTextControl);
+ d->contextObject = view;
+}
+
+QObject *QTextControl::view() const
+{
+ Q_D(const QTextControl);
+ return d->contextObject;
+}
+
void QTextControl::setDocument(QTextDocument *document)
{
Q_D(QTextControl);
@@ -859,12 +868,12 @@ void QTextControl::copy()
if (!d->cursor.hasSelection())
return;
QMimeData *data = createMimeDataFromSelection();
- QApplication::clipboard()->setMimeData(data);
+ QGuiApplication::clipboard()->setMimeData(data);
}
void QTextControl::paste(QClipboard::Mode mode)
{
- const QMimeData *md = QApplication::clipboard()->mimeData(mode);
+ const QMimeData *md = QGuiApplication::clipboard()->mimeData(mode);
if (md)
insertFromMimeData(md);
}
@@ -889,14 +898,14 @@ void QTextControl::selectAll()
emit updateRequest();
}
-void QTextControl::processEvent(QEvent *e, const QPointF &coordinateOffset, QWidget *contextWidget)
+void QTextControl::processEvent(QEvent *e, const QPointF &coordinateOffset)
{
QMatrix m;
m.translate(coordinateOffset.x(), coordinateOffset.y());
- processEvent(e, m, contextWidget);
+ processEvent(e, m);
}
-void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *contextWidget)
+void QTextControl::processEvent(QEvent *e, const QMatrix &matrix)
{
Q_D(QTextControl);
if (d->interactionFlags == Qt::NoTextInteraction) {
@@ -904,33 +913,6 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte
return;
}
- d->contextWidget = contextWidget;
-
- if (!d->contextWidget) {
- switch (e->type()) {
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneMouseMove:
- case QEvent::GraphicsSceneMousePress:
- case QEvent::GraphicsSceneMouseRelease:
- case QEvent::GraphicsSceneMouseDoubleClick:
- case QEvent::GraphicsSceneContextMenu:
- case QEvent::GraphicsSceneHoverEnter:
- case QEvent::GraphicsSceneHoverMove:
- case QEvent::GraphicsSceneHoverLeave:
- case QEvent::GraphicsSceneHelp:
- case QEvent::GraphicsSceneDragEnter:
- case QEvent::GraphicsSceneDragMove:
- case QEvent::GraphicsSceneDragLeave:
- case QEvent::GraphicsSceneDrop: {
- QGraphicsSceneEvent *ev = static_cast<QGraphicsSceneEvent *>(e);
- d->contextWidget = ev->widget();
- break;
- }
-#endif // QT_NO_GRAPHICSVIEW
- default: break;
- };
- }
-
switch (e->type()) {
case QEvent::KeyPress:
d->keyPressEvent(static_cast<QKeyEvent *>(e));
@@ -958,12 +940,6 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte
case QEvent::InputMethod:
d->inputMethodEvent(static_cast<QInputMethodEvent *>(e));
break;
-#ifndef QT_NO_CONTEXTMENU
- case QEvent::ContextMenu: {
- QContextMenuEvent *ev = static_cast<QContextMenuEvent *>(e);
- d->contextMenuEvent(ev->globalPos(), matrix.map(ev->pos()), contextWidget);
- break; }
-#endif // QT_NO_CONTEXTMENU
case QEvent::FocusIn:
case QEvent::FocusOut:
d->focusEvent(static_cast<QFocusEvent *>(e));
@@ -973,14 +949,6 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte
d->isEnabled = e->isAccepted();
break;
-#ifndef QT_NO_TOOLTIP
- case QEvent::ToolTip: {
- QHelpEvent *ev = static_cast<QHelpEvent *>(e);
- d->showToolTip(ev->globalPos(), matrix.map(ev->pos()), contextWidget);
- break;
- }
-#endif // QT_NO_TOOLTIP
-
#ifndef QT_NO_DRAGANDDROP
case QEvent::DragEnter: {
QDragEnterEvent *ev = static_cast<QDragEnterEvent *>(e);
@@ -1005,61 +973,10 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte
}
#endif
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneMousePress: {
- QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
- d->mousePressEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
- ev->screenPos());
- break; }
- case QEvent::GraphicsSceneMouseMove: {
- QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
- d->mouseMoveEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
- ev->screenPos());
- break; }
- case QEvent::GraphicsSceneMouseRelease: {
- QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
- d->mouseReleaseEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
- ev->screenPos());
- break; }
- case QEvent::GraphicsSceneMouseDoubleClick: {
- QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
- d->mouseDoubleClickEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
- ev->screenPos());
- break; }
- case QEvent::GraphicsSceneContextMenu: {
- QGraphicsSceneContextMenuEvent *ev = static_cast<QGraphicsSceneContextMenuEvent *>(e);
- d->contextMenuEvent(ev->screenPos(), matrix.map(ev->pos()), contextWidget);
- break; }
-
- case QEvent::GraphicsSceneHoverMove: {
- QGraphicsSceneHoverEvent *ev = static_cast<QGraphicsSceneHoverEvent *>(e);
- d->mouseMoveEvent(ev, Qt::NoButton, matrix.map(ev->pos()), ev->modifiers(),Qt::NoButton,
- ev->screenPos());
- break; }
-
- case QEvent::GraphicsSceneDragEnter: {
- QGraphicsSceneDragDropEvent *ev = static_cast<QGraphicsSceneDragDropEvent *>(e);
- if (d->dragEnterEvent(e, ev->mimeData()))
- ev->acceptProposedAction();
- break; }
- case QEvent::GraphicsSceneDragLeave:
- d->dragLeaveEvent();
- break;
- case QEvent::GraphicsSceneDragMove: {
- QGraphicsSceneDragDropEvent *ev = static_cast<QGraphicsSceneDragDropEvent *>(e);
- if (d->dragMoveEvent(e, ev->mimeData(), matrix.map(ev->pos())))
- ev->acceptProposedAction();
- break; }
- case QEvent::GraphicsSceneDrop: {
- QGraphicsSceneDragDropEvent *ev = static_cast<QGraphicsSceneDragDropEvent *>(e);
- if (d->dropEvent(ev->mimeData(), matrix.map(ev->pos()), ev->dropAction(), ev->source()))
- ev->accept();
- break; }
-#endif // QT_NO_GRAPHICSVIEW
#ifdef QT_KEYPAD_NAVIGATION
case QEvent::EnterEditFocus:
case QEvent::LeaveEditFocus:
- if (QApplication::keypadNavigationEnabled())
+ if (QGuiApplication::keypadNavigationEnabled())
d->editFocusEvent(e);
break;
#endif
@@ -1130,9 +1047,10 @@ void QTextControl::timerEvent(QTimerEvent *e)
if (e->timerId() == d->cursorBlinkTimer.timerId()) {
d->cursorOn = !d->cursorOn;
- if (d->cursor.hasSelection())
- d->cursorOn &= (QApplication::style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected)
- != 0);
+ // ###
+// if (d->cursor.hasSelection())
+// d->cursorOn &= (QGuiApplication::style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected)
+// != 0);
d->repaintCursor();
} else if (e->timerId() == d->trippleClickTimer.timerId()) {
@@ -1313,7 +1231,7 @@ process:
QVariant QTextControl::loadResource(int type, const QUrl &name)
{
-#ifdef QT_NO_TEXTEDIT
+#if 1
Q_UNUSED(type);
Q_UNUSED(name);
#else
@@ -1534,7 +1452,7 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con
#endif
if (trippleClickTimer.isActive()
- && ((pos - trippleClickPoint).toPoint().manhattanLength() < QApplication::startDragDistance())) {
+ && ((pos - trippleClickPoint).toPoint().manhattanLength() < startDragDistance)) {
cursor.movePosition(QTextCursor::StartOfBlock);
cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
@@ -1632,7 +1550,7 @@ void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, cons
const int oldCursorPos = cursor.position();
if (mightStartDrag) {
- if ((mousePos.toPoint() - dragStartPos).manhattanLength() > QApplication::startDragDistance())
+ if ((mousePos.toPoint() - dragStartPos).manhattanLength() > startDragDistance)
startDrag();
return;
}
@@ -1665,8 +1583,8 @@ void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, cons
if (cursor.position() != oldCursorPos)
emit q->cursorPositionChanged();
_q_updateCurrentCharFormatAndSelection();
-#ifndef QT_NO_IM
- if (contextWidget) {
+#if 0 // ### ndef QT_NO_IM
+ if (contextObject) {
if (QInputContext *ic = inputContext()) {
ic->update();
}
@@ -1709,9 +1627,9 @@ void QTextControlPrivate::mouseReleaseEvent(QEvent *e, Qt::MouseButton button, c
selectionChanged(true);
} else if (button == Qt::MidButton
&& (interactionFlags & Qt::TextEditable)
- && QApplication::clipboard()->supportsSelection()) {
+ && QGuiApplication::clipboard()->supportsSelection()) {
setCursorPosition(pos);
- const QMimeData *md = QApplication::clipboard()->mimeData(QClipboard::Selection);
+ const QMimeData *md = QGuiApplication::clipboard()->mimeData(QClipboard::Selection);
if (md)
q->insertFromMimeData(md);
#endif
@@ -1779,7 +1697,7 @@ void QTextControlPrivate::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton butto
selectedWordOnDoubleClick = cursor;
trippleClickPoint = pos;
- trippleClickTimer.start(QApplication::doubleClickInterval(), q);
+ trippleClickTimer.start(QGuiApplication::doubleClickInterval(), q);
if (doEmit) {
selectionChanged();
#ifndef QT_NO_CLIPBOARD
@@ -1793,11 +1711,11 @@ bool QTextControlPrivate::sendMouseEventToInputContext(
QEvent *e, QEvent::Type eventType, Qt::MouseButton button, const QPointF &pos,
Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons, const QPoint &globalPos)
{
-#if !defined(QT_NO_IM)
+#if 0 // ### !defined(QT_NO_IM)
Q_Q(QTextControl);
QTextLayout *layout = cursor.block().layout();
- if (contextWidget && layout && !layout->preeditAreaText().isEmpty()) {
+ if (contextObject && layout && !layout->preeditAreaText().isEmpty()) {
QInputContext *ctx = inputContext();
int cursorPos = q->hitTest(pos, Qt::FuzzyHit) - cursor.position();
@@ -1808,7 +1726,7 @@ bool QTextControlPrivate::sendMouseEventToInputContext(
return true;
}
if (ctx) {
- QMouseEvent ev(eventType, contextWidget->mapFromGlobal(globalPos), globalPos,
+ QMouseEvent ev(eventType, contextObject->mapFromGlobal(globalPos), globalPos,
button, buttons, modifiers);
ctx->mouseHandler(cursorPos, &ev);
e->setAccepted(ev.isAccepted());
@@ -1828,24 +1746,6 @@ bool QTextControlPrivate::sendMouseEventToInputContext(
return false;
}
-void QTextControlPrivate::contextMenuEvent(const QPoint &screenPos, const QPointF &docPos, QWidget *contextWidget)
-{
-#ifdef QT_NO_CONTEXTMENU
- Q_UNUSED(screenPos);
- Q_UNUSED(docPos);
- Q_UNUSED(contextWidget);
-#else
- Q_Q(QTextControl);
- if (!hasFocus)
- return;
- QMenu *menu = q->createStandardContextMenu(docPos, contextWidget);
- if (!menu)
- return;
- menu->setAttribute(Qt::WA_DeleteOnClose);
- menu->popup(screenPos);
-#endif
-}
-
bool QTextControlPrivate::dragEnterEvent(QEvent *e, const QMimeData *mimeData)
{
Q_Q(QTextControl);
@@ -1894,7 +1794,7 @@ bool QTextControlPrivate::dragMoveEvent(QEvent *e, const QMimeData *mimeData, co
return true; // accept proposed action
}
-bool QTextControlPrivate::dropEvent(const QMimeData *mimeData, const QPointF &pos, Qt::DropAction dropAction, QWidget *source)
+bool QTextControlPrivate::dropEvent(const QMimeData *mimeData, const QPointF &pos, Qt::DropAction dropAction, QObject *source)
{
Q_Q(QTextControl);
dndFeedbackCursor = QTextCursor();
@@ -1907,7 +1807,7 @@ bool QTextControlPrivate::dropEvent(const QMimeData *mimeData, const QPointF &po
QTextCursor insertionCursor = q->cursorForPosition(pos);
insertionCursor.beginEditBlock();
- if (dropAction == Qt::MoveAction && source == contextWidget)
+ if (dropAction == Qt::MoveAction && source == contextObject)
cursor.removeSelectedText();
cursor = insertionCursor;
@@ -1981,8 +1881,9 @@ void QTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
}
layout->setAdditionalFormats(overrides);
cursor.endEditBlock();
- if (cursor.d)
- cursor.d->setX();
+ QTextCursorPrivate *cursor_d = QTextCursorPrivate::getPrivate(&cursor);
+ if (cursor_d)
+ cursor_d->setX();
if (oldPreeditCursor != preeditCursor)
emit q->microFocusChanged();
selectionChanged(forceSelectionChanged);
@@ -2025,7 +1926,7 @@ void QTextControlPrivate::focusEvent(QFocusEvent *e)
emit q->updateRequest(q->selectionRect());
if (e->gotFocus()) {
#ifdef QT_KEYPAD_NAVIGATION
- if (!QApplication::keypadNavigationEnabled() || (hasEditFocus && (e->reason() == Qt::PopupFocusReason
+ if (!QGuiApplication::keypadNavigationEnabled() || (hasEditFocus && (e->reason() == Qt::PopupFocusReason
#ifdef Q_OS_SYMBIAN
|| e->reason() == Qt::ActiveWindowFocusReason
#endif
@@ -2070,7 +1971,7 @@ void QTextControlPrivate::editFocusEvent(QEvent *e)
{
Q_Q(QTextControl);
- if (QApplication::keypadNavigationEnabled()) {
+ if (QGuiApplication::keypadNavigationEnabled()) {
if (e->type() == QEvent::EnterEditFocus && interactionFlags & Qt::TextEditable) {
const QTextCursor oldSelection = cursor;
const int oldCursorPos = cursor.position();
@@ -2093,87 +1994,6 @@ void QTextControlPrivate::editFocusEvent(QEvent *e)
}
#endif
-#ifndef QT_NO_CONTEXTMENU
-QMenu *QTextControl::createStandardContextMenu(const QPointF &pos, QWidget *parent)
-{
- Q_D(QTextControl);
-
- const bool showTextSelectionActions = d->interactionFlags & (Qt::TextEditable | Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse);
-
- d->linkToCopy = QString();
- if (!pos.isNull())
- d->linkToCopy = anchorAt(pos);
-
- if (d->linkToCopy.isEmpty() && !showTextSelectionActions)
- return 0;
-
- QMenu *menu = new QMenu(parent);
- QAction *a;
-
- if (d->interactionFlags & Qt::TextEditable) {
- a = menu->addAction(tr("&Undo") + ACCEL_KEY(QKeySequence::Undo), this, SLOT(undo()));
- a->setEnabled(d->doc->isUndoAvailable());
- a = menu->addAction(tr("&Redo") + ACCEL_KEY(QKeySequence::Redo), this, SLOT(redo()));
- a->setEnabled(d->doc->isRedoAvailable());
- menu->addSeparator();
-
- a = menu->addAction(tr("Cu&t") + ACCEL_KEY(QKeySequence::Cut), this, SLOT(cut()));
- a->setEnabled(d->cursor.hasSelection());
- }
-
- if (showTextSelectionActions) {
- a = menu->addAction(tr("&Copy") + ACCEL_KEY(QKeySequence::Copy), this, SLOT(copy()));
- a->setEnabled(d->cursor.hasSelection());
- }
-
- if ((d->interactionFlags & Qt::LinksAccessibleByKeyboard)
- || (d->interactionFlags & Qt::LinksAccessibleByMouse)) {
-
- a = menu->addAction(tr("Copy &Link Location"), this, SLOT(_q_copyLink()));
- a->setEnabled(!d->linkToCopy.isEmpty());
- }
-
- if (d->interactionFlags & Qt::TextEditable) {
-#if !defined(QT_NO_CLIPBOARD)
- a = menu->addAction(tr("&Paste") + ACCEL_KEY(QKeySequence::Paste), this, SLOT(paste()));
- a->setEnabled(canPaste());
-#endif
- a = menu->addAction(tr("Delete"), this, SLOT(_q_deleteSelected()));
- a->setEnabled(d->cursor.hasSelection());
- }
-
-
- if (showTextSelectionActions) {
- menu->addSeparator();
- a = menu->addAction(tr("Select All") + ACCEL_KEY(QKeySequence::SelectAll), this, SLOT(selectAll()));
- a->setEnabled(!d->doc->isEmpty());
- }
-
-#if !defined(QT_NO_IM)
- if (d->contextWidget) {
- QInputContext *qic = d->inputContext();
- if (qic) {
- QList<QAction *> imActions = qic->actions();
- for (int i = 0; i < imActions.size(); ++i)
- menu->addAction(imActions.at(i));
- }
- }
-#endif
-
-#if defined(Q_WS_WIN) || defined(Q_WS_X11)
- if ((d->interactionFlags & Qt::TextEditable) && qt_use_rtl_extensions) {
-#else
- if (d->interactionFlags & Qt::TextEditable) {
-#endif
- menu->addSeparator();
- QUnicodeControlCharacterMenu *ctrlCharacterMenu = new QUnicodeControlCharacterMenu(this, menu);
- menu->addMenu(ctrlCharacterMenu);
- }
-
- return menu;
-}
-#endif // QT_NO_CONTEXTMENU
-
QTextCursor QTextControl::cursorForPosition(const QPointF &pos) const
{
Q_D(const QTextControl);
@@ -2250,7 +2070,7 @@ void QTextControl::setCursorWidth(int width)
Q_UNUSED(width);
#else
if (width == -1)
- width = QApplication::style()->pixelMetric(QStyle::PM_TextCursorWidth);
+ width = textCursorWidth;
d->doc->documentLayout()->setProperty("cursorWidth", width);
#endif
d->repaintCursor();
@@ -2268,9 +2088,7 @@ void QTextControl::setAcceptRichText(bool accept)
d->acceptRichText = accept;
}
-#ifndef QT_NO_TEXTEDIT
-
-void QTextControl::setExtraSelections(const QList<QTextEdit::ExtraSelection> &selections)
+void QTextControl::setExtraSelections(const QVector<QAbstractTextDocumentLayout::Selection> &selections)
{
Q_D(QTextControl);
@@ -2281,7 +2099,7 @@ void QTextControl::setExtraSelections(const QList<QTextEdit::ExtraSelection> &se
}
for (int i = 0; i < selections.count(); ++i) {
- const QTextEdit::ExtraSelection &sel = selections.at(i);
+ const QAbstractTextDocumentLayout::Selection &sel = selections.at(i);
QHash<int, int>::iterator it = hash.find(sel.cursor.anchor());
if (it != hash.end()) {
const QAbstractTextDocumentLayout::Selection &esel = d->extraSelections.at(it.value());
@@ -2309,28 +2127,15 @@ void QTextControl::setExtraSelections(const QList<QTextEdit::ExtraSelection> &se
emit updateRequest(r);
}
- d->extraSelections.resize(selections.count());
- for (int i = 0; i < selections.count(); ++i) {
- d->extraSelections[i].cursor = selections.at(i).cursor;
- d->extraSelections[i].format = selections.at(i).format;
- }
+ d->extraSelections = selections;
}
-QList<QTextEdit::ExtraSelection> QTextControl::extraSelections() const
+QVector<QAbstractTextDocumentLayout::Selection> QTextControl::extraSelections() const
{
Q_D(const QTextControl);
- QList<QTextEdit::ExtraSelection> selections;
- for (int i = 0; i < d->extraSelections.count(); ++i) {
- QTextEdit::ExtraSelection sel;
- sel.cursor = d->extraSelections.at(i).cursor;
- sel.format = d->extraSelections.at(i).format;
- selections.append(sel);
- }
- return selections;
+ return d->extraSelections;
}
-#endif // QT_NO_TEXTEDIT
-
void QTextControl::setTextWidth(qreal width)
{
Q_D(QTextControl);
@@ -2390,7 +2195,7 @@ bool QTextControl::canPaste() const
#ifndef QT_NO_CLIPBOARD
Q_D(const QTextControl);
if (d->interactionFlags & Qt::TextEditable) {
- const QMimeData *md = QApplication::clipboard()->mimeData();
+ const QMimeData *md = QGuiApplication::clipboard()->mimeData();
return md && canInsertFromMimeData(md);
}
#endif
@@ -2435,16 +2240,14 @@ bool QTextControl::isWordSelectionEnabled() const
return d->wordSelectionEnabled;
}
-#ifndef QT_NO_PRINTER
-void QTextControl::print(QPrinter *printer) const
+void QTextControl::print(QPagedPaintDevice *printer) const
{
-#ifndef QT_NO_PRINTER
Q_D(const QTextControl);
- if (!printer || !printer->isValid())
+ if (!printer)
return;
QTextDocument *tempDoc = 0;
const QTextDocument *doc = d->doc;
- if (printer->printRange() == QPrinter::Selection) {
+ if (QPagedPaintDevicePrivate::get(printer)->printSelectionOnly) {
if (!d->cursor.hasSelection())
return;
tempDoc = new QTextDocument(const_cast<QTextDocument *>(doc));
@@ -2460,9 +2263,7 @@ void QTextControl::print(QPrinter *printer) const
}
doc->print(printer);
delete tempDoc;
-#endif
}
-#endif // QT_NO_PRINTER
QMimeData *QTextControl::createMimeDataFromSelection() const
{
@@ -2720,7 +2521,7 @@ void QTextControlPrivate::activateLinkUnderCursor(QString href)
}
repaintOldAndNewSelection(oldCursor);
-#ifndef QT_NO_DESKTOPSERVICES
+#if 0 // ###ndef QT_NO_DESKTOPSERVICES
if (openExternalLinks)
QDesktopServices::openUrl(href);
else
@@ -2728,16 +2529,6 @@ void QTextControlPrivate::activateLinkUnderCursor(QString href)
emit q_func()->linkActivated(href);
}
-#ifndef QT_NO_TOOLTIP
-void QTextControlPrivate::showToolTip(const QPoint &globalPos, const QPointF &pos, QWidget *contextWidget)
-{
- const QString toolTip = q_func()->cursorForPosition(pos).charFormat().toolTip();
- if (toolTip.isEmpty())
- return;
- QToolTip::showText(globalPos, toolTip, contextWidget);
-}
-#endif // QT_NO_TOOLTIP
-
bool QTextControl::setFocusToNextOrPreviousAnchor(bool next)
{
Q_D(QTextControl);
@@ -2974,7 +2765,7 @@ bool QTextControl::cursorOn() const
return d->cursorOn;
}
-QAbstractTextDocumentLayout::PaintContext QTextControl::getPaintContext(QWidget *widget) const
+QAbstractTextDocumentLayout::PaintContext QTextControl::getPaintContext() const
{
Q_D(const QTextControl);
@@ -2994,31 +2785,28 @@ QAbstractTextDocumentLayout::PaintContext QTextControl::getPaintContext(QWidget
if (!d->dndFeedbackCursor.isNull())
ctx.cursorPosition = d->dndFeedbackCursor.position();
#ifdef QT_KEYPAD_NAVIGATION
- if (!QApplication::keypadNavigationEnabled() || d->hasEditFocus)
+ if (!QGuiApplication::keypadNavigationEnabled() || d->hasEditFocus)
#endif
if (d->cursor.hasSelection()) {
QAbstractTextDocumentLayout::Selection selection;
selection.cursor = d->cursor;
- if (d->cursorIsFocusIndicator) {
+ if (0 && d->cursorIsFocusIndicator) {
+#if 0
+ // ###
QStyleOption opt;
opt.palette = ctx.palette;
QStyleHintReturnVariant ret;
- QStyle *style = QApplication::style();
+ QStyle *style = QGuiApplication::style();
if (widget)
style = widget->style();
style->styleHint(QStyle::SH_TextControl_FocusIndicatorTextCharFormat, &opt, widget, &ret);
selection.format = qvariant_cast<QTextFormat>(ret.variant).toCharFormat();
+#endif
} else {
QPalette::ColorGroup cg = d->hasFocus ? QPalette::Active : QPalette::Inactive;
selection.format.setBackground(ctx.palette.brush(cg, QPalette::Highlight));
selection.format.setForeground(ctx.palette.brush(cg, QPalette::HighlightedText));
- QStyleOption opt;
- QStyle *style = QApplication::style();
- if (widget) {
- opt.initFrom(widget);
- style = widget->style();
- }
- if (style->styleHint(QStyle::SH_RichText_FullWidthSelection, &opt, widget))
+ if (fullWidthSelection)
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
}
ctx.selections.append(selection);
@@ -3027,11 +2815,11 @@ QAbstractTextDocumentLayout::PaintContext QTextControl::getPaintContext(QWidget
return ctx;
}
-void QTextControl::drawContents(QPainter *p, const QRectF &rect, QWidget *widget)
+void QTextControl::drawContents(QPainter *p, const QRectF &rect)
{
Q_D(QTextControl);
p->save();
- QAbstractTextDocumentLayout::PaintContext ctx = getPaintContext(widget);
+ QAbstractTextDocumentLayout::PaintContext ctx = getPaintContext();
if (rect.isValid())
p->setClipRect(rect, Qt::IntersectClip);
ctx.clip = rect;
@@ -3045,16 +2833,21 @@ void QTextControlPrivate::_q_copyLink()
#ifndef QT_NO_CLIPBOARD
QMimeData *md = new QMimeData;
md->setText(linkToCopy);
- QApplication::clipboard()->setMimeData(md);
+ QGuiApplication::clipboard()->setMimeData(md);
#endif
}
QInputContext *QTextControlPrivate::inputContext()
{
- QInputContext *ctx = contextWidget->inputContext();
- if (!ctx && contextWidget->parentWidget())
- ctx = contextWidget->parentWidget()->inputContext();
+#if 0
+ // ###
+ QInputContext *ctx = contextObject->inputContext();
+ if (!ctx && contextObject->parentWidget())
+ ctx = contextObject->parentWidget()->inputContext();
return ctx;
+#else
+ return 0;
+#endif
}
int QTextControl::hitTest(const QPointF &point, Qt::HitTestAccuracy accuracy) const
@@ -3069,59 +2862,7 @@ QRectF QTextControl::blockBoundingRect(const QTextBlock &block) const
return d->doc->documentLayout()->blockBoundingRect(block);
}
-#ifndef QT_NO_CONTEXTMENU
-#define NUM_CONTROL_CHARACTERS 10
-const struct QUnicodeControlCharacter {
- const char *text;
- ushort character;
-} qt_controlCharacters[NUM_CONTROL_CHARACTERS] = {
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "LRM Left-to-right mark"), 0x200e },
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "RLM Right-to-left mark"), 0x200f },
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "ZWJ Zero width joiner"), 0x200d },
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "ZWNJ Zero width non-joiner"), 0x200c },
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "ZWSP Zero width space"), 0x200b },
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "LRE Start of left-to-right embedding"), 0x202a },
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "RLE Start of right-to-left embedding"), 0x202b },
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "LRO Start of left-to-right override"), 0x202d },
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "RLO Start of right-to-left override"), 0x202e },
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "PDF Pop directional formatting"), 0x202c },
-};
-
-QUnicodeControlCharacterMenu::QUnicodeControlCharacterMenu(QObject *_editWidget, QWidget *parent)
- : QMenu(parent), editWidget(_editWidget)
-{
- setTitle(tr("Insert Unicode control character"));
- for (int i = 0; i < NUM_CONTROL_CHARACTERS; ++i) {
- addAction(tr(qt_controlCharacters[i].text), this, SLOT(menuActionTriggered()));
- }
-}
-
-void QUnicodeControlCharacterMenu::menuActionTriggered()
-{
- QAction *a = qobject_cast<QAction *>(sender());
- int idx = actions().indexOf(a);
- if (idx < 0 || idx >= NUM_CONTROL_CHARACTERS)
- return;
- QChar c(qt_controlCharacters[idx].character);
- QString str(c);
-#ifndef QT_NO_TEXTEDIT
- if (QTextEdit *edit = qobject_cast<QTextEdit *>(editWidget)) {
- edit->insertPlainText(str);
- return;
- }
-#endif
- if (QTextControl *control = qobject_cast<QTextControl *>(editWidget)) {
- control->insertPlainText(str);
- }
-#ifndef QT_NO_LINEEDIT
- if (QLineEdit *edit = qobject_cast<QLineEdit *>(editWidget)) {
- edit->insert(str);
- return;
- }
-#endif
-}
-#endif // QT_NO_CONTEXTMENU
QStringList QTextEditMimeData::formats() const
{
diff --git a/src/gui/text/qtextcontrol_p.h b/src/gui/text/qtextcontrol_p.h
index c5ed0ee1e0..bb91415fd2 100644
--- a/src/gui/text/qtextcontrol_p.h
+++ b/src/gui/text/qtextcontrol_p.h
@@ -57,18 +57,11 @@
#include <QtGui/qtextoption.h>
#include <QtGui/qtextcursor.h>
#include <QtGui/qtextformat.h>
-#include <QtGui/qtextedit.h>
-#include <QtGui/qmenu.h>
#include <QtCore/qrect.h>
#include <QtGui/qabstracttextdocumentlayout.h>
#include <QtGui/qtextdocumentfragment.h>
#include <QtGui/qclipboard.h>
-#ifdef QT3_SUPPORT
-#include <QtGui/qtextobject.h>
-#include <QtGui/qtextlayout.h>
-#endif
-
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
@@ -77,12 +70,12 @@ QT_MODULE(Gui)
class QStyleSheet;
class QTextDocument;
-class QMenu;
class QTextControlPrivate;
class QMimeData;
class QAbstractScrollArea;
class QEvent;
class QTimerEvent;
+class QPagedPaintDevice;
class Q_GUI_EXPORT QTextControl : public QObject
{
@@ -103,6 +96,9 @@ public:
explicit QTextControl(QTextDocument *doc, QObject *parent = 0);
virtual ~QTextControl();
+ void setView(QObject *view);
+ QObject *view() const;
+
void setDocument(QTextDocument *document);
QTextDocument *document() const;
@@ -129,9 +125,6 @@ public:
virtual void ensureCursorVisible();
virtual QVariant loadResource(int type, const QUrl &name);
-#ifndef QT_NO_CONTEXTMENU
- QMenu *createStandardContextMenu(const QPointF &pos, QWidget *parent);
-#endif
QTextCursor cursorForPosition(const QPointF &pos) const;
QRectF cursorRect(const QTextCursor &cursor) const;
@@ -153,10 +146,8 @@ public:
bool acceptRichText() const;
void setAcceptRichText(bool accept);
-#ifndef QT_NO_TEXTEDIT
- void setExtraSelections(const QList<QTextEdit::ExtraSelection> &selections);
- QList<QTextEdit::ExtraSelection> extraSelections() const;
-#endif
+ void setExtraSelections(const QVector<QAbstractTextDocumentLayout::Selection> &selections);
+ QVector<QAbstractTextDocumentLayout::Selection> extraSelections() const;
void setTextWidth(qreal width);
qreal textWidth() const;
@@ -181,13 +172,11 @@ public:
bool isWordSelectionEnabled() const;
void setWordSelectionEnabled(bool enabled);
-#ifndef QT_NO_PRINTER
- void print(QPrinter *printer) const;
-#endif
+ void print(QPagedPaintDevice *printer) const;
virtual int hitTest(const QPointF &point, Qt::HitTestAccuracy accuracy) const;
virtual QRectF blockBoundingRect(const QTextBlock &block) const;
- QAbstractTextDocumentLayout::PaintContext getPaintContext(QWidget *widget) const;
+ QAbstractTextDocumentLayout::PaintContext getPaintContext() const;
public Q_SLOTS:
void setPlainText(const QString &text);
@@ -241,11 +230,11 @@ public:
QPalette palette() const;
void setPalette(const QPalette &pal);
- virtual void processEvent(QEvent *e, const QMatrix &matrix, QWidget *contextWidget = 0);
- void processEvent(QEvent *e, const QPointF &coordinateOffset = QPointF(), QWidget *contextWidget = 0);
+ virtual void processEvent(QEvent *e, const QMatrix &matrix);
+ void processEvent(QEvent *e, const QPointF &coordinateOffset = QPointF());
// control methods
- void drawContents(QPainter *painter, const QRectF &rect = QRectF(), QWidget *widget = 0);
+ void drawContents(QPainter *painter, const QRectF &rect = QRectF());
void setFocus(bool focus, Qt::FocusReason = Qt::OtherFocusReason);
@@ -277,22 +266,6 @@ private:
};
-#ifndef QT_NO_CONTEXTMENU
-class QUnicodeControlCharacterMenu : public QMenu
-{
- Q_OBJECT
-public:
- QUnicodeControlCharacterMenu(QObject *editWidget, QWidget *parent);
-
-private Q_SLOTS:
- void menuActionTriggered();
-
-private:
- QObject *editWidget;
-};
-#endif // QT_NO_CONTEXTMENU
-
-
// also used by QLabel
class QTextEditMimeData : public QMimeData
{
@@ -312,4 +285,4 @@ QT_END_NAMESPACE
QT_END_HEADER
-#endif // QTEXTCONTROL_H
+#endif // QTextControl_H
diff --git a/src/gui/text/qtextcontrol_p_p.h b/src/gui/text/qtextcontrol_p_p.h
index 1d7f9e9945..9c7ab56395 100644
--- a/src/gui/text/qtextcontrol_p_p.h
+++ b/src/gui/text/qtextcontrol_p_p.h
@@ -54,10 +54,8 @@
//
#include "QtGui/qtextdocumentfragment.h"
-#include "QtGui/qscrollbar.h"
#include "QtGui/qtextcursor.h"
#include "QtGui/qtextformat.h"
-#include "QtGui/qmenu.h"
#include "QtGui/qabstracttextdocumentlayout.h"
#include "QtCore/qbasictimer.h"
#include "QtCore/qpointer.h"
@@ -160,16 +158,12 @@ public:
bool dragEnterEvent(QEvent *e, const QMimeData *mimeData);
void dragLeaveEvent();
bool dragMoveEvent(QEvent *e, const QMimeData *mimeData, const QPointF &pos);
- bool dropEvent(const QMimeData *mimeData, const QPointF &pos, Qt::DropAction dropAction, QWidget *source);
+ bool dropEvent(const QMimeData *mimeData, const QPointF &pos, Qt::DropAction dropAction, QObject *source);
void inputMethodEvent(QInputMethodEvent *);
void activateLinkUnderCursor(QString href = QString());
-#ifndef QT_NO_TOOLTIP
- void showToolTip(const QPoint &globalPos, const QPointF &pos, QWidget *contextWidget);
-#endif
-
void append(const QString &text, Qt::TextFormat format = Qt::AutoText);
QInputContext *inputContext();
@@ -194,7 +188,7 @@ public:
bool mightStartDrag;
QPoint dragStartPos;
- QPointer<QWidget> contextWidget;
+ QPointer<QObject> contextObject;
bool lastSelectionState;
@@ -235,4 +229,4 @@ public:
QT_END_NAMESPACE
-#endif // QTEXTCONTROL_P_H
+#endif // QTextControl_P_H
diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h
index 697899bcfa..bc4cdb5fb6 100644
--- a/src/gui/text/qtextcursor.h
+++ b/src/gui/text/qtextcursor.h
@@ -228,9 +228,10 @@ public:
private:
QSharedDataPointer<QTextCursorPrivate> d;
+ friend class QTextCursorPrivate;
friend class QTextDocumentFragmentPrivate;
friend class QTextCopyHelper;
- friend class QTextControlPrivate;
+ friend class QWidgetTextControlPrivate;
};
QT_END_NAMESPACE
diff --git a/src/gui/text/qtextcursor_p.h b/src/gui/text/qtextcursor_p.h
index aae512b0d1..c612169acf 100644
--- a/src/gui/text/qtextcursor_p.h
+++ b/src/gui/text/qtextcursor_p.h
@@ -61,13 +61,15 @@
QT_BEGIN_NAMESPACE
-class QTextCursorPrivate : public QSharedData
+class Q_GUI_EXPORT QTextCursorPrivate : public QSharedData
{
public:
QTextCursorPrivate(QTextDocumentPrivate *p);
QTextCursorPrivate(const QTextCursorPrivate &rhs);
~QTextCursorPrivate();
+ static inline QTextCursorPrivate *getPrivate(QTextCursor *c) { return c->d; }
+
enum AdjustResult { CursorMoved, CursorUnchanged };
AdjustResult adjustPosition(int positionOfChange, int charsAddedOrRemoved, QTextUndoCommand::Operation op);
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 143dc1ab8c..c1714edb0c 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -51,22 +51,20 @@
#include <qvarlengtharray.h>
#include <qtextcodec.h>
#include <qthread.h>
+#include <qcoreapplication.h>
+
#include "qtexthtmlparser_p.h"
#include "qpainter.h"
-#include "qprinter.h"
-#include "qtextedit.h"
#include <qfile.h>
#include <qfileinfo.h>
#include <qdir.h>
-#include <qapplication.h>
-#include "qtextcontrol_p.h"
#include "qfont_p.h"
-#include "private/qtextedit_p.h"
#include "private/qdataurl_p.h"
#include "qtextdocument_p.h"
-#include <private/qprinter_p.h>
#include <private/qabstracttextdocumentlayout_p.h>
+#include "qpagedpaintdevice.h"
+#include "private/qpagedpaintdevice_p.h"
#include <limits.h>
@@ -1696,7 +1694,7 @@ static void printPage(int index, QPainter *painter, const QTextDocument *doc, co
}
/*!
- Prints the document to the given \a printer. The QPrinter must be
+ Prints the document to the given \a device. The QPageablePaintDevice must be
set up before being used with this function.
This is only a convenience method to print the whole document to the printer.
@@ -1706,33 +1704,32 @@ static void printPage(int index, QPainter *painter, const QTextDocument *doc, co
If the document is not paginated, like for example a document used in a QTextEdit,
then a temporary copy of the document is created and the copy is broken into
- multiple pages according to the size of the QPrinter's paperRect(). By default
+ multiple pages according to the size of the paint device's paperRect(). By default
a 2 cm margin is set around the document contents. In addition the current page
number is printed at the bottom of each page.
- Note that QPrinter::Selection is not supported as print range with this function since
- the selection is a property of QTextCursor. If you have a QTextEdit associated with
- your QTextDocument then you can use QTextEdit's print() function because QTextEdit has
- access to the user's selection.
-
\sa QTextEdit::print()
*/
-void QTextDocument::print(QPrinter *printer) const
+void QTextDocument::print(QPagedPaintDevice *printer) const
{
Q_D(const QTextDocument);
- if (!printer || !printer->isValid())
+ if (!printer)
return;
- if (!d->title.isEmpty())
- printer->setDocName(d->title);
-
bool documentPaginated = d->pageSize.isValid() && !d->pageSize.isNull()
&& d->pageSize.height() != INT_MAX;
- if (!documentPaginated && !printer->fullPage() && !printer->d_func()->hasCustomPageMargins)
- printer->setPageMargins(23.53, 23.53, 23.53, 23.53, QPrinter::Millimeter);
+ QPagedPaintDevicePrivate *pd = QPagedPaintDevicePrivate::get(printer);
+
+ // ### set page size to paginated size?
+ QPagedPaintDevice::Margins m = printer->margins();
+ if (!documentPaginated && m.left == 0. && m.right == 0. && m.top == 0. && m.bottom == 0.) {
+ m.left = m.right = m.top = m.bottom = 2.;
+ printer->setMargins(m);
+ }
+ // ### use the margins correctly
QPainter p(printer);
@@ -1767,7 +1764,7 @@ void QTextDocument::print(QPrinter *printer) const
scaledPageSize.rwidth() *= dpiScaleX;
scaledPageSize.rheight() *= dpiScaleY;
- const QSizeF printerPageSize(printer->pageRect().size());
+ const QSizeF printerPageSize(printer->width(), printer->height());
// scale to page
p.scale(printerPageSize.width() / scaledPageSize.width(),
@@ -1789,17 +1786,12 @@ void QTextDocument::print(QPrinter *printer) const
layout->d_func()->handlers = documentLayout()->d_func()->handlers;
int dpiy = p.device()->logicalDpiY();
- int margin = 0;
- if (printer->fullPage() && !printer->d_func()->hasCustomPageMargins) {
- // for compatibility
- margin = (int) ((2/2.54)*dpiy); // 2 cm margins
- QTextFrameFormat fmt = doc->rootFrame()->frameFormat();
- fmt.setMargin(margin);
- doc->rootFrame()->setFrameFormat(fmt);
- }
+ int margin = (int) ((2/2.54)*dpiy); // 2 cm margins
+ QTextFrameFormat fmt = doc->rootFrame()->frameFormat();
+ fmt.setMargin(margin);
+ doc->rootFrame()->setFrameFormat(fmt);
- QRectF pageRect(printer->pageRect());
- body = QRectF(0, 0, pageRect.width(), pageRect.height());
+ body = QRectF(0, 0, printer->width(), printer->height());
pageNumberPos = QPointF(body.width() - margin,
body.height() - margin
+ QFontMetrics(doc->defaultFont(), p.device()).ascent()
@@ -1807,18 +1799,8 @@ void QTextDocument::print(QPrinter *printer) const
clonedDoc->setPageSize(body.size());
}
- int docCopies;
- int pageCopies;
- if (printer->collateCopies() == true){
- docCopies = 1;
- pageCopies = printer->supportsMultipleCopies() ? 1 : printer->copyCount();
- } else {
- docCopies = printer->supportsMultipleCopies() ? 1 : printer->copyCount();
- pageCopies = 1;
- }
-
- int fromPage = printer->fromPage();
- int toPage = printer->toPage();
+ int fromPage = pd->fromPage;
+ int toPage = pd->toPage;
bool ascending = true;
if (fromPage == 0 && toPage == 0) {
@@ -1835,39 +1817,27 @@ void QTextDocument::print(QPrinter *printer) const
return;
}
- if (printer->pageOrder() == QPrinter::LastPageFirst) {
- int tmp = fromPage;
- fromPage = toPage;
- toPage = tmp;
- ascending = false;
- }
-
- for (int i = 0; i < docCopies; ++i) {
+// if (printer->pageOrder() == QPrinter::LastPageFirst) {
+// int tmp = fromPage;
+// fromPage = toPage;
+// toPage = tmp;
+// ascending = false;
+// }
- int page = fromPage;
- while (true) {
- for (int j = 0; j < pageCopies; ++j) {
- if (printer->printerState() == QPrinter::Aborted
- || printer->printerState() == QPrinter::Error)
- return;
- printPage(page, &p, doc, body, pageNumberPos);
- if (j < pageCopies - 1)
- printer->newPage();
- }
+ int page = fromPage;
+ while (true) {
+ printPage(page, &p, doc, body, pageNumberPos);
- if (page == toPage)
- break;
-
- if (ascending)
- ++page;
- else
- --page;
+ if (page == toPage)
+ break;
- printer->newPage();
- }
+ if (ascending)
+ ++page;
+ else
+ --page;
- if ( i < docCopies - 1)
- printer->newPage();
+ if (!printer->newPage())
+ return;
}
}
#endif
@@ -1971,6 +1941,8 @@ QVariant QTextDocument::loadResource(int type, const QUrl &name)
if (doc) {
r = doc->loadResource(type, name);
}
+#if 0
+ // ### Qt5: reenable
#ifndef QT_NO_TEXTEDIT
else if (QTextEdit *edit = qobject_cast<QTextEdit *>(parent())) {
QUrl resolvedName = edit->d_func()->resolveUrl(name);
@@ -1978,10 +1950,11 @@ QVariant QTextDocument::loadResource(int type, const QUrl &name)
}
#endif
#ifndef QT_NO_TEXTCONTROL
- else if (QTextControl *control = qobject_cast<QTextControl *>(parent())) {
+ else if (QWidgetTextControl *control = qobject_cast<QWidgetTextControl *>(parent())) {
r = control->loadResource(type, name);
}
#endif
+#endif
// handle data: URLs
if (r.isNull() && name.scheme().compare(QLatin1String("data"), Qt::CaseInsensitive) == 0)
diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h
index 268b72e514..363d7abb21 100644
--- a/src/gui/text/qtextdocument.h
+++ b/src/gui/text/qtextdocument.h
@@ -57,7 +57,7 @@ class QTextFormatCollection;
class QTextListFormat;
class QRect;
class QPainter;
-class QPrinter;
+class QPagedPaintDevice;
class QAbstractTextDocumentLayout;
class QPoint;
class QTextObject;
@@ -206,9 +206,7 @@ public:
bool isModified() const;
-#ifndef QT_NO_PRINTER
- void print(QPrinter *printer) const;
-#endif
+ void print(QPagedPaintDevice *printer) const;
enum ResourceType {
HtmlResource = 1,
diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp
index a50798834a..04bdfa8d30 100644
--- a/src/gui/text/qtextdocumentlayout.cpp
+++ b/src/gui/text/qtextdocumentlayout.cpp
@@ -46,6 +46,7 @@
#include "qtextlist.h"
#include "qtextengine_p.h"
#include "private/qcssutil_p.h"
+#include "private/qguiapplication_p.h"
#include "qabstracttextdocumentlayout_p.h"
#include "qcssparser_p.h"
@@ -57,7 +58,6 @@
#include <qdebug.h>
#include <qvarlengtharray.h>
#include <limits.h>
-#include <qstyle.h>
#include <qbasictimer.h>
#include "private/qfunctions_p.h"
@@ -2572,7 +2572,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi
Qt::Alignment align = docPrivate->defaultTextOption.alignment();
if (blockFormat.hasProperty(QTextFormat::BlockAlignment))
align = blockFormat.alignment();
- option.setAlignment(QStyle::visualAlignment(dir, align)); // for paragraph that are RTL, alignment is auto-reversed;
+ option.setAlignment(QGuiApplicationPrivate::visualAlignment(dir, align)); // for paragraph that are RTL, alignment is auto-reversed;
if (blockFormat.nonBreakableLines() || document->pageSize().width() < 0) {
option.setWrapMode(QTextOption::ManualWrap);
diff --git a/src/gui/text/qtextdocumentlayout_p.h b/src/gui/text/qtextdocumentlayout_p.h
index 620b9bd7dd..b103d886be 100644
--- a/src/gui/text/qtextdocumentlayout_p.h
+++ b/src/gui/text/qtextdocumentlayout_p.h
@@ -63,7 +63,7 @@ class QTextListFormat;
class QTextDocumentLayoutPrivate;
-class Q_AUTOTEST_EXPORT QTextDocumentLayout : public QAbstractTextDocumentLayout
+class Q_GUI_EXPORT QTextDocumentLayout : public QAbstractTextDocumentLayout
{
Q_DECLARE_PRIVATE(QTextDocumentLayout)
Q_OBJECT
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index f7b7aa28a1..58cccfcbf7 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -53,7 +53,7 @@
#include "qstring.h"
#include <private/qunicodetables_p.h>
#include "qtextdocument_p.h"
-#include <qapplication.h>
+#include <qguiapplication.h>
#include <stdlib.h>
@@ -1629,7 +1629,7 @@ bool QTextEngine::isRightToLeft() const
itemize();
// this places the cursor in the right position depending on the keyboard layout
if (layoutData->string.isEmpty())
- return QApplication::keyboardInputDirection() == Qt::RightToLeft;
+ return QGuiApplication::keyboardInputDirection() == Qt::RightToLeft;
return layoutData->string.isRightToLeft();
}
diff --git a/src/gui/text/qtextengine_mac.cpp b/src/gui/text/qtextengine_mac.cpp
deleted file mode 100644
index 251d9b5072..0000000000
--- a/src/gui/text/qtextengine_mac.cpp
+++ /dev/null
@@ -1,656 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qtextengine_p.h"
-
-#include <private/qfontengine_coretext_p.h>
-#include <private/qfontengine_mac_p.h>
-
-QT_BEGIN_NAMESPACE
-
-// set the glyph attributes heuristically. Assumes a 1 to 1 relationship between chars and glyphs
-// and no reordering.
-// also computes logClusters heuristically
-static void heuristicSetGlyphAttributes(const QChar *uc, int length, QGlyphLayout *glyphs, unsigned short *logClusters, int num_glyphs)
-{
- // ### zeroWidth and justification are missing here!!!!!
-
- Q_UNUSED(num_glyphs);
-
-// qDebug("QScriptEngine::heuristicSetGlyphAttributes, num_glyphs=%d", item->num_glyphs);
-
- const bool symbolFont = false; // ####
- glyphs->attributes[0].mark = false;
- glyphs->attributes[0].clusterStart = true;
- glyphs->attributes[0].dontPrint = (!symbolFont && uc[0].unicode() == 0x00ad) || qIsControlChar(uc[0].unicode());
-
- int pos = 0;
- int lastCat = QChar::category(uc[0].unicode());
- for (int i = 1; i < length; ++i) {
- if (logClusters[i] == pos)
- // same glyph
- continue;
- ++pos;
- while (pos < logClusters[i]) {
- ++pos;
- }
- // hide soft-hyphens by default
- if ((!symbolFont && uc[i].unicode() == 0x00ad) || qIsControlChar(uc[i].unicode()))
- glyphs->attributes[pos].dontPrint = true;
- const QUnicodeTables::Properties *prop = QUnicodeTables::properties(uc[i].unicode());
- int cat = prop->category;
-
- // one gets an inter character justification point if the current char is not a non spacing mark.
- // as then the current char belongs to the last one and one gets a space justification point
- // after the space char.
- if (lastCat == QChar::Separator_Space)
- glyphs->attributes[pos-1].justification = HB_Space;
- else if (cat != QChar::Mark_NonSpacing)
- glyphs->attributes[pos-1].justification = HB_Character;
- else
- glyphs->attributes[pos-1].justification = HB_NoJustification;
-
- lastCat = cat;
- }
- pos = logClusters[length-1];
- if (lastCat == QChar::Separator_Space)
- glyphs->attributes[pos].justification = HB_Space;
- else
- glyphs->attributes[pos].justification = HB_Character;
-}
-
-struct QArabicProperties {
- unsigned char shape;
- unsigned char justification;
-};
-Q_DECLARE_TYPEINFO(QArabicProperties, Q_PRIMITIVE_TYPE);
-
-enum QArabicShape {
- XIsolated,
- XFinal,
- XInitial,
- XMedial,
- // intermediate state
- XCausing
-};
-
-
-// these groups correspond to the groups defined in the Unicode standard.
-// Some of these groups are equal with regards to both joining and line breaking behaviour,
-// and thus have the same enum value
-//
-// I'm not sure the mapping of syriac to arabic enums is correct with regards to justification, but as
-// I couldn't find any better document I'll hope for the best.
-enum ArabicGroup {
- // NonJoining
- ArabicNone,
- ArabicSpace,
- // Transparent
- Transparent,
- // Causing
- Center,
- Kashida,
-
- // Arabic
- // Dual
- Beh,
- Noon,
- Meem = Noon,
- Heh = Noon,
- KnottedHeh = Noon,
- HehGoal = Noon,
- SwashKaf = Noon,
- Yeh,
- Hah,
- Seen,
- Sad = Seen,
- Tah,
- Kaf = Tah,
- Gaf = Tah,
- Lam = Tah,
- Ain,
- Feh = Ain,
- Qaf = Ain,
- // Right
- Alef,
- Waw,
- Dal,
- TehMarbuta = Dal,
- Reh,
- HamzaOnHehGoal,
- YehWithTail = HamzaOnHehGoal,
- YehBarre = HamzaOnHehGoal,
-
- // Syriac
- // Dual
- Beth = Beh,
- Gamal = Ain,
- Heth = Noon,
- Teth = Hah,
- Yudh = Noon,
- Kaph = Noon,
- Lamadh = Lam,
- Mim = Noon,
- Nun = Noon,
- Semakh = Noon,
- FinalSemakh = Noon,
- SyriacE = Ain,
- Pe = Ain,
- ReversedPe = Hah,
- Qaph = Noon,
- Shin = Noon,
- Fe = Ain,
-
- // Right
- Alaph = Alef,
- Dalath = Dal,
- He = Dal,
- SyriacWaw = Waw,
- Zain = Alef,
- YudhHe = Waw,
- Sadhe = HamzaOnHehGoal,
- Taw = Dal,
-
- // Compiler bug? Otherwise ArabicGroupsEnd would be equal to Dal + 1.
- Dummy = HamzaOnHehGoal,
- ArabicGroupsEnd
-};
-
-static const unsigned char arabic_group[0x150] = {
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-
- Transparent, Transparent, Transparent, Transparent,
- Transparent, Transparent, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-
- ArabicNone, ArabicNone, Alef, Alef,
- Waw, Alef, Yeh, Alef,
- Beh, TehMarbuta, Beh, Beh,
- Hah, Hah, Hah, Dal,
-
- Dal, Reh, Reh, Seen,
- Seen, Sad, Sad, Tah,
- Tah, Ain, Ain, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-
- // 0x640
- Kashida, Feh, Qaf, Kaf,
- Lam, Meem, Noon, Heh,
- Waw, Yeh, Yeh, Transparent,
- Transparent, Transparent, Transparent, Transparent,
-
- Transparent, Transparent, Transparent, Transparent,
- Transparent, Transparent, Transparent, Transparent,
- Transparent, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, Beh, Qaf,
-
- Transparent, Alef, Alef, Alef,
- ArabicNone, Alef, Waw, Waw,
- Yeh, Beh, Beh, Beh,
- Beh, Beh, Beh, Beh,
-
- // 0x680
- Beh, Hah, Hah, Hah,
- Hah, Hah, Hah, Hah,
- Dal, Dal, Dal, Dal,
- Dal, Dal, Dal, Dal,
-
- Dal, Reh, Reh, Reh,
- Reh, Reh, Reh, Reh,
- Reh, Reh, Seen, Seen,
- Seen, Sad, Sad, Tah,
-
- Ain, Feh, Feh, Feh,
- Feh, Feh, Feh, Qaf,
- Qaf, Gaf, SwashKaf, Gaf,
- Kaf, Kaf, Kaf, Gaf,
-
- Gaf, Gaf, Gaf, Gaf,
- Gaf, Lam, Lam, Lam,
- Lam, Noon, Noon, Noon,
- Noon, Noon, KnottedHeh, Hah,
-
- // 0x6c0
- TehMarbuta, HehGoal, HamzaOnHehGoal, HamzaOnHehGoal,
- Waw, Waw, Waw, Waw,
- Waw, Waw, Waw, Waw,
- Yeh, YehWithTail, Yeh, Waw,
-
- Yeh, Yeh, YehBarre, YehBarre,
- ArabicNone, TehMarbuta, Transparent, Transparent,
- Transparent, Transparent, Transparent, Transparent,
- Transparent, ArabicNone, ArabicNone, Transparent,
-
- Transparent, Transparent, Transparent, Transparent,
- Transparent, ArabicNone, ArabicNone, Transparent,
- Transparent, ArabicNone, Transparent, Transparent,
- Transparent, Transparent, Dal, Reh,
-
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, Seen, Sad,
- Ain, ArabicNone, ArabicNone, KnottedHeh,
-
- // 0x700
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-
- Alaph, Transparent, Beth, Gamal,
- Gamal, Dalath, Dalath, He,
- SyriacWaw, Zain, Heth, Teth,
- Teth, Yudh, YudhHe, Kaph,
-
- Lamadh, Mim, Nun, Semakh,
- FinalSemakh, SyriacE, Pe, ReversedPe,
- Sadhe, Qaph, Dalath, Shin,
- Taw, Beth, Gamal, Dalath,
-
- Transparent, Transparent, Transparent, Transparent,
- Transparent, Transparent, Transparent, Transparent,
- Transparent, Transparent, Transparent, Transparent,
- Transparent, Transparent, Transparent, Transparent,
-
- Transparent, Transparent, Transparent, Transparent,
- Transparent, Transparent, Transparent, Transparent,
- Transparent, Transparent, Transparent, ArabicNone,
- ArabicNone, Zain, Kaph, Fe,
-};
-
-static inline ArabicGroup arabicGroup(unsigned short uc)
-{
- if (uc >= 0x0600 && uc < 0x750)
- return (ArabicGroup) arabic_group[uc-0x600];
- else if (uc == 0x200d)
- return Center;
- else if (QChar::category(uc) == QChar::Separator_Space)
- return ArabicSpace;
- else
- return ArabicNone;
-}
-
-
-/*
- Arabic shaping obeys a number of rules according to the joining classes (see Unicode book, section on
- arabic).
-
- Each unicode char has a joining class (right, dual (left&right), center (joincausing) or transparent).
- transparent joining is not encoded in QChar::joining(), but applies to all combining marks and format marks.
-
- Right join-causing: dual + center
- Left join-causing: dual + right + center
-
- Rules are as follows (for a string already in visual order, as we have it here):
-
- R1 Transparent characters do not affect joining behaviour.
- R2 A right joining character, that has a right join-causing char on the right will get form XRight
- (R3 A left joining character, that has a left join-causing char on the left will get form XLeft)
- Note: the above rule is meaningless, as there are no pure left joining characters defined in Unicode
- R4 A dual joining character, that has a left join-causing char on the left and a right join-causing char on
- the right will get form XMedial
- R5 A dual joining character, that has a right join causing char on the right, and no left join causing char on the left
- will get form XRight
- R6 A dual joining character, that has a left join causing char on the left, and no right join causing char on the right
- will get form XLeft
- R7 Otherwise the character will get form XIsolated
-
- Additionally we have to do the minimal ligature support for lam-alef ligatures:
-
- L1 Transparent characters do not affect ligature behaviour.
- L2 Any sequence of Alef(XRight) + Lam(XMedial) will form the ligature Alef.Lam(XLeft)
- L3 Any sequence of Alef(XRight) + Lam(XLeft) will form the ligature Alef.Lam(XIsolated)
-
- The state table below handles rules R1-R7.
-*/
-
-enum Joining {
- JNone,
- JCausing,
- JDual,
- JRight,
- JTransparent
-};
-
-static const Joining joining_for_group[ArabicGroupsEnd] = {
- // NonJoining
- JNone, // ArabicNone
- JNone, // ArabicSpace
- // Transparent
- JTransparent, // Transparent
- // Causing
- JCausing, // Center
- JCausing, // Kashida
- // Dual
- JDual, // Beh
- JDual, // Noon
- JDual, // Yeh
- JDual, // Hah
- JDual, // Seen
- JDual, // Tah
- JDual, // Ain
- // Right
- JRight, // Alef
- JRight, // Waw
- JRight, // Dal
- JRight, // Reh
- JRight // HamzaOnHehGoal
-};
-
-
-struct JoiningPair {
- QArabicShape form1;
- QArabicShape form2;
-};
-
-static const JoiningPair joining_table[5][4] =
-// None, Causing, Dual, Right
-{
- { { XIsolated, XIsolated }, { XIsolated, XCausing }, { XIsolated, XInitial }, { XIsolated, XIsolated } }, // XIsolated
- { { XFinal, XIsolated }, { XFinal, XCausing }, { XFinal, XInitial }, { XFinal, XIsolated } }, // XFinal
- { { XIsolated, XIsolated }, { XInitial, XCausing }, { XInitial, XMedial }, { XInitial, XFinal } }, // XInitial
- { { XFinal, XIsolated }, { XMedial, XCausing }, { XMedial, XMedial }, { XMedial, XFinal } }, // XMedial
- { { XIsolated, XIsolated }, { XIsolated, XCausing }, { XIsolated, XMedial }, { XIsolated, XFinal } }, // XCausing
-};
-
-
-/*
-According to http://www.microsoft.com/middleeast/Arabicdev/IE6/KBase.asp
-
-1. Find the priority of the connecting opportunities in each word
-2. Add expansion at the highest priority connection opportunity
-3. If more than one connection opportunity have the same highest value,
- use the opportunity closest to the end of the word.
-
-Following is a chart that provides the priority for connection
-opportunities and where expansion occurs. The character group names
-are those in table 6.6 of the UNICODE 2.0 book.
-
-
-PrioritY Glyph Condition Kashida Location
-
-Arabic_Kashida User inserted Kashida The user entered a Kashida in a position. After the user
- (Shift+j or Shift+[E with hat]) Thus, it is the highest priority to insert an inserted kashida
- automatic kashida.
-
-Arabic_Seen Seen, Sad Connecting to the next character. After the character.
- (Initial or medial form).
-
-Arabic_HaaDal Teh Marbutah, Haa, Dal Connecting to previous character. Before the final form
- of these characters.
-
-Arabic_Alef Alef, Tah, Lam, Connecting to previous character. Before the final form
- Kaf and Gaf of these characters.
-
-Arabic_BaRa Reh, Yeh Connected to medial Beh Before preceding medial Baa
-
-Arabic_Waw Waw, Ain, Qaf, Feh Connecting to previous character. Before the final form of
- these characters.
-
-Arabic_Normal Other connecting Connecting to previous character. Before the final form
- characters of these characters.
-
-
-
-This seems to imply that we have at most one kashida point per arabic word.
-
-*/
-
-void qt_getArabicProperties(const unsigned short *chars, int len, QArabicProperties *properties)
-{
-// qDebug("arabicSyriacOpenTypeShape: properties:");
- int lastPos = 0;
- int lastGroup = ArabicNone;
-
- ArabicGroup group = arabicGroup(chars[0]);
- Joining j = joining_for_group[group];
- QArabicShape shape = joining_table[XIsolated][j].form2;
- properties[0].justification = HB_NoJustification;
-
- for (int i = 1; i < len; ++i) {
- // #### fix handling for spaces and punktuation
- properties[i].justification = HB_NoJustification;
-
- group = arabicGroup(chars[i]);
- j = joining_for_group[group];
-
- if (j == JTransparent) {
- properties[i].shape = XIsolated;
- continue;
- }
-
- properties[lastPos].shape = joining_table[shape][j].form1;
- shape = joining_table[shape][j].form2;
-
- switch(lastGroup) {
- case Seen:
- if (properties[lastPos].shape == XInitial || properties[lastPos].shape == XMedial)
- properties[i-1].justification = HB_Arabic_Seen;
- break;
- case Hah:
- if (properties[lastPos].shape == XFinal)
- properties[lastPos-1].justification = HB_Arabic_HaaDal;
- break;
- case Alef:
- if (properties[lastPos].shape == XFinal)
- properties[lastPos-1].justification = HB_Arabic_Alef;
- break;
- case Ain:
- if (properties[lastPos].shape == XFinal)
- properties[lastPos-1].justification = HB_Arabic_Waw;
- break;
- case Noon:
- if (properties[lastPos].shape == XFinal)
- properties[lastPos-1].justification = HB_Arabic_Normal;
- break;
- case ArabicNone:
- break;
-
- default:
- Q_ASSERT(false);
- }
-
- lastGroup = ArabicNone;
-
- switch(group) {
- case ArabicNone:
- case Transparent:
- // ### Center should probably be treated as transparent when it comes to justification.
- case Center:
- break;
- case ArabicSpace:
- properties[i].justification = HB_Arabic_Space;
- break;
- case Kashida:
- properties[i].justification = HB_Arabic_Kashida;
- break;
- case Seen:
- lastGroup = Seen;
- break;
-
- case Hah:
- case Dal:
- lastGroup = Hah;
- break;
-
- case Alef:
- case Tah:
- lastGroup = Alef;
- break;
-
- case Yeh:
- case Reh:
- if (properties[lastPos].shape == XMedial && arabicGroup(chars[lastPos]) == Beh)
- properties[lastPos-1].justification = HB_Arabic_BaRa;
- break;
-
- case Ain:
- case Waw:
- lastGroup = Ain;
- break;
-
- case Noon:
- case Beh:
- case HamzaOnHehGoal:
- lastGroup = Noon;
- break;
- case ArabicGroupsEnd:
- Q_ASSERT(false);
- }
-
- lastPos = i;
- }
- properties[lastPos].shape = joining_table[shape][JNone].form1;
-
-
-// for (int i = 0; i < len; ++i)
-// qDebug("arabic properties(%d): uc=%x shape=%d, justification=%d", i, chars[i], properties[i].shape, properties[i].justification);
-}
-
-void QTextEngine::shapeTextMac(int item) const
-{
- QScriptItem &si = layoutData->items[item];
-
- si.glyph_data_offset = layoutData->used;
-
- QFontEngine *font = fontEngine(si, &si.ascent, &si.descent, &si.leading);
- if (font->type() != QFontEngine::Multi) {
- shapeTextWithHarfbuzz(item);
- return;
- }
-
-#ifndef QT_MAC_USE_COCOA
- QFontEngineMacMulti *fe = static_cast<QFontEngineMacMulti *>(font);
-#else
- QCoreTextFontEngineMulti *fe = static_cast<QCoreTextFontEngineMulti *>(font);
-#endif
- QTextEngine::ShaperFlags flags;
- if (si.analysis.bidiLevel % 2)
- flags |= RightToLeft;
- if (option.useDesignMetrics())
- flags |= DesignMetrics;
-
- attributes(); // pre-initialize char attributes
-
- const int len = length(item);
- int num_glyphs = length(item);
- const QChar *str = layoutData->string.unicode() + si.position;
- ushort upperCased[256];
- if (si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase
- || si.analysis.flags == QScriptAnalysis::Lowercase) {
- ushort *uc = upperCased;
- if (len > 256)
- uc = new ushort[len];
- for (int i = 0; i < len; ++i) {
- if(si.analysis.flags == QScriptAnalysis::Lowercase)
- uc[i] = str[i].toLower().unicode();
- else
- uc[i] = str[i].toUpper().unicode();
- }
- str = reinterpret_cast<const QChar *>(uc);
- }
-
- ensureSpace(num_glyphs);
- num_glyphs = layoutData->glyphLayout.numGlyphs - layoutData->used;
-
- QGlyphLayout g = availableGlyphs(&si);
- g.numGlyphs = num_glyphs;
- unsigned short *log_clusters = logClusters(&si);
-
- bool stringToCMapFailed = false;
- if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes(), &si)) {
- ensureSpace(num_glyphs);
- g = availableGlyphs(&si);
- stringToCMapFailed = !fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters,
- attributes(), &si);
- }
-
- if (!stringToCMapFailed) {
- heuristicSetGlyphAttributes(str, len, &g, log_clusters, num_glyphs);
-
- si.num_glyphs = num_glyphs;
-
- layoutData->used += si.num_glyphs;
-
- QGlyphLayout g = shapedGlyphs(&si);
-
- if (si.analysis.script == QUnicodeTables::Arabic) {
- QVarLengthArray<QArabicProperties> props(len + 2);
- QArabicProperties *properties = props.data();
- int f = si.position;
- int l = len;
- if (f > 0) {
- --f;
- ++l;
- ++properties;
- }
- if (f + l < layoutData->string.length()) {
- ++l;
- }
- qt_getArabicProperties((const unsigned short *)(layoutData->string.unicode()+f), l, props.data());
-
- unsigned short *log_clusters = logClusters(&si);
-
- for (int i = 0; i < len; ++i) {
- int gpos = log_clusters[i];
- g.attributes[gpos].justification = properties[i].justification;
- }
- }
- }
-
- const ushort *uc = reinterpret_cast<const ushort *>(str);
-
- if ((si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase
- || si.analysis.flags == QScriptAnalysis::Lowercase)
- && uc != upperCased)
- delete [] uc;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index 6e82de8f5c..325623fc63 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -93,7 +93,7 @@ class QAbstractTextDocumentLayout;
// * negative yoff means the following stuff is drawn higher up.
// the characters bounding rect is given by QRect(x,y,width,height), its advance by
// xoo and yoff
-struct glyph_metrics_t
+struct Q_GUI_EXPORT glyph_metrics_t
{
inline glyph_metrics_t()
: x(100000), y(100000) {}
@@ -426,7 +426,7 @@ public:
InLayout,
LayoutFailed,
};
- struct LayoutData {
+ struct Q_GUI_EXPORT LayoutData {
LayoutData(const QString &str, void **stack_memory, int mem_size);
LayoutData();
~LayoutData();
@@ -650,7 +650,7 @@ private:
int getClusterLength(unsigned short *logClusters, const HB_CharAttributes *attributes, int from, int to, int glyph_pos, int *start);
};
-class QStackTextEngine : public QTextEngine {
+class Q_GUI_EXPORT QStackTextEngine : public QTextEngine {
public:
enum { MemSize = 256*40/sizeof(void *) };
QStackTextEngine(const QString &string, const QFont &f);
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index 5b60dfaf69..41dc1130ee 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -43,10 +43,10 @@
#include <qbytearray.h>
#include <qtextcodec.h>
-#include <qapplication.h>
#include <qstack.h>
#include <qdebug.h>
#include <qthread.h>
+#include <qcoreapplication.h>
#include "qtextdocument.h"
#include "qtextformat_p.h"
@@ -1055,7 +1055,7 @@ void QTextHtmlParserNode::initializeProperties(const QTextHtmlParserNode *parent
&& !attributes.at(i + 1).isEmpty()) {
hasHref = true;
charFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
- charFormat.setForeground(QApplication::palette().link());
+ charFormat.setForeground(Qt::blue); // ### Qt5: QApplication::palette().link());
}
}
@@ -1406,7 +1406,7 @@ void QTextHtmlParserNode::applyBackgroundImage(const QString &url, const QTextDo
if (!url.isEmpty() && resourceProvider) {
QVariant val = resourceProvider->resource(QTextDocument::ImageResource, url);
- if (qApp->thread() != QThread::currentThread()) {
+ if (QCoreApplication::instance()->thread() != QThread::currentThread()) {
// must use images in non-GUI threads
if (val.type() == QVariant::Image) {
QImage image = qvariant_cast<QImage>(val);
diff --git a/src/gui/text/qtextimagehandler.cpp b/src/gui/text/qtextimagehandler.cpp
index 78761184df..fcc13a58ff 100644
--- a/src/gui/text/qtextimagehandler.cpp
+++ b/src/gui/text/qtextimagehandler.cpp
@@ -42,13 +42,12 @@
#include "qtextimagehandler_p.h"
-#include <qapplication.h>
+#include <qcoreapplication.h>
#include <qtextformat.h>
#include <qpainter.h>
#include <qdebug.h>
#include <private/qtextengine_p.h>
#include <qpalette.h>
-#include <qtextbrowser.h>
#include <qthread.h>
QT_BEGIN_NAMESPACE
@@ -73,7 +72,8 @@ static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format)
if (pm.isNull()) {
QString context;
-#ifndef QT_NO_TEXTBROWSER
+#if 0
+ // ### Qt5
QTextBrowser *browser = qobject_cast<QTextBrowser *>(doc->parent());
if (browser)
context = browser->source().toString();
@@ -150,7 +150,9 @@ static QImage getImage(QTextDocument *doc, const QTextImageFormat &format)
if (image.isNull()) {
QString context;
-#ifndef QT_NO_TEXTBROWSER
+
+#if 0
+ // ### Qt5
QTextBrowser *browser = qobject_cast<QTextBrowser *>(doc->parent());
if (browser)
context = browser->source().toString();
@@ -210,7 +212,7 @@ QSizeF QTextImageHandler::intrinsicSize(QTextDocument *doc, int posInDocument, c
Q_UNUSED(posInDocument)
const QTextImageFormat imageFormat = format.toImageFormat();
- if (qApp->thread() != QThread::currentThread())
+ if (QCoreApplication::instance()->thread() != QThread::currentThread())
return getImageSize(doc, imageFormat);
return getPixmapSize(doc, imageFormat);
}
@@ -220,7 +222,7 @@ void QTextImageHandler::drawObject(QPainter *p, const QRectF &rect, QTextDocumen
Q_UNUSED(posInDocument)
const QTextImageFormat imageFormat = format.toImageFormat();
- if (qApp->thread() != QThread::currentThread()) {
+ if (QCoreApplication::instance()->thread() != QThread::currentThread()) {
const QImage image = getImage(doc, imageFormat);
p->drawImage(rect, image, image.rect());
} else {
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 8c5e63da54..25d7de827e 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -44,14 +44,12 @@
#include <qthread.h>
#include <qfont.h>
-#include <qapplication.h>
#include <qpainter.h>
#include <qvarlengtharray.h>
#include <qtextformat.h>
#include <qabstracttextdocumentlayout.h>
#include "qtextdocument_p.h"
#include "qtextformat_p.h"
-#include "qstyleoption.h"
#include "qpainterpath.h"
#include "qglyphrun.h"
#include "qglyphrun_p.h"
diff --git a/src/gui/text/qtextoption.cpp b/src/gui/text/qtextoption.cpp
index d384cbeaee..fe58583d04 100644
--- a/src/gui/text/qtextoption.cpp
+++ b/src/gui/text/qtextoption.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
#include "qtextoption.h"
-#include "qapplication.h"
+#include "qguiapplication.h"
#include "qlist.h"
QT_BEGIN_NAMESPACE
@@ -82,7 +82,7 @@ QTextOption::QTextOption(Qt::Alignment alignment)
tab(-1),
d(0)
{
- direction = QApplication::layoutDirection();
+ direction = QGuiApplication::layoutDirection();
}
/*!
diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri
index eb5937a493..5e5f8e31c8 100644
--- a/src/gui/text/text.pri
+++ b/src/gui/text/text.pri
@@ -9,9 +9,8 @@ HEADERS += \
text/qfontmetrics.h \
text/qfont_p.h \
text/qfontsubset_p.h \
- text/qtextcontrol_p.h \
- text/qtextcontrol_p_p.h \
- text/qtextengine_p.h \
+ text/qlinecontrol_p.h \
+ text/qtextengine_p.h \
text/qtextlayout.h \
text/qtextformat.h \
text/qtextformat_p.h \
@@ -24,7 +23,9 @@ HEADERS += \
text/qtexthtmlparser_p.h \
text/qabstracttextdocumentlayout.h \
text/qtextdocumentlayout_p.h \
- text/qtextcursor.h \
+ text/qtextcontrol_p.h \
+ text/qtextcontrol_p_p.h \
+ text/qtextcursor.h \
text/qtextcursor_p.h \
text/qtextdocumentfragment.h \
text/qtextdocumentfragment_p.h \
@@ -52,8 +53,9 @@ SOURCES += \
text/qfontsubset.cpp \
text/qfontmetrics.cpp \
text/qfontdatabase.cpp \
- text/qtextcontrol.cpp \
- text/qtextengine.cpp \
+ text/qlinecontrol.cpp \
+ text/qtextcontrol.cpp \
+ text/qtextengine.cpp \
text/qtextlayout.cpp \
text/qtextformat.cpp \
text/qtextobject.cpp \
@@ -78,7 +80,7 @@ SOURCES += \
text/qrawfont.cpp \
text/qglyphrun.cpp
-win32 {
+win32:!qpa {
SOURCES += \
text/qfont_win.cpp \
text/qfontengine_win.cpp \
@@ -104,7 +106,7 @@ unix:x11 {
text/qrawfont_ft.cpp
}
-!embedded:!qpa:!x11:mac {
+!qpa:!x11:mac {
HEADERS += \
text/qfontengine_mac_p.h
OBJECTIVE_HEADERS += \
@@ -120,22 +122,6 @@ unix:x11 {
}
}
-embedded {
- SOURCES += \
- text/qfont_qws.cpp \
- text/qfontengine_qws.cpp \
- text/qfontengine_ft.cpp \
- text/qfontengine_qpf.cpp \
- text/qabstractfontengine_qws.cpp \
- text/qrawfont_ft.cpp
- HEADERS += \
- text/qfontengine_ft_p.h \
- text/qfontengine_qpf_p.h \
- text/qabstractfontengine_qws.h \
- text/qabstractfontengine_p.h
- DEFINES += QT_NO_FONTCONFIG
-}
-
qpa {
SOURCES += \
text/qfont_qpa.cpp \
@@ -233,9 +219,7 @@ contains(QT_CONFIG, freetype) {
DEFINES += FT2_BUILD_LIBRARY FT_CONFIG_OPTION_SYSTEM_ZLIB
- embedded:CONFIG += opentype
} else:contains(QT_CONFIG, system-freetype) {
- embedded:CONFIG += opentype
# pull in the proper freetype2 include directory
include($$QT_SOURCE_TREE/config.tests/unix/freetype/freetype.pri)
LIBS_PRIVATE += -lfreetype