diff options
author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2014-09-01 15:02:07 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2014-09-03 21:00:45 +0200 |
commit | 49b71cd747ed5144c60198d8c09f4c2e99eca853 (patch) | |
tree | b24398bb3da4470b54a0c28efc986f869af8096b | |
parent | 493382c64f32630ee72ef74771ddb53d5c098f3b (diff) |
Improve layout and rendering speed of complex font path
This patch enables the use of the TextLayout object previously only used
by the Mac port. This caches a line of laid out text making reflowing
text much faster when using the complex font path.
The patch also enables caching in the QTextLayout, this improves also
drawing and measuring of complex fonts, since previously we would throw
away details of the layout after calculating a line, but then
recalculate it for drawing or measuring.
Change-Id: I9db40cdb5a35d28072204f950a8aa50669ac643b
Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
-rw-r--r-- | Source/WebCore/platform/graphics/Font.cpp | 2 | ||||
-rw-r--r-- | Source/WebCore/platform/graphics/Font.h | 1 | ||||
-rw-r--r-- | Source/WebCore/platform/graphics/qt/FontQt.cpp | 66 |
3 files changed, 67 insertions, 2 deletions
diff --git a/Source/WebCore/platform/graphics/Font.cpp b/Source/WebCore/platform/graphics/Font.cpp index f58bcc843..4f6570f8a 100644 --- a/Source/WebCore/platform/graphics/Font.cpp +++ b/Source/WebCore/platform/graphics/Font.cpp @@ -329,7 +329,7 @@ float Font::width(const TextRun& run, int& charsConsumed, String& glyphName) con return width(run); } -#if !PLATFORM(MAC) +#if !PLATFORM(MAC) && !PLATFORM(QT) PassOwnPtr<TextLayout> Font::createLayout(RenderText*, float, bool) const { return nullptr; diff --git a/Source/WebCore/platform/graphics/Font.h b/Source/WebCore/platform/graphics/Font.h index 08e0ad49a..f2625871f 100644 --- a/Source/WebCore/platform/graphics/Font.h +++ b/Source/WebCore/platform/graphics/Font.h @@ -212,6 +212,7 @@ private: friend struct WidthIterator; friend class SVGTextRunRenderingContext; + friend class TextLayout; public: // Useful for debugging the different font rendering code paths. diff --git a/Source/WebCore/platform/graphics/qt/FontQt.cpp b/Source/WebCore/platform/graphics/qt/FontQt.cpp index 324fdf05f..3eead7e70 100644 --- a/Source/WebCore/platform/graphics/qt/FontQt.cpp +++ b/Source/WebCore/platform/graphics/qt/FontQt.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) + Copyright (C) 2012, 2014 Digia Plc. and/or its subsidiary(-ies) Copyright (C) 2008, 2010 Holger Hans Peter Freyther Copyright (C) 2009 Dirk Schulze <krit@webkit.org> @@ -31,6 +31,8 @@ #include "GraphicsContext.h" #include "NotImplemented.h" #include "Pattern.h" +#include "RenderBlock.h" +#include "RenderText.h" #include "ShadowBlur.h" #include "TextRun.h" @@ -62,6 +64,7 @@ static QTextLine setupLayout(QTextLayout* layout, const TextRun& style) int flags = style.rtl() ? Qt::TextForceRightToLeft : Qt::TextForceLeftToRight; if (style.expansion()) flags |= Qt::TextJustificationForced; + layout->setCacheEnabled(true); layout->setFlags(flags); layout->beginLayout(); QTextLine line = layout->createLine(); @@ -168,6 +171,67 @@ static void drawQtGlyphRun(GraphicsContext* context, const QGlyphRun& qtGlyphRun } } +class TextLayout { +public: + static bool isNeeded(RenderText* text, const Font& font) + { + TextRun run = RenderBlock::constructTextRun(text, font, text, text->style()); + return font.codePath(run) == Font::Complex; + } + + TextLayout(RenderText* text, const Font& font, float xPos) + { + const TextRun run(constructTextRun(text, font, xPos)); + const String sanitized = Font::normalizeSpaces(run.characters16(), run.length()); + const QString string(sanitized); + m_layout.setText(string); + m_layout.setRawFont(font.rawFont()); + font.initFormatForTextLayout(&m_layout, run); + m_line = setupLayout(&m_layout, run); + } + + float width(unsigned from, unsigned len, HashSet<const SimpleFontData*>* fallbackFonts) + { + Q_UNUSED(fallbackFonts); + float x1 = m_line.cursorToX(from); + float x2 = m_line.cursorToX(from + len); + float width = qAbs(x2 - x1); + + return width; + } + +private: + static TextRun constructTextRun(RenderText* text, const Font& font, float xPos) + { + TextRun run = RenderBlock::constructTextRun(text, font, text, text->style()); + run.setCharactersLength(text->textLength()); + ASSERT(run.charactersLength() >= run.length()); + + run.setXPos(xPos); + return run; + } + + QTextLayout m_layout; + QTextLine m_line; +}; + +PassOwnPtr<TextLayout> Font::createLayout(RenderText* text, float xPos, bool collapseWhiteSpace) const +{ + if (!collapseWhiteSpace || !TextLayout::isNeeded(text, *this)) + return PassOwnPtr<TextLayout>(); + return adoptPtr(new TextLayout(text, *this, xPos)); +} + +void Font::deleteLayout(TextLayout* layout) +{ + delete layout; +} + +float Font::width(TextLayout& layout, unsigned from, unsigned len, HashSet<const SimpleFontData*>* fallbackFonts) +{ + return layout.width(from, len, fallbackFonts); +} + void Font::drawComplexText(GraphicsContext* ctx, const TextRun& run, const FloatPoint& point, int from, int to) const { String sanitized = Font::normalizeSpaces(run.characters16(), run.length()); |