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

Side by Side Diff: Source/platform/fonts/shaping/CachingWordShapeIterator.h

Issue 1242213002: Add tab characters support in complex path (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: fast/text/drawBidiText.html NeedsRebaseline Created 5 years, 4 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2015 Google Inc. All rights reserved. 2 * Copyright (C) 2015 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 20 matching lines...) Expand all
31 #include "platform/fonts/shaping/HarfBuzzShaper.h" 31 #include "platform/fonts/shaping/HarfBuzzShaper.h"
32 #include "platform/fonts/shaping/ShapeCache.h" 32 #include "platform/fonts/shaping/ShapeCache.h"
33 #include "wtf/text/CharacterNames.h" 33 #include "wtf/text/CharacterNames.h"
34 34
35 namespace blink { 35 namespace blink {
36 36
37 class CachingWordShapeIterator { 37 class CachingWordShapeIterator {
38 public: 38 public:
39 CachingWordShapeIterator(ShapeCache* cache, const TextRun& run, 39 CachingWordShapeIterator(ShapeCache* cache, const TextRun& run,
40 const Font* font) 40 const Font* font)
41 : m_shapeCache(cache), m_textRun(run), m_font(font), m_startIndex(0) 41 : m_shapeCache(cache), m_textRun(run), m_font(font)
42 , m_widthSoFar(0), m_startIndex(0)
42 { 43 {
43 ASSERT(font); 44 ASSERT(font);
44 const FontDescription& fontDescription = font->fontDescription(); 45 const FontDescription& fontDescription = font->fontDescription();
45 46
46 // Word and letter spacing can change the width of a word, as can tabs 47 // Word and letter spacing can change the width of a word, as can tabs
47 // as we segment solely based on on space characters. 48 // as we segment solely based on on space characters.
48 // If expansion is used (for justified text) the spacing between words 49 // If expansion is used (for justified text) the spacing between words
49 // change and thus we need to shape the entire run. 50 // change and thus we need to shape the entire run.
50 m_wordResultCachable = !fontDescription.wordSpacing() 51 m_wordResultCachable = !fontDescription.wordSpacing()
51 && !fontDescription.letterSpacing() && !run.allowTabs() 52 && !fontDescription.letterSpacing()
52 && m_textRun.expansion() == 0.0f; 53 && m_textRun.expansion() == 0.0f;
53 54
54 // Shaping word by word is faster as each word is cached. If we cannot 55 // Shaping word by word is faster as each word is cached. If we cannot
55 // use the cache or if the font doesn't support word by word shaping 56 // use the cache or if the font doesn't support word by word shaping
56 // fall back on shaping the entire run. 57 // fall back on shaping the entire run.
57 m_shapeByWord = m_wordResultCachable && m_font->canShapeWordByWord(); 58 m_shapeByWord = m_wordResultCachable && m_font->canShapeWordByWord();
58 } 59 }
59 60
60 bool next(RefPtr<ShapeResult>* wordResult) 61 bool next(RefPtr<ShapeResult>* wordResult)
61 { 62 {
63 if (UNLIKELY(m_textRun.allowTabs()))
64 return nextForAllowTabs(wordResult);
65
62 if (!m_shapeByWord) { 66 if (!m_shapeByWord) {
63 if (m_startIndex) 67 if (m_startIndex)
64 return false; 68 return false;
65 *wordResult = shapeWord(m_textRun, m_font); 69 *wordResult = shapeWord(m_textRun, m_font);
66 m_startIndex = 1; 70 m_startIndex = 1;
67 return *wordResult; 71 return *wordResult;
68 } 72 }
69 73
70 unsigned length = m_textRun.length(); 74 return nextWord(wordResult);
71 if (m_startIndex < length) {
72 if (m_textRun[m_startIndex] == spaceCharacter) {
73 TextRun wordRun = m_textRun.subRun(m_startIndex, 1);
74 *wordResult = shapeWord(wordRun, m_font);
75 m_startIndex++;
76 return true;
77 }
78
79 for (unsigned i = m_startIndex; ; i++) {
80 if (i == length || m_textRun[i] == spaceCharacter) {
81 TextRun wordRun = m_textRun.subRun(m_startIndex,
82 i - m_startIndex);
83 *wordResult = shapeWord(wordRun, m_font);
84 m_startIndex = i;
85 return true;
86 }
87 }
88 }
89 return false;
90 } 75 }
91 76
92 private: 77 private:
93 PassRefPtr<ShapeResult> shapeWord(const TextRun& wordRun, const Font* font) 78 PassRefPtr<ShapeResult> shapeWord(const TextRun& wordRun, const Font* font)
94 { 79 {
95 ShapeCacheEntry* cacheEntry = m_wordResultCachable 80 ShapeCacheEntry* cacheEntry = m_wordResultCachable
96 ? m_shapeCache->add(wordRun, ShapeCacheEntry()) 81 ? m_shapeCache->add(wordRun, ShapeCacheEntry())
97 : nullptr; 82 : nullptr;
98 if (cacheEntry && cacheEntry->m_shapeResult) 83 if (cacheEntry && cacheEntry->m_shapeResult)
99 return cacheEntry->m_shapeResult; 84 return cacheEntry->m_shapeResult;
100 85
101 HarfBuzzShaper shaper(font, wordRun); 86 HarfBuzzShaper shaper(font, wordRun);
102 RefPtr<ShapeResult> shapeResult = shaper.shapeResult(); 87 RefPtr<ShapeResult> shapeResult = shaper.shapeResult();
103 if (!shapeResult) 88 if (!shapeResult)
104 return nullptr; 89 return nullptr;
105 90
106 if (cacheEntry) 91 if (cacheEntry)
107 cacheEntry->m_shapeResult = shapeResult; 92 cacheEntry->m_shapeResult = shapeResult;
108 93
109 return shapeResult.release(); 94 return shapeResult.release();
110 } 95 }
111 96
97 bool nextWord(RefPtr<ShapeResult>* wordResult)
98 {
99 unsigned length = m_textRun.length();
100 if (m_startIndex < length) {
101 if (m_textRun[m_startIndex] == spaceCharacter
102 || m_textRun[m_startIndex] == tabulationCharacter) {
103 TextRun wordRun = m_textRun.subRun(m_startIndex, 1);
104 *wordResult = shapeWord(wordRun, m_font);
105 m_startIndex++;
106 return *wordResult;
107 }
108
109 return nextUntilCharacterOrTab(wordResult, spaceCharacter);
110 }
111 return false;
112 }
113
114 bool nextUntilCharacterOrTab(RefPtr<ShapeResult>* wordResult, UChar delimite r)
115 {
116 unsigned length = m_textRun.length();
117 ASSERT(m_startIndex < length);
118 for (unsigned i = m_startIndex + 1; ; i++) {
119 if (i == length || m_textRun[i] == delimiter
120 || m_textRun[i] == tabulationCharacter) {
121 TextRun wordRun = m_textRun.subRun(m_startIndex,
122 i - m_startIndex);
123 m_startIndex = i;
124 *wordResult = shapeWord(wordRun, m_font);
125 return *wordResult;
126 }
127 }
128 }
129
130 bool nextForAllowTabs(RefPtr<ShapeResult>* wordResult)
131 {
132 unsigned length = m_textRun.length();
133 if (m_startIndex >= length)
134 return false;
135
136 if (UNLIKELY(m_textRun[m_startIndex] == tabulationCharacter)) {
137 for (unsigned i = m_startIndex + 1; ; i++) {
138 if (i == length || m_textRun[i] != tabulationCharacter) {
139 *wordResult = ShapeResult::createForTabulationCharacters(
140 m_font, m_textRun, m_widthSoFar, i - m_startIndex);
141 m_startIndex = i;
142 break;
143 }
144 }
145 } else if (!m_shapeByWord) {
146 if (!nextUntilCharacterOrTab(wordResult, 0))
147 return false;
148 } else {
149 if (!nextWord(wordResult))
150 return false;
151 }
152 if (!*wordResult)
153 return false;
154 m_widthSoFar += (*wordResult)->width();
155 return true;
156 }
157
112 ShapeCache* m_shapeCache; 158 ShapeCache* m_shapeCache;
113 const TextRun& m_textRun; 159 const TextRun& m_textRun;
114 const Font* m_font; 160 const Font* m_font;
161 float m_widthSoFar; // Used only when allowTabs()
115 unsigned m_startIndex : 30; 162 unsigned m_startIndex : 30;
116 unsigned m_wordResultCachable : 1; 163 unsigned m_wordResultCachable : 1;
117 unsigned m_shapeByWord : 1; 164 unsigned m_shapeByWord : 1;
118 }; 165 };
119 166
120 } // namespace blink 167 } // namespace blink
121 168
122 #endif // CachingWordShapeIterator_h 169 #endif // CachingWordShapeIterator_h
OLDNEW
« no previous file with comments | « LayoutTests/fast/css/tab-size-complex-path-expected.html ('k') | Source/platform/fonts/shaping/HarfBuzzShaper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698