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

Side by Side Diff: third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.cpp

Issue 2715773002: Add ShapeResult::RunInfo glyph iterators (Closed)
Patch Set: fillGlyphBufferForResult Created 3 years, 9 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 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "platform/fonts/shaping/ShapeResultBuffer.h" 5 #include "platform/fonts/shaping/ShapeResultBuffer.h"
6 6
7 #include "platform/fonts/CharacterRange.h" 7 #include "platform/fonts/CharacterRange.h"
8 #include "platform/fonts/GlyphBuffer.h" 8 #include "platform/fonts/GlyphBuffer.h"
9 #include "platform/fonts/SimpleFontData.h" 9 #include "platform/fonts/SimpleFontData.h"
10 #include "platform/fonts/shaping/ShapeResultInlineHeaders.h" 10 #include "platform/fonts/shaping/ShapeResultInlineHeaders.h"
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 int numGraphemes = -1; 82 int numGraphemes = -1;
83 while (0 <= cursorPos) { 83 while (0 <= cursorPos) {
84 cursorPos = cursorPosIterator->next(); 84 cursorPos = cursorPosIterator->next();
85 numGraphemes++; 85 numGraphemes++;
86 } 86 }
87 return std::max(0, numGraphemes); 87 return std::max(0, numGraphemes);
88 } 88 }
89 89
90 } // anonymous namespace 90 } // anonymous namespace
91 91
92 template <TextDirection direction> 92 float ShapeResultBuffer::fillGlyphBufferForResult(GlyphBuffer* glyphBuffer,
93 float ShapeResultBuffer::fillGlyphBufferForRun(GlyphBuffer* glyphBuffer, 93 const ShapeResult& result,
94 const ShapeResult::RunInfo* run, 94 const TextRun& textRun,
95 const TextRun& textRun, 95 float initialAdvance,
96 float initialAdvance, 96 unsigned from,
97 unsigned from, 97 unsigned to,
98 unsigned to, 98 unsigned runOffset) {
99 unsigned runOffset) { 99 auto totalAdvance = initialAdvance;
100 if (!run) 100
101 return 0; 101 for (const auto& run : result.m_runs) {
102 float advanceSoFar = initialAdvance; 102 totalAdvance = run->forEachGlyphInRange(
103 const unsigned numGlyphs = run->m_glyphData.size(); 103 totalAdvance, from, to, runOffset,
104 for (unsigned i = 0; i < numGlyphs; ++i) { 104 [&](const HarfBuzzRunGlyphData& glyphData, float totalAdvance,
105 const HarfBuzzRunGlyphData& glyphData = run->m_glyphData[i]; 105 uint16_t characterIndex) -> bool {
106 uint16_t currentCharacterIndex = 106
107 run->m_startIndex + glyphData.characterIndex + runOffset; 107 addGlyphToBuffer(glyphBuffer, totalAdvance, run->m_direction,
108 if ((direction == TextDirection::kRtl && currentCharacterIndex >= to) || 108 run->m_fontData.get(), glyphData, textRun,
109 (direction == TextDirection::kLtr && currentCharacterIndex < from)) { 109 characterIndex);
110 advanceSoFar += glyphData.advance; 110 return true;
111 } else if ((direction == TextDirection::kRtl && 111 });
112 currentCharacterIndex >= from) ||
113 (direction == TextDirection::kLtr &&
114 currentCharacterIndex < to)) {
115 addGlyphToBuffer(glyphBuffer, advanceSoFar, run->m_direction,
116 run->m_fontData.get(), glyphData, textRun,
117 currentCharacterIndex);
118 advanceSoFar += glyphData.advance;
119 }
120 } 112 }
121 return advanceSoFar - initialAdvance; 113
114 return totalAdvance;
122 } 115 }
123 116
124 float ShapeResultBuffer::fillGlyphBufferForTextEmphasisRun( 117 float ShapeResultBuffer::fillGlyphBufferForTextEmphasisRun(
125 GlyphBuffer* glyphBuffer, 118 GlyphBuffer* glyphBuffer,
126 const ShapeResult::RunInfo* run, 119 const ShapeResult::RunInfo* run,
127 const TextRun& textRun, 120 const TextRun& textRun,
128 const GlyphData* emphasisData, 121 const GlyphData* emphasisData,
129 float initialAdvance, 122 float initialAdvance,
130 unsigned from, 123 unsigned from,
131 unsigned to, 124 unsigned to,
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 clusterStart = clusterEnd; 200 clusterStart = clusterEnd;
208 clusterAdvance = 0; 201 clusterAdvance = 0;
209 } 202 }
210 } 203 }
211 return advanceSoFar - initialAdvance; 204 return advanceSoFar - initialAdvance;
212 } 205 }
213 206
214 float ShapeResultBuffer::fillFastHorizontalGlyphBuffer( 207 float ShapeResultBuffer::fillFastHorizontalGlyphBuffer(
215 GlyphBuffer* glyphBuffer, 208 GlyphBuffer* glyphBuffer,
216 const TextRun& textRun) const { 209 const TextRun& textRun) const {
217 ASSERT(!hasVerticalOffsets()); 210 DCHECK(!hasVerticalOffsets());
218 211
219 float advance = 0; 212 float advance = 0;
220 213
221 unsigned characterIndex = 0; 214 unsigned characterIndex = 0;
222 for (unsigned i = 0; i < m_results.size(); ++i) { 215 for (unsigned i = 0; i < m_results.size(); ++i) {
223 const auto& wordResult = isLeftToRightDirection(textRun.direction()) 216 const auto& wordResult = isLeftToRightDirection(textRun.direction())
224 ? m_results[i] 217 ? m_results[i]
225 : m_results[m_results.size() - 1 - i]; 218 : m_results[m_results.size() - 1 - i];
226 ASSERT(!wordResult->hasVerticalOffsets()); 219 DCHECK(!wordResult->hasVerticalOffsets());
227 220
228 for (const auto& run : wordResult->m_runs) { 221 for (const auto& run : wordResult->m_runs) {
229 ASSERT(run); 222 DCHECK(run);
230 ASSERT(HB_DIRECTION_IS_HORIZONTAL(run->m_direction)); 223 DCHECK(HB_DIRECTION_IS_HORIZONTAL(run->m_direction));
231 224
232 for (const auto& glyphData : run->m_glyphData) { 225 advance = run->forEachGlyph(
233 ASSERT(!glyphData.offset.height()); 226 advance,
227 [&](const HarfBuzzRunGlyphData& glyphData,
228 float totalAdvance) -> bool {
229 DCHECK(!glyphData.offset.height());
234 230
235 if (!isSkipInkException(*glyphBuffer, textRun, 231 if (!isSkipInkException(
236 characterIndex + glyphData.characterIndex)) { 232 *glyphBuffer, textRun,
237 glyphBuffer->add(glyphData.glyph, run->m_fontData.get(), 233 characterIndex + glyphData.characterIndex)) {
238 advance + glyphData.offset.width()); 234 glyphBuffer->add(glyphData.glyph, run->m_fontData.get(),
239 } 235 totalAdvance + glyphData.offset.width());
240 236 }
241 advance += glyphData.advance; 237 return true;
242 } 238 });
243 } 239 }
244 characterIndex += wordResult->m_numCharacters; 240 characterIndex += wordResult->m_numCharacters;
245 } 241 }
246 242
247 ASSERT(!glyphBuffer->hasVerticalOffsets()); 243 ASSERT(!glyphBuffer->hasVerticalOffsets());
248 244
249 return advance; 245 return advance;
250 } 246 }
251 247
252 float ShapeResultBuffer::fillGlyphBuffer(GlyphBuffer* glyphBuffer, 248 float ShapeResultBuffer::fillGlyphBuffer(GlyphBuffer* glyphBuffer,
253 const TextRun& textRun, 249 const TextRun& textRun,
254 unsigned from, 250 unsigned from,
255 unsigned to) const { 251 unsigned to) const {
256 // Fast path: full run with no vertical offsets 252 // Fast path: full run with no vertical offsets
257 if (!from && to == textRun.length() && !hasVerticalOffsets()) 253 if (!from && to == textRun.length() && !hasVerticalOffsets())
258 return fillFastHorizontalGlyphBuffer(glyphBuffer, textRun); 254 return fillFastHorizontalGlyphBuffer(glyphBuffer, textRun);
259 255
260 float advance = 0; 256 float advance = 0;
261 257
262 if (textRun.rtl()) { 258 if (textRun.rtl()) {
263 unsigned wordOffset = textRun.length(); 259 unsigned wordOffset = textRun.length();
264 for (unsigned j = 0; j < m_results.size(); j++) { 260 for (unsigned j = 0; j < m_results.size(); j++) {
265 unsigned resolvedIndex = m_results.size() - 1 - j; 261 unsigned resolvedIndex = m_results.size() - 1 - j;
266 const RefPtr<const ShapeResult>& wordResult = m_results[resolvedIndex]; 262 const RefPtr<const ShapeResult>& wordResult = m_results[resolvedIndex];
267 for (unsigned i = 0; i < wordResult->m_runs.size(); i++) {
268 advance += fillGlyphBufferForRun<TextDirection::kRtl>(
269 glyphBuffer, wordResult->m_runs[i].get(), textRun, advance, from,
270 to, wordOffset - wordResult->numCharacters());
271 }
272 wordOffset -= wordResult->numCharacters(); 263 wordOffset -= wordResult->numCharacters();
264 advance = fillGlyphBufferForResult(glyphBuffer, *wordResult, textRun,
265 advance, from, to, wordOffset);
273 } 266 }
274 } else { 267 } else {
275 unsigned wordOffset = 0; 268 unsigned wordOffset = 0;
276 for (unsigned j = 0; j < m_results.size(); j++) { 269 for (const auto& wordResult : m_results) {
277 const RefPtr<const ShapeResult>& wordResult = m_results[j]; 270 advance = fillGlyphBufferForResult(glyphBuffer, *wordResult, textRun,
278 for (unsigned i = 0; i < wordResult->m_runs.size(); i++) { 271 advance, from, to, wordOffset);
279 advance += fillGlyphBufferForRun<TextDirection::kLtr>(
280 glyphBuffer, wordResult->m_runs[i].get(), textRun, advance, from,
281 to, wordOffset);
282 }
283 wordOffset += wordResult->numCharacters(); 272 wordOffset += wordResult->numCharacters();
284 } 273 }
285 } 274 }
286 275
287 return advance; 276 return advance;
288 } 277 }
289 278
290 float ShapeResultBuffer::fillGlyphBufferForTextEmphasis( 279 float ShapeResultBuffer::fillGlyphBufferForTextEmphasis(
291 GlyphBuffer* glyphBuffer, 280 GlyphBuffer* glyphBuffer,
292 const TextRun& textRun, 281 const TextRun& textRun,
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 totalOffset += offsetForWord; 482 totalOffset += offsetForWord;
494 if (targetX >= 0 && targetX <= wordResult->width()) 483 if (targetX >= 0 && targetX <= wordResult->width())
495 return totalOffset; 484 return totalOffset;
496 targetX -= wordResult->width(); 485 targetX -= wordResult->width();
497 } 486 }
498 } 487 }
499 return totalOffset; 488 return totalOffset;
500 } 489 }
501 490
502 } // namespace blink 491 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698