summaryrefslogtreecommitdiffstats
path: root/src/gui/text
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/text')
-rw-r--r--src/gui/text/qabstracttextdocumentlayout.cpp20
-rw-r--r--src/gui/text/qfont.cpp103
-rw-r--r--src/gui/text/qfont_p.h5
-rw-r--r--src/gui/text/qfontdatabase.cpp2
-rw-r--r--src/gui/text/qfontengine_ft.cpp2
-rw-r--r--src/gui/text/qfontengine_p.h2
-rw-r--r--src/gui/text/qfontengine_qpa.cpp85
-rw-r--r--src/gui/text/qfontengine_qpa_p.h5
-rw-r--r--src/gui/text/qfontmetrics.cpp78
-rw-r--r--src/gui/text/qrawfont.cpp6
-rw-r--r--src/gui/text/qrawfont.h1
-rw-r--r--src/gui/text/qtextcursor.cpp10
-rw-r--r--src/gui/text/qtextdocument.cpp14
-rw-r--r--src/gui/text/qtextdocumentwriter.cpp8
-rw-r--r--src/gui/text/qtextengine.cpp175
-rw-r--r--src/gui/text/qtextengine_p.h8
-rw-r--r--src/gui/text/qtextlayout.cpp44
-rw-r--r--src/gui/text/qtextlayout.h7
-rw-r--r--src/gui/text/qtextlist.cpp2
-rw-r--r--src/gui/text/qtexttable.cpp12
20 files changed, 391 insertions, 198 deletions
diff --git a/src/gui/text/qabstracttextdocumentlayout.cpp b/src/gui/text/qabstracttextdocumentlayout.cpp
index 86de48b1dc..589c0f701f 100644
--- a/src/gui/text/qabstracttextdocumentlayout.cpp
+++ b/src/gui/text/qabstracttextdocumentlayout.cpp
@@ -100,14 +100,14 @@ QT_BEGIN_NAMESPACE
custom text object into a document:
\list
- \o Choose an \a objectType. The \a objectType is an integer with a
+ \li Choose an \a objectType. The \a objectType is an integer with a
value greater or equal to QTextFormat::UserObject.
- \o Create a QTextCharFormat object and set the object type to the
+ \li Create a QTextCharFormat object and set the object type to the
chosen type using the setObjectType() function.
- \o Implement the QTextObjectInterface class.
- \o Call QAbstractTextDocumentLayout::registerHandler() with an instance of your
+ \li Implement the QTextObjectInterface class.
+ \li Call QAbstractTextDocumentLayout::registerHandler() with an instance of your
QTextObjectInterface subclass to register your object type.
- \o Insert QChar::ObjectReplacementCharacter with the aforementioned
+ \li Insert QChar::ObjectReplacementCharacter with the aforementioned
QTextCharFormat of the chosen object type into the document.
As mentioned, the functions of QTextObjectInterface
\l{QTextObjectInterface::}{intrinsicSize()} and
@@ -269,17 +269,17 @@ QT_BEGIN_NAMESPACE
implementation of this function would have to do the following:
\list
- \o Determine the list of changed \l{QTextBlock}(s) using the parameters
+ \li Determine the list of changed \l{QTextBlock}(s) using the parameters
provided.
- \o Each QTextBlock object's corresponding QTextLayout object needs to
+ \li Each QTextBlock object's corresponding QTextLayout object needs to
be processed. You can access the \l{QTextBlock}'s layout using the
QTextBlock::layout() function. This processing should take the
document's page size into consideration.
- \o If the total number of pages changed, the pageCountChanged() signal
+ \li If the total number of pages changed, the pageCountChanged() signal
should be emitted.
- \o If the total size changed, the documentSizeChanged() signal should
+ \li If the total size changed, the documentSizeChanged() signal should
be emitted.
- \o The update() signal should be emitted to schedule a repaint of areas
+ \li The update() signal should be emitted to schedule a repaint of areas
in the layout that require repainting.
\endlist
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index ee833a06cf..c68452d55a 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -419,14 +419,14 @@ QFontEngineData::~QFontEngineData()
\target fontmatching
The font matching algorithm works as follows:
\list 1
- \o The specified font family is searched for.
- \o If not found, the styleHint() is used to select a replacement
+ \li The specified font family is searched for.
+ \li If not found, the styleHint() is used to select a replacement
family.
- \o Each replacement font family is searched for.
- \o If none of these are found or there was no styleHint(), "helvetica"
+ \li Each replacement font family is searched for.
+ \li If none of these are found or there was no styleHint(), "helvetica"
will be searched for.
- \o If "helvetica" isn't found Qt will try the lastResortFamily().
- \o If the lastResortFamily() isn't found Qt will try the
+ \li If "helvetica" isn't found Qt will try the lastResortFamily().
+ \li If the lastResortFamily() isn't found Qt will try the
lastResortFont() which will always return a name of some kind.
\endlist
@@ -440,10 +440,10 @@ QFontEngineData::~QFontEngineData()
Once a font is found, the remaining attributes are matched in order of
priority:
\list 1
- \o fixedPitch()
- \o pointSize() (see below)
- \o weight()
- \o style()
+ \li fixedPitch()
+ \li pointSize() (see below)
+ \li weight()
+ \li style()
\endlist
If you have a font which matches on family, even if none of the
@@ -861,35 +861,35 @@ int QFont::pointSize() const
\table
\header
- \o
- \o PreferDefaultHinting
- \o PreferNoHinting
- \o PreferVerticalHinting
- \o PreferFullHinting
+ \li
+ \li PreferDefaultHinting
+ \li PreferNoHinting
+ \li PreferVerticalHinting
+ \li PreferFullHinting
\row
- \o Windows Vista (w/o Platform Update) and earlier
- \o Full hinting
- \o Full hinting
- \o Full hinting
- \o Full hinting
+ \li Windows Vista (w/o Platform Update) and earlier
+ \li Full hinting
+ \li Full hinting
+ \li Full hinting
+ \li Full hinting
\row
- \o Windows 7 and Windows Vista (w/Platform Update) and DirectWrite enabled in Qt
- \o Full hinting
- \o Vertical hinting
- \o Vertical hinting
- \o Full hinting
+ \li Windows 7 and Windows Vista (w/Platform Update) and DirectWrite enabled in Qt
+ \li Full hinting
+ \li Vertical hinting
+ \li Vertical hinting
+ \li Full hinting
\row
- \o FreeType
- \o Operating System setting
- \o No hinting
- \o Vertical hinting (light)
- \o Full hinting
+ \li FreeType
+ \li Operating System setting
+ \li No hinting
+ \li Vertical hinting (light)
+ \li Full hinting
\row
- \o Cocoa on Mac OS X
- \o No hinting
- \o No hinting
- \o No hinting
- \o No hinting
+ \li Cocoa on Mac OS X
+ \li No hinting
+ \li No hinting
+ \li No hinting
+ \li No hinting
\endtable
\note Please be aware that altering the hinting preference on Windows is available through
@@ -2277,7 +2277,7 @@ QDataStream &operator>>(QDataStream &s, QFont &font)
There are three ways to create a QFontInfo object.
\list 1
- \o Calling the QFontInfo constructor with a QFont creates a font
+ \li Calling the QFontInfo constructor with a QFont creates a font
info object for a screen-compatible font, i.e. the font cannot be
a printer font. If the font is changed later, the font
info object is \e not updated.
@@ -2286,12 +2286,12 @@ QDataStream &operator>>(QDataStream &s, QFont &font)
inaccurate. Printer fonts are not always accessible so the nearest
screen font is used if a printer font is supplied.)
- \o QWidget::fontInfo() returns the font info for a widget's font.
+ \li QWidget::fontInfo() returns the font info for a widget's font.
This is equivalent to calling QFontInfo(widget->font()). If the
widget's font is changed later, the font info object is \e not
updated.
- \o QPainter::fontInfo() returns the font info for a painter's
+ \li QPainter::fontInfo() returns the font info for a painter's
current font. If the painter's font is changed later, the font
info object is \e not updated.
\endlist
@@ -2715,18 +2715,22 @@ QFontEngine *QFontCache::findEngine(const Key &key)
EngineCache::Iterator it = engineCache.find(key),
end = engineCache.end();
if (it == end) return 0;
-
// found... update the hitcount and timestamp
- it.value().hits++;
- it.value().timestamp = ++current_timestamp;
+ updateHitCountAndTimeStamp(it.value());
+
+ return it.value().data;
+}
+
+void QFontCache::updateHitCountAndTimeStamp(Engine &value)
+{
+ value.hits++;
+ value.timestamp = ++current_timestamp;
FC_DEBUG("QFontCache: found font engine\n"
" %p: timestamp %4u hits %3u ref %2d/%2d, type '%s'",
- it.value().data, it.value().timestamp, it.value().hits,
- it.value().data->ref.load(), it.value().data->cache_count,
- it.value().data->name());
-
- return it.value().data;
+ value.data, value.timestamp, value.hits,
+ value.data->ref.load(), value.data->cache_count,
+ value.data->name());
}
void QFontCache::removeEngine(QFontEngine *engine)
@@ -2743,14 +2747,17 @@ void QFontCache::removeEngine(QFontEngine *engine)
}
}
-void QFontCache::insertEngine(const Key &key, QFontEngine *engine)
+void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMulti)
{
FC_DEBUG("QFontCache: inserting new engine %p", engine);
Engine data(engine);
data.timestamp = ++current_timestamp;
- engineCache.insert(key, data);
+ if (insertMulti)
+ engineCache.insertMulti(key, data);
+ else
+ engineCache.insert(key, data);
// only increase the cost if this is the first time we insert the engine
if (engine->cache_count == 0)
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index d10249201a..06cf787880 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -242,9 +242,10 @@ public:
EngineCache engineCache;
QFontEngine *findEngine(const Key &key);
- void insertEngine(const Key &key, QFontEngine *engine);
- void removeEngine(QFontEngine *engine);
+ void updateHitCountAndTimeStamp(Engine &value);
+ void insertEngine(const Key &key, QFontEngine *engine, bool insertMulti = false);
+ void removeEngine(QFontEngine *engine);
private:
void increaseCost(uint cost);
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 7fa486e1ee..468d029cf2 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -2244,7 +2244,7 @@ int QFontDatabase::addApplicationFont(const QString &fileName)
Currently only TrueType fonts and TrueType font collections are supported.
- \bold{Note:} Adding application fonts on Unix/X11 platforms without fontconfig is
+ \b{Note:} Adding application fonts on Unix/X11 platforms without fontconfig is
currently not supported.
\sa addApplicationFont(), applicationFontFamilies(), removeApplicationFont()
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 14e2dba364..8880eb7cb3 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -877,7 +877,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
if (err != FT_Err_Ok)
qWarning("load glyph failed err=%x face=%p, glyph=%d", err, face, glyph);
- if (!set || set->outline_drawing || fetchMetricsOnly)
+ if ((!set || set->outline_drawing) && fetchMetricsOnly)
return 0;
FT_GlyphSlot slot = face->glyph;
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index cf9c26f2a4..44464ee788 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -85,6 +85,7 @@ struct QGlyphLayout;
class Q_GUI_EXPORT QFontEngine : public QObject
{
+ Q_OBJECT
public:
enum Type {
Box,
@@ -343,6 +344,7 @@ private:
class Q_GUI_EXPORT QFontEngineMulti : public QFontEngine
{
+ Q_OBJECT
public:
explicit QFontEngineMulti(int engineCount);
~QFontEngineMulti();
diff --git a/src/gui/text/qfontengine_qpa.cpp b/src/gui/text/qfontengine_qpa.cpp
index 33657367fa..48679824a4 100644
--- a/src/gui/text/qfontengine_qpa.cpp
+++ b/src/gui/text/qfontengine_qpa.cpp
@@ -46,8 +46,10 @@
#include <QtCore/QDir>
#include <QtCore/QBuffer>
-#include <QtGui/QPlatformFontDatabase>
#include <QtGui/private/qpaintengine_raster_p.h>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/QPlatformFontDatabase>
+#include <QtGui/QPlatformIntegration>
QT_BEGIN_NAMESPACE
@@ -662,6 +664,20 @@ void QPAGenerator::writeTaggedQFixed(QFontEngineQPA::HeaderTag tag, QFixed value
QFontEngineMultiQPA::QFontEngineMultiQPA(QFontEngine *fe, int _script, const QStringList &fallbacks)
: QFontEngineMulti(fallbacks.size() + 1),
fallbackFamilies(fallbacks), script(_script)
+ , fallbacksQueried(true)
+{
+ init(fe);
+}
+
+QFontEngineMultiQPA::QFontEngineMultiQPA(QFontEngine *fe, int _script)
+ : QFontEngineMulti(2)
+ , script(_script)
+ , fallbacksQueried(false)
+{
+ init(fe);
+}
+
+void QFontEngineMultiQPA::init(QFontEngine *fe)
{
Q_ASSERT(fe && fe->type() != QFontEngine::Multi);
engines[0] = fe;
@@ -672,18 +688,73 @@ QFontEngineMultiQPA::QFontEngineMultiQPA(QFontEngine *fe, int _script, const QSt
void QFontEngineMultiQPA::loadEngine(int at)
{
+ bool canLoadFallbackEngine = true;
+ if (!fallbacksQueried) {
+ // Original FontEngine to restore after the fill.
+ QFontEngine *fe = engines[0];
+ fallbackFamilies = QGuiApplicationPrivate::instance()->platformIntegration()->fontDatabase()->fallbacksForFamily(fe->fontDef.family, QFont::Style(fe->fontDef.style)
+ , QFont::AnyStyle, QUnicodeTables::Script(script));
+ if (fallbackFamilies.size() > 1) {
+ engines.fill(0, fallbackFamilies.size() + 1);
+ engines[0] = fe;
+ } else {
+ // Turns out we lied about having any fallback at all.
+ canLoadFallbackEngine = false;
+ engines[1] = fe;
+ }
+ fallbacksQueried = true;
+ }
Q_ASSERT(at < engines.size());
Q_ASSERT(engines.at(at) == 0);
-
QFontDef request = fontDef;
- request.styleStrategy |= QFont::NoFontMerging;
- request.family = fallbackFamilies.at(at-1);
- engines[at] = QFontDatabase::findFont(script,
- /*fontprivate*/0,
- request, false);
+ if (canLoadFallbackEngine) {
+ request.styleStrategy |= QFont::NoFontMerging;
+ request.family = fallbackFamilies.at(at-1);
+ engines[at] = QFontDatabase::findFont(script,
+ /*fontprivate = */0,
+ request, /*multi = */false);
+ }
Q_ASSERT(engines[at]);
engines[at]->ref.ref();
engines[at]->fontDef = request;
}
+/*
+ This is used indirectly by QtWebKit when using QTextLayout::setRawFont
+
+ The purpose of this is to provide the necessary font fallbacks when drawing complex
+ text. Since QtWebKit ends up repeatedly creating QTextLayout instances and passing them
+ the same raw font over and over again, we want to cache the corresponding multi font engine
+ as it may contain fallback font engines already.
+*/
+QFontEngine* QFontEngineMultiQPA::createMultiFontEngine(QFontEngine *fe, int script)
+{
+ QFontEngine *engine = 0;
+ QFontCache::Key key(fe->fontDef, script, /*multi = */true);
+ QFontCache *fc = QFontCache::instance();
+ // We can't rely on the fontDef (and hence the cache Key)
+ // alone to distinguish webfonts, since these should not be
+ // accidentally shared, even if the resulting fontcache key
+ // is strictly identical. See:
+ // http://www.w3.org/TR/css3-fonts/#font-face-rule
+ const bool faceIsLocal = !fe->faceId().filename.isEmpty();
+ QFontCache::EngineCache::Iterator it = fc->engineCache.find(key),
+ end = fc->engineCache.end();
+ while (it != end && it.key() == key) {
+ QFontEngineMulti *cachedEngine = qobject_cast<QFontEngineMulti *>(it.value().data);
+ if (faceIsLocal || (cachedEngine && fe == cachedEngine->engine(0))) {
+ engine = cachedEngine;
+ fc->updateHitCountAndTimeStamp(it.value());
+ break;
+ }
+ it++;
+ }
+ if (!engine) {
+ engine = new QFontEngineMultiQPA(fe, script);
+ QFontCache::instance()->insertEngine(key, engine, /* insertMulti */ !faceIsLocal);
+ }
+ Q_ASSERT(engine);
+ return engine;
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/text/qfontengine_qpa_p.h b/src/gui/text/qfontengine_qpa_p.h
index ed2e071ac2..16991ad2ca 100644
--- a/src/gui/text/qfontengine_qpa_p.h
+++ b/src/gui/text/qfontengine_qpa_p.h
@@ -249,13 +249,18 @@ public:
QFontEngineMultiQPA(QFontEngine *fe, int script, const QStringList &fallbacks);
void loadEngine(int at);
+ static QFontEngine* createMultiFontEngine(QFontEngine *fe, int script);
int fallbackFamilyCount() const { return fallbackFamilies.size(); }
QString fallbackFamilyAt(int at) const { return fallbackFamilies.at(at); }
private:
+ QFontEngineMultiQPA(QFontEngine *fe, int script);
+ void init(QFontEngine *fe);
+
QStringList fallbackFamilies;
int script;
+ bool fallbacksQueried;
};
QT_END_NAMESPACE
diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp
index 283494e316..7209fbdfc3 100644
--- a/src/gui/text/qfontmetrics.cpp
+++ b/src/gui/text/qfontmetrics.cpp
@@ -76,7 +76,7 @@ extern void qt_format_text(const QFont& font, const QRectF &_r,
QFontMetrics object:
\list 1
- \o Calling the QFontMetrics constructor with a QFont creates a
+ \li Calling the QFontMetrics constructor with a QFont creates a
font metrics object for a screen-compatible font, i.e. the font
cannot be a printer font. If the font is changed
later, the font metrics object is \e not updated.
@@ -85,12 +85,12 @@ extern void qt_format_text(const QFont& font, const QRectF &_r,
inaccurate. Printer fonts are not always accessible so the nearest
screen font is used if a printer font is supplied.)
- \o QWidget::fontMetrics() returns the font metrics for a widget's
+ \li QWidget::fontMetrics() returns the font metrics for a widget's
font. This is equivalent to QFontMetrics(widget->font()). If the
widget's font is changed later, the font metrics object is \e not
updated.
- \o QPainter::fontMetrics() returns the font metrics for a
+ \li QPainter::fontMetrics() returns the font metrics for a
painter's current font. If the painter's font is changed later, the
font metrics object is \e not updated.
\endlist
@@ -713,20 +713,20 @@ QRect QFontMetrics::boundingRect(QChar ch) const
The \a flags argument is the bitwise OR of the following flags:
\list
- \o Qt::AlignLeft aligns to the left border, except for
+ \li Qt::AlignLeft aligns to the left border, except for
Arabic and Hebrew where it aligns to the right.
- \o Qt::AlignRight aligns to the right border, except for
+ \li Qt::AlignRight aligns to the right border, except for
Arabic and Hebrew where it aligns to the left.
- \o Qt::AlignJustify produces justified text.
- \o Qt::AlignHCenter aligns horizontally centered.
- \o Qt::AlignTop aligns to the top border.
- \o Qt::AlignBottom aligns to the bottom border.
- \o Qt::AlignVCenter aligns vertically centered
- \o Qt::AlignCenter (== \c{Qt::AlignHCenter | Qt::AlignVCenter})
- \o Qt::TextSingleLine ignores newline characters in the text.
- \o Qt::TextExpandTabs expands tabs (see below)
- \o Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
- \o Qt::TextWordWrap breaks the text to fit the rectangle.
+ \li Qt::AlignJustify produces justified text.
+ \li Qt::AlignHCenter aligns horizontally centered.
+ \li Qt::AlignTop aligns to the top border.
+ \li Qt::AlignBottom aligns to the bottom border.
+ \li Qt::AlignVCenter aligns vertically centered
+ \li Qt::AlignCenter (== \c{Qt::AlignHCenter | Qt::AlignVCenter})
+ \li Qt::TextSingleLine ignores newline characters in the text.
+ \li Qt::TextExpandTabs expands tabs (see below)
+ \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
+ \li Qt::TextWordWrap breaks the text to fit the rectangle.
\endlist
Qt::Horizontal alignment defaults to Qt::AlignLeft and vertical
@@ -780,10 +780,10 @@ QRect QFontMetrics::boundingRect(const QRect &rect, int flags, const QString &te
The \a flags argument is the bitwise OR of the following flags:
\list
- \o Qt::TextSingleLine ignores newline characters.
- \o Qt::TextExpandTabs expands tabs (see below)
- \o Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
- \o Qt::TextWordBreak breaks the text to fit the rectangle.
+ \li Qt::TextSingleLine ignores newline characters.
+ \li Qt::TextExpandTabs expands tabs (see below)
+ \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
+ \li Qt::TextWordBreak breaks the text to fit the rectangle.
\endlist
If Qt::TextExpandTabs is set in \a flags, then: if \a tabArray is
@@ -1490,20 +1490,20 @@ QRectF QFontMetricsF::boundingRect(QChar ch) const
The \a flags argument is the bitwise OR of the following flags:
\list
- \o Qt::AlignLeft aligns to the left border, except for
+ \li Qt::AlignLeft aligns to the left border, except for
Arabic and Hebrew where it aligns to the right.
- \o Qt::AlignRight aligns to the right border, except for
+ \li Qt::AlignRight aligns to the right border, except for
Arabic and Hebrew where it aligns to the left.
- \o Qt::AlignJustify produces justified text.
- \o Qt::AlignHCenter aligns horizontally centered.
- \o Qt::AlignTop aligns to the top border.
- \o Qt::AlignBottom aligns to the bottom border.
- \o Qt::AlignVCenter aligns vertically centered
- \o Qt::AlignCenter (== \c{Qt::AlignHCenter | Qt::AlignVCenter})
- \o Qt::TextSingleLine ignores newline characters in the text.
- \o Qt::TextExpandTabs expands tabs (see below)
- \o Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
- \o Qt::TextWordWrap breaks the text to fit the rectangle.
+ \li Qt::AlignJustify produces justified text.
+ \li Qt::AlignHCenter aligns horizontally centered.
+ \li Qt::AlignTop aligns to the top border.
+ \li Qt::AlignBottom aligns to the bottom border.
+ \li Qt::AlignVCenter aligns vertically centered
+ \li Qt::AlignCenter (== \c{Qt::AlignHCenter | Qt::AlignVCenter})
+ \li Qt::TextSingleLine ignores newline characters in the text.
+ \li Qt::TextExpandTabs expands tabs (see below)
+ \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
+ \li Qt::TextWordWrap breaks the text to fit the rectangle.
\endlist
Qt::Horizontal alignment defaults to Qt::AlignLeft and vertical
@@ -1517,9 +1517,9 @@ QRectF QFontMetricsF::boundingRect(QChar ch) const
If Qt::TextExpandTabs is set in \a flags, the following behavior is
used to interpret tab characters in the text:
\list
- \o If \a tabArray is non-null, it specifies a 0-terminated sequence of
+ \li If \a tabArray is non-null, it specifies a 0-terminated sequence of
pixel-positions for tabs in the text.
- \o If \a tabStops is non-zero, it is used as the tab spacing (in pixels).
+ \li If \a tabStops is non-zero, it is used as the tab spacing (in pixels).
\endlist
Note that the bounding rectangle may extend to the left of (0, 0),
@@ -1559,10 +1559,10 @@ QRectF QFontMetricsF::boundingRect(const QRectF &rect, int flags, const QString&
The \a flags argument is the bitwise OR of the following flags:
\list
- \o Qt::TextSingleLine ignores newline characters.
- \o Qt::TextExpandTabs expands tabs (see below)
- \o Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
- \o Qt::TextWordBreak breaks the text to fit the rectangle.
+ \li Qt::TextSingleLine ignores newline characters.
+ \li Qt::TextExpandTabs expands tabs (see below)
+ \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
+ \li Qt::TextWordBreak breaks the text to fit the rectangle.
\endlist
These flags are defined in \l{Qt::TextFlags}.
@@ -1570,9 +1570,9 @@ QRectF QFontMetricsF::boundingRect(const QRectF &rect, int flags, const QString&
If Qt::TextExpandTabs is set in \a flags, the following behavior is
used to interpret tab characters in the text:
\list
- \o If \a tabArray is non-null, it specifies a 0-terminated sequence of
+ \li If \a tabArray is non-null, it specifies a 0-terminated sequence of
pixel-positions for tabs in the text.
- \o If \a tabStops is non-zero, it is used as the tab spacing (in pixels).
+ \li If \a tabStops is non-zero, it is used as the tab spacing (in pixels).
\endlist
Newline characters are processed as line breaks.
diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp
index 79793d5845..9fbeef4685 100644
--- a/src/gui/text/qrawfont.cpp
+++ b/src/gui/text/qrawfont.cpp
@@ -86,13 +86,13 @@ QT_BEGIN_NAMESPACE
QRawFont can be constructed in a number of ways:
\list
- \o It can be constructed by calling QTextLayout::glyphs() or QTextFragment::glyphs(). The
+ \li It can be constructed by calling QTextLayout::glyphs() or QTextFragment::glyphs(). The
returned QGlyphs objects will contain QRawFont objects which represent the actual fonts
used to render each portion of the text.
- \o It can be constructed by passing a QFont object to QRawFont::fromFont(). The function
+ \li It can be constructed by passing a QFont object to QRawFont::fromFont(). The function
will return a QRawFont object representing the font that will be selected as response to
the QFont query and the selected writing system.
- \o It can be constructed by passing a file name or QByteArray directly to the QRawFont
+ \li It can be constructed by passing a file name or QByteArray directly to the QRawFont
constructor, or by calling loadFromFile() or loadFromData(). In this case, the
font will not be registered in QFontDatabase, and it will not be available as part of
regular font selection.
diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h
index 5cd996e705..bc5f6621c8 100644
--- a/src/gui/text/qrawfont.h
+++ b/src/gui/text/qrawfont.h
@@ -138,6 +138,7 @@ public:
private:
friend class QRawFontPrivate;
friend class QTextLayout;
+ friend class QTextEngine;
QExplicitlySharedDataPointer<QRawFontPrivate> d;
};
diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp
index cbffc4315f..02fd921fac 100644
--- a/src/gui/text/qtextcursor.cpp
+++ b/src/gui/text/qtextcursor.cpp
@@ -950,15 +950,15 @@ QTextLayout *QTextCursorPrivate::blockLayout(QTextBlock &block) const{
document with the cursor:
\list
- \i Lists are ordered sequences of block elements that are decorated with
+ \li Lists are ordered sequences of block elements that are decorated with
bullet points or symbols. These are inserted in a specified format
with insertList().
- \i Tables are inserted with the insertTable() function, and can be
+ \li Tables are inserted with the insertTable() function, and can be
given an optional format. These contain an array of cells that can
be traversed using the cursor.
- \i Inline images are inserted with insertImage(). The image to be
+ \li Inline images are inserted with insertImage(). The image to be
used can be specified in an image format, or by name.
- \i Frames are inserted by calling insertFrame() with a specified format.
+ \li Frames are inserted by calling insertFrame() with a specified format.
\endlist
Actions can be grouped (i.e. treated as a single action for
@@ -1621,7 +1621,7 @@ void QTextCursor::selectedTableCells(int *firstRow, int *numRows, int *firstColu
/*!
Clears the current selection by setting the anchor to the cursor position.
- Note that it does \bold{not} delete the text of the selection.
+ Note that it does \b{not} delete the text of the selection.
\sa removeSelectedText() hasSelection()
*/
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 1fad064b5c..a8991d5428 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -261,14 +261,14 @@ QTextCodec *Qt::codecForHtml(const QByteArray &ba)
system. The following are the undo/redo operations of a QTextDocument:
\list
- \o Insertion or removal of characters. A sequence of insertions or removals
+ \li Insertion or removal of characters. A sequence of insertions or removals
within the same text block are regarded as a single undo/redo operation.
- \o Insertion or removal of text blocks. Sequences of insertion or removals
+ \li Insertion or removal of text blocks. Sequences of insertion or removals
in a single operation (e.g., by selecting and then deleting text) are
regarded as a single undo/redo operation.
- \o Text character format changes.
- \o Text block format changes.
- \o Text block group format changes.
+ \li Text character format changes.
+ \li Text block format changes.
+ \li Text block group format changes.
\endlist
\sa QTextCursor, QTextEdit, \link richtext.html Rich Text Processing\endlink , {Text Object Example}
@@ -887,7 +887,7 @@ QChar QTextDocument::characterAt(int pos) const
The style sheet needs to be compliant to CSS 2.1 syntax.
- \bold{Note:} Changing the default style sheet does not have any effect to the existing content
+ \b{Note:} Changing the default style sheet does not have any effect to the existing content
of the document.
\sa {Supported HTML Subset}
@@ -1169,7 +1169,7 @@ void QTextDocument::setPlainText(const QString &text)
The HTML formatting is respected as much as possible; for example,
"<b>bold</b> text" will produce text where the first word has a font
- weight that gives it a bold appearance: "\bold{bold} text".
+ weight that gives it a bold appearance: "\b{bold} text".
\note It is the responsibility of the caller to make sure that the
text is correctly decoded when a QString containing HTML is created
diff --git a/src/gui/text/qtextdocumentwriter.cpp b/src/gui/text/qtextdocumentwriter.cpp
index d43a61866d..b0bbeb7a47 100644
--- a/src/gui/text/qtextdocumentwriter.cpp
+++ b/src/gui/text/qtextdocumentwriter.cpp
@@ -345,10 +345,10 @@ QTextCodec *QTextDocumentWriter::codec() const
By default, Qt can write the following formats:
\table
- \header \o Format \o Description
- \row \o plaintext \o Plain text
- \row \o HTML \o HyperText Markup Language
- \row \o ODF \o OpenDocument Format
+ \header \li Format \li Description
+ \row \li plaintext \li Plain text
+ \row \li HTML \li HyperText Markup Language
+ \row \li ODF \li OpenDocument Format
\endtable
\sa setFormat()
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index c63f0fede8..0460db14d5 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -53,13 +53,18 @@
#include "qstring.h"
#include <private/qunicodetables_p.h>
#include "qtextdocument_p.h"
+#include "qrawfont.h"
+#include "qrawfont_p.h"
#include <qguiapplication.h>
#include <qinputmethod.h>
#include <stdlib.h>
+#include "qfontengine_qpa_p.h"
QT_BEGIN_NAMESPACE
+static const float smallCapsFraction = 0.7;
+
namespace {
// Helper class used in QTextEngine::itemize
// keep it out here to allow us to keep supporting various compilers.
@@ -900,13 +905,25 @@ void QTextEngine::shapeText(int item) const
return;
QGlyphLayout glyphs = shapedGlyphs(&si);
- QFont font = this->font(si);
- bool letterSpacingIsAbsolute = font.d->letterSpacingIsAbsolute;
- QFixed letterSpacing = font.d->letterSpacing;
- QFixed wordSpacing = font.d->wordSpacing;
+ bool letterSpacingIsAbsolute;
+ QFixed letterSpacing, wordSpacing;
+#ifndef QT_NO_RAWFONT
+ if (useRawFont) {
+ QTextCharFormat f = format(&si);
+ wordSpacing = QFixed::fromReal(f.fontWordSpacing());
+ letterSpacing = QFixed::fromReal(f.fontLetterSpacing());
+ letterSpacingIsAbsolute = true;
+ } else
+#endif
+ {
+ QFont font = this->font(si);
+ letterSpacingIsAbsolute = font.d->letterSpacingIsAbsolute;
+ letterSpacing = font.d->letterSpacing;
+ wordSpacing = font.d->wordSpacing;
- if (letterSpacingIsAbsolute && letterSpacing.value())
- letterSpacing *= font.d->dpi / qt_defaultDpiY();
+ if (letterSpacingIsAbsolute && letterSpacing.value())
+ letterSpacing *= font.d->dpi / qt_defaultDpiY();
+ }
if (letterSpacing != 0) {
for (int i = 1; i < si.num_glyphs; ++i) {
@@ -973,7 +990,14 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
QFontEngine *font = fontEngine(si, &si.ascent, &si.descent, &si.leading);
- bool kerningEnabled = this->font(si).d->kerning;
+ bool kerningEnabled;
+#ifndef QT_NO_RAWFONT
+ if (useRawFont) {
+ QTextCharFormat f = format(&si);
+ kerningEnabled = f.fontKerning();
+ } else
+#endif
+ kerningEnabled = this->font(si).d->kerning;
HB_ShaperItem entire_shaper_item;
qMemSet(&entire_shaper_item, 0, sizeof(entire_shaper_item));
@@ -1159,6 +1183,9 @@ static void init(QTextEngine *e)
e->underlinePositions = 0;
e->specialData = 0;
e->stackEngine = false;
+#ifndef QT_NO_RAWFONT
+ e->useRawFont = false;
+#endif
}
QTextEngine::QTextEngine()
@@ -1401,7 +1428,21 @@ void QTextEngine::itemize() const
++it;
}
} else {
- itemizer.generate(0, length, static_cast<QFont::Capitalization> (fnt.d->capital));
+#ifndef QT_NO_RAWFONT
+ if (useRawFont && specialData) {
+ int lastIndex = 0;
+ for (int i = 0; i < specialData->addFormats.size(); ++i) {
+ const QTextLayout::FormatRange &range = specialData->addFormats.at(i);
+ if (range.format.fontCapitalization()) {
+ itemizer.generate(lastIndex, range.start - lastIndex, QFont::MixedCase);
+ itemizer.generate(range.start, range.length, range.format.fontCapitalization());
+ lastIndex = range.start + range.length;
+ }
+ }
+ itemizer.generate(lastIndex, length - lastIndex, QFont::MixedCase);
+ } else
+#endif
+ itemizer.generate(0, length, static_cast<QFont::Capitalization> (fnt.d->capital));
}
addRequiredBoundaries();
@@ -1663,59 +1704,85 @@ QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFix
int script = si.analysis.script;
QFont font = fnt;
- if (hasFormats()) {
- if (feCache.prevFontEngine && feCache.prevPosition == si.position && feCache.prevLength == length(&si) && feCache.prevScript == script) {
+#ifndef QT_NO_RAWFONT
+ if (useRawFont && rawFont.isValid()) {
+ if (feCache.prevFontEngine && feCache.prevFontEngine->type() == QFontEngine::Multi && feCache.prevScript == script) {
engine = feCache.prevFontEngine;
- scaledEngine = feCache.prevScaledFontEngine;
} else {
- QTextCharFormat f = format(&si);
- font = f.font();
-
- if (block.docHandle() && block.docHandle()->layout()) {
- // Make sure we get the right dpi on printers
- QPaintDevice *pdev = block.docHandle()->layout()->paintDevice();
- if (pdev)
- font = QFont(font, pdev);
- } else {
- font = font.resolve(fnt);
- }
- engine = font.d->engineForScript(script);
- QTextCharFormat::VerticalAlignment valign = f.verticalAlignment();
- if (valign == QTextCharFormat::AlignSuperScript || valign == QTextCharFormat::AlignSubScript) {
- if (font.pointSize() != -1)
- font.setPointSize((font.pointSize() * 2) / 3);
- else
- font.setPixelSize((font.pixelSize() * 2) / 3);
- scaledEngine = font.d->engineForScript(script);
- }
+ engine = QFontEngineMultiQPA::createMultiFontEngine(rawFont.d->fontEngine, script);
feCache.prevFontEngine = engine;
- if (engine)
- engine->ref.ref();
- feCache.prevScaledFontEngine = scaledEngine;
- if (scaledEngine)
- scaledEngine->ref.ref();
feCache.prevScript = script;
- feCache.prevPosition = si.position;
- feCache.prevLength = length(&si);
+ engine->ref.ref();
+ if (feCache.prevScaledFontEngine)
+ releaseCachedFontEngine(feCache.prevScaledFontEngine);
}
- } else {
- if (feCache.prevFontEngine && feCache.prevScript == script && feCache.prevPosition == -1)
- engine = feCache.prevFontEngine;
- else {
- engine = font.d->engineForScript(script);
- feCache.prevFontEngine = engine;
- if (engine)
- engine->ref.ref();
- feCache.prevScript = script;
- feCache.prevPosition = -1;
- feCache.prevLength = -1;
- feCache.prevScaledFontEngine = 0;
+ if (si.analysis.flags & QFont::SmallCaps) {
+ if (feCache.prevScaledFontEngine) {
+ scaledEngine = feCache.prevScaledFontEngine;
+ } else {
+ QFontEngine *scEngine = rawFont.d->fontEngine->cloneWithSize(smallCapsFraction * rawFont.pixelSize());
+ scaledEngine = QFontEngineMultiQPA::createMultiFontEngine(scEngine, script);
+ scaledEngine->ref.ref();
+ feCache.prevScaledFontEngine = scaledEngine;
+ }
+ }
+ } else
+#endif
+ {
+ if (hasFormats()) {
+ if (feCache.prevFontEngine && feCache.prevPosition == si.position && feCache.prevLength == length(&si) && feCache.prevScript == script) {
+ engine = feCache.prevFontEngine;
+ scaledEngine = feCache.prevScaledFontEngine;
+ } else {
+ QTextCharFormat f = format(&si);
+ font = f.font();
+
+ if (block.docHandle() && block.docHandle()->layout()) {
+ // Make sure we get the right dpi on printers
+ QPaintDevice *pdev = block.docHandle()->layout()->paintDevice();
+ if (pdev)
+ font = QFont(font, pdev);
+ } else {
+ font = font.resolve(fnt);
+ }
+ engine = font.d->engineForScript(script);
+ QTextCharFormat::VerticalAlignment valign = f.verticalAlignment();
+ if (valign == QTextCharFormat::AlignSuperScript || valign == QTextCharFormat::AlignSubScript) {
+ if (font.pointSize() != -1)
+ font.setPointSize((font.pointSize() * 2) / 3);
+ else
+ font.setPixelSize((font.pixelSize() * 2) / 3);
+ scaledEngine = font.d->engineForScript(script);
+ }
+ feCache.prevFontEngine = engine;
+ if (engine)
+ engine->ref.ref();
+ feCache.prevScaledFontEngine = scaledEngine;
+ if (scaledEngine)
+ scaledEngine->ref.ref();
+ feCache.prevScript = script;
+ feCache.prevPosition = si.position;
+ feCache.prevLength = length(&si);
+ }
+ } else {
+ if (feCache.prevFontEngine && feCache.prevScript == script && feCache.prevPosition == -1)
+ engine = feCache.prevFontEngine;
+ else {
+ engine = font.d->engineForScript(script);
+ feCache.prevFontEngine = engine;
+ if (engine)
+ engine->ref.ref();
+ feCache.prevScript = script;
+ feCache.prevPosition = -1;
+ feCache.prevLength = -1;
+ feCache.prevScaledFontEngine = 0;
+ }
}
- }
- if (si.analysis.flags == QScriptAnalysis::SmallCaps) {
- QFontPrivate *p = font.d->smallCapsFontPrivate();
- scaledEngine = p->engineForScript(script);
+ if (si.analysis.flags == QScriptAnalysis::SmallCaps) {
+ QFontPrivate *p = font.d->smallCapsFontPrivate();
+ scaledEngine = p->engineForScript(script);
+ }
}
if (ascent) {
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index b29f626b68..6f1fd713f1 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -581,7 +581,10 @@ public:
mutable FontEngineCache feCache;
QString text;
- QFont fnt;
+ mutable QFont fnt;
+#ifndef QT_NO_RAWFONT
+ QRawFont rawFont;
+#endif
QTextBlock block;
QTextOption option;
@@ -594,6 +597,9 @@ public:
uint stackEngine : 1;
uint forceJustification : 1;
uint visualMovement : 1;
+#ifndef QT_NO_RAWFONT
+ uint useRawFont : 1;
+#endif
int *underlinePositions;
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 943caea644..d5b05a8957 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -361,6 +361,22 @@ QTextLayout::~QTextLayout()
delete d;
}
+#ifndef QT_NO_RAWFONT
+/*!
+ \internal
+ Sets a raw font, to be used with QTextLayout::glyphRuns.
+ Note that this only supports the needs of WebKit.
+ Use of this function with e.g. QTextLayout::draw will result
+ in undefined behaviour.
+*/
+void QTextLayout::setRawFont(const QRawFont &rawFont)
+{
+ d->rawFont = rawFont;
+ d->useRawFont = true;
+ d->resetFontEngineCache();
+}
+#endif
+
/*!
Sets the layout's font to the given \a font. The layout is
invalidated and must be laid out again.
@@ -370,6 +386,9 @@ QTextLayout::~QTextLayout()
void QTextLayout::setFont(const QFont &font)
{
d->fnt = font;
+#ifndef QT_NO_RAWFONT
+ d->useRawFont = false;
+#endif
d->resetFontEngineCache();
}
@@ -2204,15 +2223,17 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
continue;
}
- QFont font = eng->font(si);
-
+ QFont font;
QGlyphRun::GlyphRunFlags flags;
- if (font.overline())
- flags |= QGlyphRun::Overline;
- if (font.underline())
- flags |= QGlyphRun::Underline;
- if (font.strikeOut())
- flags |= QGlyphRun::StrikeOut;
+ if (!eng->useRawFont) {
+ font = eng->font(si);
+ if (font.overline())
+ flags |= QGlyphRun::Overline;
+ if (font.underline())
+ flags |= QGlyphRun::Underline;
+ if (font.strikeOut())
+ flags |= QGlyphRun::StrikeOut;
+ }
bool rtl = false;
if (si.analysis.bidiLevel % 2) {
@@ -2264,7 +2285,8 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
iterator.getSelectionBounds(&x, &width);
if (glyphLayout.numGlyphs > 0) {
- QFontEngine *mainFontEngine = font.d->engineForScript(si.analysis.script);
+ QFontEngine *mainFontEngine = eng->fontEngine(si);
+
if (mainFontEngine->type() == QFontEngine::Multi) {
QFontEngineMulti *multiFontEngine = static_cast<QFontEngineMulti *>(mainFontEngine);
int end = rtl ? glyphLayout.numGlyphs : 0;
@@ -2331,6 +2353,10 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
*/
void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatRange *selection) const
{
+#ifndef QT_NO_RAWFONT
+ // Not intended to work with rawfont
+ Q_ASSERT(!eng->useRawFont);
+#endif
const QScriptLine &line = eng->lines[index];
QPen pen = p->pen();
diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h
index a3bc79dc52..2c38973371 100644
--- a/src/gui/text/qtextlayout.h
+++ b/src/gui/text/qtextlayout.h
@@ -59,6 +59,9 @@ QT_BEGIN_NAMESPACE
class QTextEngine;
class QFont;
+#ifndef QT_NO_RAWFONT
+class QRawFont;
+#endif
class QRect;
class QRegion;
class QTextFormat;
@@ -114,6 +117,10 @@ public:
void setFont(const QFont &f);
QFont font() const;
+#ifndef QT_NO_RAWFONT
+ void setRawFont(const QRawFont &rawFont);
+#endif
+
void setText(const QString& string);
QString text() const;
diff --git a/src/gui/text/qtextlist.cpp b/src/gui/text/qtextlist.cpp
index 5a642e90ef..c3c71bc021 100644
--- a/src/gui/text/qtextlist.cpp
+++ b/src/gui/text/qtextlist.cpp
@@ -107,7 +107,7 @@ public:
Returns true if the list has no items; otherwise returns false.
- \bold{Note:} Empty lists are automatically deleted by the QTextDocument that owns
+ \b{Note:} Empty lists are automatically deleted by the QTextDocument that owns
them.
\sa count()
diff --git a/src/gui/text/qtexttable.cpp b/src/gui/text/qtexttable.cpp
index 12af933fd0..65bc8fde1e 100644
--- a/src/gui/text/qtexttable.cpp
+++ b/src/gui/text/qtexttable.cpp
@@ -541,22 +541,22 @@ void QTextTablePrivate::update() const
\table 80%
\row
- \o \inlineimage texttable-split.png Original Table
- \o Suppose we have a 2x3 table of names and addresses. To merge both
+ \li \inlineimage texttable-split.png Original Table
+ \li Suppose we have a 2x3 table of names and addresses. To merge both
columns in the first row we invoke mergeCells() with \a row = 0,
\a column = 0, \a numRows = 1 and \a numColumns = 2.
\snippet doc/src/snippets/textdocument-texttable/main.cpp 0
\row
- \o \inlineimage texttable-merge.png
- \o This gives us the following table. To split the first row of the table
+ \li \inlineimage texttable-merge.png
+ \li This gives us the following table. To split the first row of the table
back into two cells, we invoke the splitCell() function with \a numRows
and \a numCols = 1.
\snippet doc/src/snippets/textdocument-texttable/main.cpp 1
\row
- \o \inlineimage texttable-split.png Split Table
- \o This results in the original table.
+ \li \inlineimage texttable-split.png Split Table
+ \li This results in the original table.
\endtable
\sa QTextTableFormat