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

Side by Side 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: Addressing review comments Created 5 years, 6 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2015 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #ifndef CachingWordShapeIterator_h
27 #define CachingWordShapeIterator_h
28
29 #include "platform/fonts/SimpleFontData.h"
30 #include "platform/fonts/shaping/CachingWordShapeIterator.h"
31 #include "platform/fonts/shaping/HarfBuzzShaper.h"
32 #include "platform/fonts/shaping/ShapeCache.h"
33 #include "wtf/unicode/CharacterNames.h"
34
35 namespace blink {
36
37 class CachingWordShapeIterator {
38 public:
39 CachingWordShapeIterator(ShapeCache* cache, const TextRun& run,
40 const Font* font, HashSet<const SimpleFontData*>* fallbackFonts)
41 : m_shapeCache(cache), m_textRun(run), m_font(font)
42 , m_fallbackFonts(fallbackFonts), m_startIndex(0)
43 {
44 ASSERT(font);
45 const FontDescription& fontDescription = font->fontDescription();
46 bool hasWordSpacingOrLetterSpacing = fontDescription.wordSpacing()
47 || fontDescription.letterSpacing();
48 // Word spacing and letter spacing can change the width of a word.
49 // If a tab occurs inside a word, the width of the word varies based on
50 // its position on the line.
51 // If expansion is used (for justified text) the spacing between words
52 // change and thus we cannot use the word cache.
53 // FIXME: Move expansion handling from shaping to ShapeResult and add
54 // support for expansion to shapeWord.
55 m_isCacheable = !hasWordSpacingOrLetterSpacing && !run.allowTabs()
56 && m_textRun.expansion() == 0.0f;
57
58 // Shaping word by word is faster as each word is cached. If we cannot
59 // use the cache or if the font doesn't support word by word shaping
60 // fall back on shaping the entire run.
61 m_shapeByWord = m_font->canShapeWordByWord() && m_isCacheable;
62 }
63
64 bool next(RefPtr<ShapeResult>* wordResult)
65 {
66 if (!m_shapeByWord) {
67 if (m_startIndex)
68 return false;
69 *wordResult = shapeWord(m_textRun, m_font, m_fallbackFonts);
70 m_startIndex = 1;
71 return *wordResult;
72 }
73
74 unsigned length = m_textRun.length();
75 if (m_startIndex < length) {
76 if (m_textRun[m_startIndex] == spaceCharacter) {
77 if (!m_spaceShape) {
78 TextRun wordRun = m_textRun.subRun(m_startIndex, 1);
79 m_spaceShape = shapeWord(wordRun, m_font, m_fallbackFonts);
80 }
81 *wordResult = m_spaceShape;
82 m_startIndex++;
83 return true;
84 }
85
86 for (unsigned i = m_startIndex; ; i++) {
87 if (i == length || m_textRun[i] == spaceCharacter) {
88 TextRun wordRun = m_textRun.subRun(m_startIndex,
89 i - m_startIndex);
90 *wordResult = shapeWord(wordRun, m_font, m_fallbackFonts);
91 m_startIndex = i;
92 return true;
93 }
94 }
95 }
96 return false;
97 }
98
99 private:
100 PassRefPtr<ShapeResult> shapeWord(const TextRun& wordRun,
101 const Font* font, HashSet<const SimpleFontData*>* fallbackFonts)
102 {
103 ShapeCacheEntry* cacheEntry = m_isCacheable
104 ? m_shapeCache->add(wordRun, ShapeCacheEntry())
105 : nullptr;
106 if (cacheEntry && cacheEntry->m_shapeResult)
107 return cacheEntry->m_shapeResult;
108
109 HarfBuzzShaper shaper(font, wordRun, fallbackFonts);
110 RefPtr<ShapeResult> shapeResult = shaper.shapeResult();
111 if (!shapeResult)
112 return nullptr;
113
114 if (cacheEntry && (!fallbackFonts || fallbackFonts->isEmpty()))
drott 2015/06/23 12:45:51 Could you add a similar FIXME + crbug for the fact
115 cacheEntry->m_shapeResult = shapeResult;
116
117 return shapeResult.release();
118 }
119
120 ShapeCache* m_shapeCache;
121 const TextRun& m_textRun;
122 const Font* m_font;
123 HashSet<const SimpleFontData*>* m_fallbackFonts;
124 unsigned m_startIndex : 30;
125 unsigned m_isCacheable : 1;
drott 2015/06/23 12:45:51 When reviewing, I struggled to understand what thi
126 unsigned m_shapeByWord : 1;
127 RefPtr<ShapeResult> m_spaceShape;
128 };
129
130 } // namespace blink
131
132 #endif // CachingWordShapeIterator_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698