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

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

Issue 2598393002: Do not skip ink for ideographic scripts (Closed)
Patch Set: drott nits Created 3 years, 11 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"
11 #include "platform/geometry/FloatPoint.h" 11 #include "platform/geometry/FloatPoint.h"
12 #include "platform/text/Character.h" 12 #include "platform/text/Character.h"
13 #include "platform/text/TextBreakIterator.h" 13 #include "platform/text/TextBreakIterator.h"
14 #include "platform/text/TextDirection.h" 14 #include "platform/text/TextDirection.h"
15 15
16 namespace blink { 16 namespace blink {
17 17
18 namespace { 18 namespace {
19 19
20 inline void addIsSkipInkException(GlyphBuffer* glyphBuffer,
21 const TextRun& run,
22 unsigned characterIndex) {
23 // We want to skip descenders in general, but it is undesirable renderings for
24 // CJK characters.
25 DCHECK(!run.is8Bit()) << "8Bit() is always false, better to avoid to call";
26 UChar32 baseCharacter = run.codepointAt(characterIndex);
27 glyphBuffer->addIsSkipInkException(
28 Character::isCJKIdeographOrSymbol(baseCharacter));
29 }
30
20 inline void addGlyphToBuffer(GlyphBuffer* glyphBuffer, 31 inline void addGlyphToBuffer(GlyphBuffer* glyphBuffer,
21 float advance, 32 float advance,
22 hb_direction_t direction, 33 hb_direction_t direction,
23 const SimpleFontData* fontData, 34 const SimpleFontData* fontData,
24 const HarfBuzzRunGlyphData& glyphData) { 35 const HarfBuzzRunGlyphData& glyphData,
36 const TextRun& run,
37 unsigned characterIndex) {
25 FloatPoint startOffset = HB_DIRECTION_IS_HORIZONTAL(direction) 38 FloatPoint startOffset = HB_DIRECTION_IS_HORIZONTAL(direction)
26 ? FloatPoint(advance, 0) 39 ? FloatPoint(advance, 0)
27 : FloatPoint(0, advance); 40 : FloatPoint(0, advance);
28 glyphBuffer->add(glyphData.glyph, fontData, startOffset + glyphData.offset); 41 glyphBuffer->add(glyphData.glyph, fontData, startOffset + glyphData.offset);
42 if (glyphBuffer->hasSkipInkExceptions())
43 addIsSkipInkException(glyphBuffer, run, characterIndex);
29 } 44 }
30 45
31 inline void addEmphasisMark(GlyphBuffer* buffer, 46 inline void addEmphasisMark(GlyphBuffer* buffer,
32 const GlyphData* emphasisData, 47 const GlyphData* emphasisData,
33 FloatPoint glyphCenter, 48 FloatPoint glyphCenter,
34 float midGlyphOffset) { 49 float midGlyphOffset) {
35 ASSERT(buffer); 50 ASSERT(buffer);
36 ASSERT(emphasisData); 51 ASSERT(emphasisData);
37 52
38 const SimpleFontData* emphasisFontData = emphasisData->fontData; 53 const SimpleFontData* emphasisFontData = emphasisData->fontData;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 numGraphemes++; 86 numGraphemes++;
72 } 87 }
73 return std::max(0, numGraphemes); 88 return std::max(0, numGraphemes);
74 } 89 }
75 90
76 } // anonymous namespace 91 } // anonymous namespace
77 92
78 template <TextDirection direction> 93 template <TextDirection direction>
79 float ShapeResultBuffer::fillGlyphBufferForRun(GlyphBuffer* glyphBuffer, 94 float ShapeResultBuffer::fillGlyphBufferForRun(GlyphBuffer* glyphBuffer,
80 const ShapeResult::RunInfo* run, 95 const ShapeResult::RunInfo* run,
96 const TextRun& textRun,
81 float initialAdvance, 97 float initialAdvance,
82 unsigned from, 98 unsigned from,
83 unsigned to, 99 unsigned to,
84 unsigned runOffset) { 100 unsigned runOffset) {
85 if (!run) 101 if (!run)
86 return 0; 102 return 0;
87 float advanceSoFar = initialAdvance; 103 float advanceSoFar = initialAdvance;
88 const unsigned numGlyphs = run->m_glyphData.size(); 104 const unsigned numGlyphs = run->m_glyphData.size();
89 for (unsigned i = 0; i < numGlyphs; ++i) { 105 for (unsigned i = 0; i < numGlyphs; ++i) {
90 const HarfBuzzRunGlyphData& glyphData = run->m_glyphData[i]; 106 const HarfBuzzRunGlyphData& glyphData = run->m_glyphData[i];
91 uint16_t currentCharacterIndex = 107 uint16_t currentCharacterIndex =
92 run->m_startIndex + glyphData.characterIndex + runOffset; 108 run->m_startIndex + glyphData.characterIndex + runOffset;
93 if ((direction == TextDirection::Rtl && currentCharacterIndex >= to) || 109 if ((direction == TextDirection::Rtl && currentCharacterIndex >= to) ||
94 (direction == TextDirection::Ltr && currentCharacterIndex < from)) { 110 (direction == TextDirection::Ltr && currentCharacterIndex < from)) {
95 advanceSoFar += glyphData.advance; 111 advanceSoFar += glyphData.advance;
96 } else if ((direction == TextDirection::Rtl && 112 } else if ((direction == TextDirection::Rtl &&
97 currentCharacterIndex >= from) || 113 currentCharacterIndex >= from) ||
98 (direction == TextDirection::Ltr && 114 (direction == TextDirection::Ltr &&
99 currentCharacterIndex < to)) { 115 currentCharacterIndex < to)) {
100 addGlyphToBuffer(glyphBuffer, advanceSoFar, run->m_direction, 116 addGlyphToBuffer(glyphBuffer, advanceSoFar, run->m_direction,
101 run->m_fontData.get(), glyphData); 117 run->m_fontData.get(), glyphData, textRun,
118 currentCharacterIndex);
102 advanceSoFar += glyphData.advance; 119 advanceSoFar += glyphData.advance;
103 } 120 }
104 } 121 }
105 return advanceSoFar - initialAdvance; 122 return advanceSoFar - initialAdvance;
106 } 123 }
107 124
108 float ShapeResultBuffer::fillGlyphBufferForTextEmphasisRun( 125 float ShapeResultBuffer::fillGlyphBufferForTextEmphasisRun(
109 GlyphBuffer* glyphBuffer, 126 GlyphBuffer* glyphBuffer,
110 const ShapeResult::RunInfo* run, 127 const ShapeResult::RunInfo* run,
111 const TextRun& textRun, 128 const TextRun& textRun,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 } 207 }
191 clusterStart = clusterEnd; 208 clusterStart = clusterEnd;
192 clusterAdvance = 0; 209 clusterAdvance = 0;
193 } 210 }
194 } 211 }
195 return advanceSoFar - initialAdvance; 212 return advanceSoFar - initialAdvance;
196 } 213 }
197 214
198 float ShapeResultBuffer::fillFastHorizontalGlyphBuffer( 215 float ShapeResultBuffer::fillFastHorizontalGlyphBuffer(
199 GlyphBuffer* glyphBuffer, 216 GlyphBuffer* glyphBuffer,
200 TextDirection dir) const { 217 const TextRun& textRun) const {
201 ASSERT(!hasVerticalOffsets()); 218 ASSERT(!hasVerticalOffsets());
202 219
203 float advance = 0; 220 float advance = 0;
204 221
222 unsigned characterIndex = 0;
205 for (unsigned i = 0; i < m_results.size(); ++i) { 223 for (unsigned i = 0; i < m_results.size(); ++i) {
206 const auto& wordResult = isLeftToRightDirection(dir) 224 const auto& wordResult = isLeftToRightDirection(textRun.direction())
207 ? m_results[i] 225 ? m_results[i]
208 : m_results[m_results.size() - 1 - i]; 226 : m_results[m_results.size() - 1 - i];
209 ASSERT(!wordResult->hasVerticalOffsets()); 227 ASSERT(!wordResult->hasVerticalOffsets());
210 228
211 for (const auto& run : wordResult->m_runs) { 229 for (const auto& run : wordResult->m_runs) {
212 ASSERT(run); 230 ASSERT(run);
213 ASSERT(HB_DIRECTION_IS_HORIZONTAL(run->m_direction)); 231 ASSERT(HB_DIRECTION_IS_HORIZONTAL(run->m_direction));
214 232
215 for (const auto& glyphData : run->m_glyphData) { 233 for (const auto& glyphData : run->m_glyphData) {
216 ASSERT(!glyphData.offset.height()); 234 ASSERT(!glyphData.offset.height());
217 235
218 glyphBuffer->add(glyphData.glyph, run->m_fontData.get(), 236 glyphBuffer->add(glyphData.glyph, run->m_fontData.get(),
219 advance + glyphData.offset.width()); 237 advance + glyphData.offset.width());
238 if (glyphBuffer->hasSkipInkExceptions()) {
239 addIsSkipInkException(glyphBuffer, textRun,
240 characterIndex + glyphData.characterIndex);
241 }
242
220 advance += glyphData.advance; 243 advance += glyphData.advance;
221 } 244 }
222 } 245 }
246 characterIndex += wordResult->m_numCharacters;
223 } 247 }
224 248
225 ASSERT(!glyphBuffer->hasVerticalOffsets()); 249 ASSERT(!glyphBuffer->hasVerticalOffsets());
226 250
227 return advance; 251 return advance;
228 } 252 }
229 253
230 float ShapeResultBuffer::fillGlyphBuffer(GlyphBuffer* glyphBuffer, 254 float ShapeResultBuffer::fillGlyphBuffer(GlyphBuffer* glyphBuffer,
231 const TextRun& textRun, 255 const TextRun& textRun,
232 unsigned from, 256 unsigned from,
233 unsigned to) const { 257 unsigned to) const {
234 // Fast path: full run with no vertical offsets 258 // Fast path: full run with no vertical offsets
235 if (!from && to == textRun.length() && !hasVerticalOffsets()) 259 if (!from && to == textRun.length() && !hasVerticalOffsets())
236 return fillFastHorizontalGlyphBuffer(glyphBuffer, textRun.direction()); 260 return fillFastHorizontalGlyphBuffer(glyphBuffer, textRun);
237 261
238 float advance = 0; 262 float advance = 0;
239 263
240 if (textRun.rtl()) { 264 if (textRun.rtl()) {
241 unsigned wordOffset = textRun.length(); 265 unsigned wordOffset = textRun.length();
242 for (unsigned j = 0; j < m_results.size(); j++) { 266 for (unsigned j = 0; j < m_results.size(); j++) {
243 unsigned resolvedIndex = m_results.size() - 1 - j; 267 unsigned resolvedIndex = m_results.size() - 1 - j;
244 const RefPtr<const ShapeResult>& wordResult = m_results[resolvedIndex]; 268 const RefPtr<const ShapeResult>& wordResult = m_results[resolvedIndex];
245 for (unsigned i = 0; i < wordResult->m_runs.size(); i++) { 269 for (unsigned i = 0; i < wordResult->m_runs.size(); i++) {
246 advance += fillGlyphBufferForRun<TextDirection::Rtl>( 270 advance += fillGlyphBufferForRun<TextDirection::Rtl>(
247 glyphBuffer, wordResult->m_runs[i].get(), advance, from, to, 271 glyphBuffer, wordResult->m_runs[i].get(), textRun, advance, from,
248 wordOffset - wordResult->numCharacters()); 272 to, wordOffset - wordResult->numCharacters());
249 } 273 }
250 wordOffset -= wordResult->numCharacters(); 274 wordOffset -= wordResult->numCharacters();
251 } 275 }
252 } else { 276 } else {
253 unsigned wordOffset = 0; 277 unsigned wordOffset = 0;
254 for (unsigned j = 0; j < m_results.size(); j++) { 278 for (unsigned j = 0; j < m_results.size(); j++) {
255 const RefPtr<const ShapeResult>& wordResult = m_results[j]; 279 const RefPtr<const ShapeResult>& wordResult = m_results[j];
256 for (unsigned i = 0; i < wordResult->m_runs.size(); i++) { 280 for (unsigned i = 0; i < wordResult->m_runs.size(); i++) {
257 advance += fillGlyphBufferForRun<TextDirection::Ltr>( 281 advance += fillGlyphBufferForRun<TextDirection::Ltr>(
258 glyphBuffer, wordResult->m_runs[i].get(), advance, from, to, 282 glyphBuffer, wordResult->m_runs[i].get(), textRun, advance, from,
259 wordOffset); 283 to, wordOffset);
260 } 284 }
261 wordOffset += wordResult->numCharacters(); 285 wordOffset += wordResult->numCharacters();
262 } 286 }
263 } 287 }
264 288
265 return advance; 289 return advance;
266 } 290 }
267 291
268 float ShapeResultBuffer::fillGlyphBufferForTextEmphasis( 292 float ShapeResultBuffer::fillGlyphBufferForTextEmphasis(
269 GlyphBuffer* glyphBuffer, 293 GlyphBuffer* glyphBuffer,
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 totalOffset += offsetForWord; 471 totalOffset += offsetForWord;
448 if (targetX >= 0 && targetX <= wordResult->width()) 472 if (targetX >= 0 && targetX <= wordResult->width())
449 return totalOffset; 473 return totalOffset;
450 targetX -= wordResult->width(); 474 targetX -= wordResult->width();
451 } 475 }
452 } 476 }
453 return totalOffset; 477 return totalOffset;
454 } 478 }
455 479
456 } // namespace blink 480 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698