From 49b71cd747ed5144c60198d8c09f4c2e99eca853 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 1 Sep 2014 15:02:07 +0200 Subject: 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 --- Source/WebCore/platform/graphics/Font.cpp | 2 +- Source/WebCore/platform/graphics/Font.h | 1 + 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 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 @@ -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* 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 Font::createLayout(RenderText* text, float xPos, bool collapseWhiteSpace) const +{ + if (!collapseWhiteSpace || !TextLayout::isNeeded(text, *this)) + return PassOwnPtr(); + return adoptPtr(new TextLayout(text, *this, xPos)); +} + +void Font::deleteLayout(TextLayout* layout) +{ + delete layout; +} + +float Font::width(TextLayout& layout, unsigned from, unsigned len, HashSet* 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()); -- cgit v1.2.3