summaryrefslogtreecommitdiffstats
path: root/src/gui/text
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/text')
-rw-r--r--src/gui/text/qtextengine.cpp65
-rw-r--r--src/gui/text/qtextengine_p.h17
-rw-r--r--src/gui/text/qtextlayout.cpp14
3 files changed, 71 insertions, 25 deletions
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 8374c62158..03717dca2f 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1392,6 +1392,7 @@ void QTextEngine::invalidate()
maxWidth = 0;
if (specialData)
specialData->resolvedFormatIndices.clear();
+ feCache.reset();
}
void QTextEngine::clearLineData()
@@ -1783,6 +1784,13 @@ QFont QTextEngine::font(const QScriptItem &si) const
return font;
}
+QTextEngine::FontEngineCache::FontEngineCache()
+{
+ reset();
+}
+
+//we cache the previous results of this function, as calling it numerous times with the same effective
+//input is common (and hard to cache at a higher level)
QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFixed *descent, QFixed *leading) const
{
QFontEngine *engine = 0;
@@ -1791,28 +1799,47 @@ QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFix
QFont font = fnt;
if (hasFormats()) {
- 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);
+ if (feCache.prevFontEngine && feCache.prevPosition == si.position && feCache.prevLength == length(&si) && feCache.prevScript == script) {
+ engine = feCache.prevFontEngine;
+ scaledEngine = feCache.prevScaledFontEngine;
} 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);
+ 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;
+ feCache.prevScaledFontEngine = scaledEngine;
+ feCache.prevScript = script;
+ feCache.prevPosition = si.position;
+ feCache.prevLength = length(&si);
}
} else {
- engine = font.d->engineForScript(script);
+ if (feCache.prevFontEngine && feCache.prevScript == script && feCache.prevPosition == -1)
+ engine = feCache.prevFontEngine;
+ else {
+ engine = font.d->engineForScript(script);
+ feCache.prevFontEngine = engine;
+ feCache.prevScript = script;
+ feCache.prevPosition = -1;
+ feCache.prevLength = -1;
+ feCache.prevScaledFontEngine = 0;
+ }
}
if (si.analysis.flags == QScriptAnalysis::SmallCaps) {
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index 86551a4a86..c920c7ba6e 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -558,6 +558,23 @@ public:
mutable QScriptLineArray lines;
+ struct FontEngineCache {
+ FontEngineCache();
+ mutable QFontEngine *prevFontEngine;
+ mutable QFontEngine *prevScaledFontEngine;
+ mutable int prevScript;
+ mutable int prevPosition;
+ mutable int prevLength;
+ inline void reset() {
+ prevFontEngine = 0;
+ prevScaledFontEngine = 0;
+ prevScript = -1;
+ prevPosition = -1;
+ prevLength = -1;
+ }
+ };
+ mutable FontEngineCache feCache;
+
QString text;
QFont fnt;
QTextBlock block;
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 86c6f48919..183bcea72d 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -386,6 +386,7 @@ QTextLayout::~QTextLayout()
void QTextLayout::setFont(const QFont &font)
{
d->fnt = font;
+ d->feCache.reset();
}
/*!
@@ -518,6 +519,7 @@ void QTextLayout::setAdditionalFormats(const QList<FormatRange> &formatList)
}
if (d->block.docHandle())
d->block.docHandle()->documentChange(d->block.position(), d->block.length());
+ d->feCache.reset();
}
/*!
@@ -1867,14 +1869,14 @@ void QTextLine::layout_helper(int maxGlyphs)
lbh.currentPosition = qMax(line.from, current.position);
end = current.position + eng->length(item);
lbh.glyphs = eng->shapedGlyphs(&current);
+ QFontEngine *fontEngine = eng->fontEngine(current);
+ if (lbh.fontEngine != fontEngine) {
+ lbh.fontEngine = fontEngine;
+ lbh.minimumRightBearing = qMin(QFixed(),
+ QFixed::fromReal(fontEngine->minRightBearing()));
+ }
}
const QScriptItem &current = eng->layoutData->items[item];
- QFontEngine *fontEngine = eng->fontEngine(current);
- if (lbh.fontEngine != fontEngine) {
- lbh.fontEngine = fontEngine;
- lbh.minimumRightBearing = qMin(QFixed(),
- QFixed::fromReal(fontEngine->minRightBearing()));
- }
lbh.tmpData.leading = qMax(lbh.tmpData.leading + lbh.tmpData.ascent,
current.leading + current.ascent) - qMax(lbh.tmpData.ascent,