Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(216)

Unified Diff: Source/platform/fonts/shaping/CachingWordShapeIterator.h

Issue 1192223002: Optimize Complex Text Shaping and Caching (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Change CachingWordShaperTest as suggested Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/platform/fonts/WidthCache.h ('k') | Source/platform/fonts/shaping/CachingWordShaper.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/platform/fonts/shaping/CachingWordShapeIterator.h
diff --git a/Source/platform/fonts/shaping/CachingWordShapeIterator.h b/Source/platform/fonts/shaping/CachingWordShapeIterator.h
new file mode 100644
index 0000000000000000000000000000000000000000..469fb398b3c97954bd41d5c6709b39a59ab7ff26
--- /dev/null
+++ b/Source/platform/fonts/shaping/CachingWordShapeIterator.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2015 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CachingWordShapeIterator_h
+#define CachingWordShapeIterator_h
+
+#include "platform/fonts/SimpleFontData.h"
+#include "platform/fonts/shaping/CachingWordShapeIterator.h"
+#include "platform/fonts/shaping/HarfBuzzShaper.h"
+#include "platform/fonts/shaping/ShapeCache.h"
+#include "wtf/text/CharacterNames.h"
+
+namespace blink {
+
+class CachingWordShapeIterator {
+public:
+ CachingWordShapeIterator(ShapeCache* cache, const TextRun& run,
+ const Font* font, HashSet<const SimpleFontData*>* fallbackFonts)
+ : m_shapeCache(cache), m_textRun(run), m_font(font)
+ , m_fallbackFonts(fallbackFonts), m_startIndex(0)
+ {
+ ASSERT(font);
+ const FontDescription& fontDescription = font->fontDescription();
+
+ // Letter spacing can change the width of a word, as can tabs as we
+ // segment solely based on on space characters.
+ m_wordResultCachable = !fontDescription.letterSpacing()
+ && !run.allowTabs();
+
+ // Shaping word by word is faster as each word is cached. If we cannot
+ // use the cache or if the font doesn't support word by word shaping
+ // fall back on shaping the entire run.
+ // If word spacing or expansion is used (for justified text) the spacing
+ // between words change and thus we need to shape the entire run.
+ m_shapeByWord = m_wordResultCachable && m_font->canShapeWordByWord()
+ && !fontDescription.wordSpacing() && m_textRun.expansion() == 0.0f;
+ }
+
+ bool next(RefPtr<ShapeResult>* wordResult)
+ {
+ if (!m_shapeByWord) {
+ if (m_startIndex)
+ return false;
+ *wordResult = shapeWord(m_textRun, m_font, m_fallbackFonts);
+ m_startIndex = 1;
+ return *wordResult;
+ }
+
+ unsigned length = m_textRun.length();
+ if (m_startIndex < length) {
+ if (m_textRun[m_startIndex] == spaceCharacter) {
+ TextRun wordRun = m_textRun.subRun(m_startIndex, 1);
+ *wordResult = shapeWord(wordRun, m_font, m_fallbackFonts);
+ m_startIndex++;
+ return true;
+ }
+
+ for (unsigned i = m_startIndex; ; i++) {
+ if (i == length || m_textRun[i] == spaceCharacter) {
+ TextRun wordRun = m_textRun.subRun(m_startIndex,
+ i - m_startIndex);
+ *wordResult = shapeWord(wordRun, m_font, m_fallbackFonts);
+ m_startIndex = i;
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+private:
+ PassRefPtr<ShapeResult> shapeWord(const TextRun& wordRun,
+ const Font* font, HashSet<const SimpleFontData*>* fallbackFonts)
+ {
+ ShapeCacheEntry* cacheEntry = m_wordResultCachable
+ ? m_shapeCache->add(wordRun, ShapeCacheEntry())
+ : nullptr;
+ if (cacheEntry && cacheEntry->m_shapeResult)
+ return cacheEntry->m_shapeResult;
+
+ HarfBuzzShaper shaper(font, wordRun, fallbackFonts);
+ RefPtr<ShapeResult> shapeResult = shaper.shapeResult();
+ if (!shapeResult)
+ return nullptr;
+
+ // FIXME: Add support for fallback fonts. https://crbug.com/503688
+ if (cacheEntry && (!fallbackFonts || fallbackFonts->isEmpty()))
+ cacheEntry->m_shapeResult = shapeResult;
+
+ return shapeResult.release();
+ }
+
+ ShapeCache* m_shapeCache;
+ const TextRun& m_textRun;
+ const Font* m_font;
+ HashSet<const SimpleFontData*>* m_fallbackFonts;
+ unsigned m_startIndex : 30;
+ unsigned m_wordResultCachable : 1;
+ unsigned m_shapeByWord : 1;
+};
+
+} // namespace blink
+
+#endif // CachingWordShapeIterator_h
« no previous file with comments | « Source/platform/fonts/WidthCache.h ('k') | Source/platform/fonts/shaping/CachingWordShaper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698