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

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: w/updated TestExpectations 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 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/text/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
47 // Letter spacing can change the width of a word, as can tabs as we
48 // segment solely based on on space characters.
49 m_wordResultCachable = !fontDescription.letterSpacing()
50 && !run.allowTabs();
51
52 // Shaping word by word is faster as each word is cached. If we cannot
53 // use the cache or if the font doesn't support word by word shaping
54 // fall back on shaping the entire run.
55 // If word spacing or expansion is used (for justified text) the spacing
56 // between words change and thus we need to shape the entire run.
57 m_shapeByWord = m_wordResultCachable && m_font->canShapeWordByWord()
58 && !fontDescription.wordSpacing() && m_textRun.expansion() == 0.0f;
59 }
60
61 bool next(RefPtr<ShapeResult>* wordResult)
62 {
63 if (!m_shapeByWord) {
64 if (m_startIndex)
65 return false;
66 *wordResult = shapeWord(m_textRun, m_font, m_fallbackFonts);
67 m_startIndex = 1;
68 return *wordResult;
69 }
70
71 unsigned length = m_textRun.length();
72 if (m_startIndex < length) {
73 if (m_textRun[m_startIndex] == spaceCharacter) {
74 TextRun wordRun = m_textRun.subRun(m_startIndex, 1);
75 *wordResult = shapeWord(wordRun, m_font, m_fallbackFonts);
76 m_startIndex++;
77 return true;
78 }
79
80 for (unsigned i = m_startIndex; ; i++) {
81 if (i == length || m_textRun[i] == spaceCharacter) {
82 TextRun wordRun = m_textRun.subRun(m_startIndex,
83 i - m_startIndex);
84 *wordResult = shapeWord(wordRun, m_font, m_fallbackFonts);
85 m_startIndex = i;
86 return true;
87 }
88 }
89 }
90 return false;
91 }
92
93 private:
94 PassRefPtr<ShapeResult> shapeWord(const TextRun& wordRun,
95 const Font* font, HashSet<const SimpleFontData*>* fallbackFonts)
96 {
97 ShapeCacheEntry* cacheEntry = m_wordResultCachable
98 ? m_shapeCache->add(wordRun, ShapeCacheEntry())
99 : nullptr;
100 if (cacheEntry && cacheEntry->m_shapeResult)
101 return cacheEntry->m_shapeResult;
102
103 HarfBuzzShaper shaper(font, wordRun, fallbackFonts);
104 RefPtr<ShapeResult> shapeResult = shaper.shapeResult();
105 if (!shapeResult)
106 return nullptr;
107
108 // FIXME: Add support for fallback fonts. https://crbug.com/503688
109 if (cacheEntry && (!fallbackFonts || fallbackFonts->isEmpty()))
110 cacheEntry->m_shapeResult = shapeResult;
111
112 return shapeResult.release();
113 }
114
115 ShapeCache* m_shapeCache;
116 const TextRun& m_textRun;
117 const Font* m_font;
118 HashSet<const SimpleFontData*>* m_fallbackFonts;
119 unsigned m_startIndex : 30;
120 unsigned m_wordResultCachable : 1;
121 unsigned m_shapeByWord : 1;
122 };
123
124 } // namespace blink
125
126 #endif // CachingWordShapeIterator_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698