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

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

Issue 1561633002: Relocate ShapeResult's GlyphBuffer helpers to ShapeResultBuffer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased Created 4 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
« no previous file with comments | « third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 * Copyright (c) 2012 Google Inc. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be
3 * Copyright (C) 2013 BlackBerry Limited. All rights reserved. 3 // found in the LICENSE file.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31 4
32 #include "platform/fonts/shaping/ShapeResult.h" 5 #include "platform/fonts/shaping/ShapeResultBuffer.h"
33 6
34 #include "platform/fonts/Font.h" 7 #include "platform/fonts/Character.h"
35 #include "platform/fonts/GlyphBuffer.h" 8 #include "platform/fonts/GlyphBuffer.h"
9 #include "platform/fonts/SimpleFontData.h"
36 #include "platform/fonts/shaping/ShapeResultInlineHeaders.h" 10 #include "platform/fonts/shaping/ShapeResultInlineHeaders.h"
11 #include "platform/geometry/FloatPoint.h"
37 #include "platform/text/TextBreakIterator.h" 12 #include "platform/text/TextBreakIterator.h"
13 #include "platform/text/TextDirection.h"
38 14
39 namespace blink { 15 namespace blink {
40 16
41 float ShapeResult::RunInfo::xPositionForVisualOffset(unsigned offset) const 17 namespace {
42 {
43 ASSERT(offset < m_numCharacters);
44 if (rtl())
45 offset = m_numCharacters - offset - 1;
46 return xPositionForOffset(offset);
47 }
48 18
49 float ShapeResult::RunInfo::xPositionForOffset(unsigned offset) const 19 inline void addGlyphToBuffer(GlyphBuffer* glyphBuffer, float advance, hb_directi on_t direction,
50 { 20 const SimpleFontData* fontData, const HarfBuzzRunGlyphData& glyphData)
51 ASSERT(offset <= m_numCharacters);
52 const unsigned numGlyphs = m_glyphData.size();
53 unsigned glyphIndex = 0;
54 float position = 0;
55 if (rtl()) {
56 while (glyphIndex < numGlyphs && m_glyphData[glyphIndex].characterIndex > offset) {
57 position += m_glyphData[glyphIndex].advance;
58 ++glyphIndex;
59 }
60 // For RTL, we need to return the right side boundary of the character.
61 // Add advance of glyphs which are part of the character.
62 while (glyphIndex < numGlyphs - 1 && m_glyphData[glyphIndex].characterIn dex == m_glyphData[glyphIndex + 1].characterIndex) {
63 position += m_glyphData[glyphIndex].advance;
64 ++glyphIndex;
65 }
66 position += m_glyphData[glyphIndex].advance;
67 } else {
68 while (glyphIndex < numGlyphs && m_glyphData[glyphIndex].characterIndex < offset) {
69 position += m_glyphData[glyphIndex].advance;
70 ++glyphIndex;
71 }
72 }
73 return position;
74 }
75
76 int ShapeResult::RunInfo::characterIndexForXPosition(float targetX) const
77 {
78 ASSERT(targetX <= m_width);
79 const unsigned numGlyphs = m_glyphData.size();
80 float currentX = 0;
81 float currentAdvance = m_glyphData[0].advance;
82 unsigned glyphIndex = 0;
83
84 // Sum up advances that belong to the first character.
85 while (glyphIndex < numGlyphs - 1 && m_glyphData[glyphIndex].characterIndex == m_glyphData[glyphIndex + 1].characterIndex)
86 currentAdvance += m_glyphData[++glyphIndex].advance;
87 currentAdvance = currentAdvance / 2.0;
88 if (targetX <= currentAdvance)
89 return rtl() ? m_numCharacters : 0;
90
91 currentX = currentAdvance;
92 ++glyphIndex;
93 while (glyphIndex < numGlyphs) {
94 unsigned prevCharacterIndex = m_glyphData[glyphIndex - 1].characterIndex ;
95 float prevAdvance = currentAdvance;
96 currentAdvance = m_glyphData[glyphIndex].advance;
97 while (glyphIndex < numGlyphs - 1 && m_glyphData[glyphIndex].characterIn dex == m_glyphData[glyphIndex + 1].characterIndex)
98 currentAdvance += m_glyphData[++glyphIndex].advance;
99 currentAdvance = currentAdvance / 2.0;
100 float nextX = currentX + prevAdvance + currentAdvance;
101 if (currentX <= targetX && targetX <= nextX)
102 return rtl() ? prevCharacterIndex : m_glyphData[glyphIndex].characte rIndex;
103 currentX = nextX;
104 ++glyphIndex;
105 }
106
107 return rtl() ? 0 : m_numCharacters;
108 }
109
110 void ShapeResult::RunInfo::setGlyphAndPositions(unsigned index,
111 uint16_t glyphId, float advance, float offsetX, float offsetY)
112 {
113 HarfBuzzRunGlyphData& data = m_glyphData[index];
114 data.glyph = glyphId;
115 data.advance = advance;
116 data.offset = FloatSize(offsetX, offsetY);
117 }
118
119 ShapeResult::ShapeResult(const Font* font, unsigned numCharacters, TextDirection direction)
120 : m_width(0)
121 , m_primaryFont(const_cast<SimpleFontData*>(font->primaryFont()))
122 , m_numCharacters(numCharacters)
123 , m_numGlyphs(0)
124 , m_direction(direction)
125 , m_hasVerticalOffsets(0)
126 {
127 }
128
129 ShapeResult::~ShapeResult()
130 {
131 }
132
133 static inline void addGlyphToBuffer(GlyphBuffer* glyphBuffer, float advance,
134 hb_direction_t direction, const SimpleFontData* fontData,
135 const HarfBuzzRunGlyphData& glyphData)
136 { 21 {
137 FloatPoint startOffset = HB_DIRECTION_IS_HORIZONTAL(direction) 22 FloatPoint startOffset = HB_DIRECTION_IS_HORIZONTAL(direction)
138 ? FloatPoint(advance, 0) 23 ? FloatPoint(advance, 0)
139 : FloatPoint(0, advance); 24 : FloatPoint(0, advance);
140 glyphBuffer->add(glyphData.glyph, fontData, startOffset + glyphData.offset); 25 glyphBuffer->add(glyphData.glyph, fontData, startOffset + glyphData.offset);
141 } 26 }
142 27
28 inline void addEmphasisMark(GlyphBuffer* buffer,
29 const GlyphData* emphasisData, FloatPoint glyphCenter,
30 float midGlyphOffset)
31 {
32 ASSERT(buffer);
33 ASSERT(emphasisData);
34
35 const SimpleFontData* emphasisFontData = emphasisData->fontData;
36 ASSERT(emphasisFontData);
37
38 bool isVertical = emphasisFontData->platformData().isVerticalAnyUpright()
39 && emphasisFontData->verticalData();
40
41 if (!isVertical) {
42 buffer->add(emphasisData->glyph, emphasisFontData,
43 midGlyphOffset - glyphCenter.x());
44 } else {
45 buffer->add(emphasisData->glyph, emphasisFontData,
46 FloatPoint(-glyphCenter.x(), midGlyphOffset - glyphCenter.y()));
47 }
48 }
49
50 inline unsigned countGraphemesInCluster(const UChar* str, unsigned strLength,
51 uint16_t startIndex, uint16_t endIndex)
52 {
53 if (startIndex > endIndex) {
54 uint16_t tempIndex = startIndex;
55 startIndex = endIndex;
56 endIndex = tempIndex;
57 }
58 uint16_t length = endIndex - startIndex;
59 ASSERT(static_cast<unsigned>(startIndex + length) <= strLength);
60 TextBreakIterator* cursorPosIterator = cursorMovementIterator(&str[startInde x], length);
61
62 int cursorPos = cursorPosIterator->current();
63 int numGraphemes = -1;
64 while (0 <= cursorPos) {
65 cursorPos = cursorPosIterator->next();
66 numGraphemes++;
67 }
68 return std::max(0, numGraphemes);
69 }
70
71 } // anonymous namespace
72
143 template<TextDirection direction> 73 template<TextDirection direction>
144 float ShapeResult::fillGlyphBufferForRun(GlyphBuffer* glyphBuffer, 74 float ShapeResultBuffer::fillGlyphBufferForRun(GlyphBuffer* glyphBuffer,
145 const RunInfo* run, float initialAdvance, unsigned from, unsigned to, 75 const ShapeResult::RunInfo* run, float initialAdvance, unsigned from, unsign ed to,
146 unsigned runOffset) 76 unsigned runOffset)
147 { 77 {
148 if (!run) 78 if (!run)
149 return 0; 79 return 0;
150 float advanceSoFar = initialAdvance; 80 float advanceSoFar = initialAdvance;
151 const unsigned numGlyphs = run->m_glyphData.size(); 81 const unsigned numGlyphs = run->m_glyphData.size();
152 for (unsigned i = 0; i < numGlyphs; ++i) { 82 for (unsigned i = 0; i < numGlyphs; ++i) {
153 const HarfBuzzRunGlyphData& glyphData = run->m_glyphData[i]; 83 const HarfBuzzRunGlyphData& glyphData = run->m_glyphData[i];
154 uint16_t currentCharacterIndex = run->m_startIndex + 84 uint16_t currentCharacterIndex = run->m_startIndex +
155 glyphData.characterIndex + runOffset; 85 glyphData.characterIndex + runOffset;
156 if ((direction == RTL && currentCharacterIndex >= to) 86 if ((direction == RTL && currentCharacterIndex >= to)
157 || (direction == LTR && currentCharacterIndex < from)) { 87 || (direction == LTR && currentCharacterIndex < from)) {
158 advanceSoFar += glyphData.advance; 88 advanceSoFar += glyphData.advance;
159 } else if ((direction == RTL && currentCharacterIndex >= from) 89 } else if ((direction == RTL && currentCharacterIndex >= from)
160 || (direction == LTR && currentCharacterIndex < to)) { 90 || (direction == LTR && currentCharacterIndex < to)) {
161 addGlyphToBuffer(glyphBuffer, advanceSoFar, run->m_direction, 91 addGlyphToBuffer(glyphBuffer, advanceSoFar, run->m_direction,
162 run->m_fontData.get(), glyphData); 92 run->m_fontData.get(), glyphData);
163 advanceSoFar += glyphData.advance; 93 advanceSoFar += glyphData.advance;
164 } 94 }
165 } 95 }
166 return advanceSoFar - initialAdvance; 96 return advanceSoFar - initialAdvance;
167 } 97 }
168 98
169 static inline unsigned countGraphemesInCluster(const UChar* str, 99 float ShapeResultBuffer::fillGlyphBufferForTextEmphasisRun(GlyphBuffer* glyphBuf fer,
170 unsigned strLength, uint16_t startIndex, uint16_t endIndex) 100 const ShapeResult::RunInfo* run, const TextRun& textRun, const GlyphData* em phasisData,
171 {
172 if (startIndex > endIndex) {
173 uint16_t tempIndex = startIndex;
174 startIndex = endIndex;
175 endIndex = tempIndex;
176 }
177 uint16_t length = endIndex - startIndex;
178 ASSERT(static_cast<unsigned>(startIndex + length) <= strLength);
179 TextBreakIterator* cursorPosIterator = cursorMovementIterator(&str[startInde x], length);
180
181 int cursorPos = cursorPosIterator->current();
182 int numGraphemes = -1;
183 while (0 <= cursorPos) {
184 cursorPos = cursorPosIterator->next();
185 numGraphemes++;
186 }
187 return std::max(0, numGraphemes);
188 }
189
190 static inline void addEmphasisMark(GlyphBuffer* buffer,
191 const GlyphData* emphasisData, FloatPoint glyphCenter,
192 float midGlyphOffset)
193 {
194 ASSERT(buffer);
195 ASSERT(emphasisData);
196
197 const SimpleFontData* emphasisFontData = emphasisData->fontData;
198 ASSERT(emphasisFontData);
199
200 bool isVertical = emphasisFontData->platformData().isVerticalAnyUpright()
201 && emphasisFontData->verticalData();
202
203 if (!isVertical) {
204 buffer->add(emphasisData->glyph, emphasisFontData,
205 midGlyphOffset - glyphCenter.x());
206 } else {
207 buffer->add(emphasisData->glyph, emphasisFontData,
208 FloatPoint(-glyphCenter.x(), midGlyphOffset - glyphCenter.y()));
209 }
210 }
211
212 float ShapeResult::fillGlyphBufferForTextEmphasisRun(GlyphBuffer* glyphBuffer,
213 const RunInfo* run, const TextRun& textRun, const GlyphData* emphasisData,
214 float initialAdvance, unsigned from, unsigned to, unsigned runOffset) 101 float initialAdvance, unsigned from, unsigned to, unsigned runOffset)
215 { 102 {
216 if (!run) 103 if (!run)
217 return 0; 104 return 0;
218 105
219 unsigned graphemesInCluster = 1; 106 unsigned graphemesInCluster = 1;
220 float clusterAdvance = 0; 107 float clusterAdvance = 0;
221 108
222 FloatPoint glyphCenter = emphasisData->fontData-> 109 FloatPoint glyphCenter = emphasisData->fontData->
223 boundsForGlyph(emphasisData->glyph).center(); 110 boundsForGlyph(emphasisData->glyph).center();
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 addEmphasisMark(glyphBuffer, emphasisData, glyphCenter, adva nceSoFar + glyphAdvanceX / 2); 162 addEmphasisMark(glyphBuffer, emphasisData, glyphCenter, adva nceSoFar + glyphAdvanceX / 2);
276 advanceSoFar += glyphAdvanceX; 163 advanceSoFar += glyphAdvanceX;
277 } 164 }
278 clusterStart = clusterEnd; 165 clusterStart = clusterEnd;
279 clusterAdvance = 0; 166 clusterAdvance = 0;
280 } 167 }
281 } 168 }
282 return advanceSoFar - initialAdvance; 169 return advanceSoFar - initialAdvance;
283 } 170 }
284 171
285 float ShapeResult::fillFastHorizontalGlyphBuffer(const ShapeResultBuffer& result sBuffer, 172 float ShapeResultBuffer::fillFastHorizontalGlyphBuffer(GlyphBuffer* glyphBuffer,
286 GlyphBuffer* glyphBuffer, TextDirection dir) 173 TextDirection dir) const
287 { 174 {
288 ASSERT(!resultsBuffer.hasVerticalOffsets()); 175 ASSERT(!hasVerticalOffsets());
289 176
290 const auto& results = resultsBuffer.results();
291 float advance = 0; 177 float advance = 0;
292 178
293 for (unsigned i = 0; i < results.size(); ++i) { 179 for (unsigned i = 0; i < m_results.size(); ++i) {
294 const auto& wordResult = 180 const auto& wordResult =
295 isLeftToRightDirection(dir) ? results[i] : results[results.size() - 1 - i]; 181 isLeftToRightDirection(dir) ? m_results[i] : m_results[m_results.siz e() - 1 - i];
296 ASSERT(!wordResult->hasVerticalOffsets()); 182 ASSERT(!wordResult->hasVerticalOffsets());
297 183
298 for (const auto& run : wordResult->m_runs) { 184 for (const auto& run : wordResult->m_runs) {
299 ASSERT(run); 185 ASSERT(run);
300 ASSERT(HB_DIRECTION_IS_HORIZONTAL(run->m_direction)); 186 ASSERT(HB_DIRECTION_IS_HORIZONTAL(run->m_direction));
301 187
302 for (const auto& glyphData : run->m_glyphData) { 188 for (const auto& glyphData : run->m_glyphData) {
303 ASSERT(!glyphData.offset.height()); 189 ASSERT(!glyphData.offset.height());
304 190
305 glyphBuffer->add(glyphData.glyph, run->m_fontData.get(), 191 glyphBuffer->add(glyphData.glyph, run->m_fontData.get(),
306 advance + glyphData.offset.width()); 192 advance + glyphData.offset.width());
307 advance += glyphData.advance; 193 advance += glyphData.advance;
308 } 194 }
309 } 195 }
310 } 196 }
311 197
312 ASSERT(!glyphBuffer->hasVerticalOffsets()); 198 ASSERT(!glyphBuffer->hasVerticalOffsets());
313 199
314 return advance; 200 return advance;
315 } 201 }
316 202
317 float ShapeResult::fillGlyphBuffer(const ShapeResultBuffer& resultsBuffer, 203 float ShapeResultBuffer::fillGlyphBuffer(GlyphBuffer* glyphBuffer, const TextRun & textRun,
318 GlyphBuffer* glyphBuffer, const TextRun& textRun, 204 unsigned from, unsigned to) const
319 unsigned from, unsigned to)
320 { 205 {
321 // Fast path: full run with no vertical offsets 206 // Fast path: full run with no vertical offsets
322 if (!from && to == static_cast<unsigned>(textRun.length()) && !resultsBuffer .hasVerticalOffsets()) 207 if (!from && to == static_cast<unsigned>(textRun.length()) && !hasVerticalOf fsets())
323 return fillFastHorizontalGlyphBuffer(resultsBuffer, glyphBuffer, textRun .direction()); 208 return fillFastHorizontalGlyphBuffer(glyphBuffer, textRun.direction());
324 209
325 const auto& results = resultsBuffer.results();
326 float advance = 0; 210 float advance = 0;
327 211
328 if (textRun.rtl()) { 212 if (textRun.rtl()) {
329 unsigned wordOffset = textRun.length(); 213 unsigned wordOffset = textRun.length();
330 for (unsigned j = 0; j < results.size(); j++) { 214 for (unsigned j = 0; j < m_results.size(); j++) {
331 unsigned resolvedIndex = results.size() - 1 - j; 215 unsigned resolvedIndex = m_results.size() - 1 - j;
332 const RefPtr<ShapeResult>& wordResult = results[resolvedIndex]; 216 const RefPtr<ShapeResult>& wordResult = m_results[resolvedIndex];
333 for (unsigned i = 0; i < wordResult->m_runs.size(); i++) { 217 for (unsigned i = 0; i < wordResult->m_runs.size(); i++) {
334 advance += wordResult->fillGlyphBufferForRun<RTL>(glyphBuffer, 218 advance += fillGlyphBufferForRun<RTL>(glyphBuffer,
335 wordResult->m_runs[i].get(), advance, from, to, 219 wordResult->m_runs[i].get(), advance, from, to,
336 wordOffset - wordResult->numCharacters()); 220 wordOffset - wordResult->numCharacters());
337 } 221 }
338 wordOffset -= wordResult->numCharacters(); 222 wordOffset -= wordResult->numCharacters();
339 } 223 }
340 } else { 224 } else {
341 unsigned wordOffset = 0; 225 unsigned wordOffset = 0;
342 for (unsigned j = 0; j < results.size(); j++) { 226 for (unsigned j = 0; j < m_results.size(); j++) {
343 const RefPtr<ShapeResult>& wordResult = results[j]; 227 const RefPtr<ShapeResult>& wordResult = m_results[j];
344 for (unsigned i = 0; i < wordResult->m_runs.size(); i++) { 228 for (unsigned i = 0; i < wordResult->m_runs.size(); i++) {
345 advance += wordResult->fillGlyphBufferForRun<LTR>(glyphBuffer, 229 advance += fillGlyphBufferForRun<LTR>(glyphBuffer,
346 wordResult->m_runs[i].get(), advance, from, to, wordOffset); 230 wordResult->m_runs[i].get(), advance, from, to, wordOffset);
347 } 231 }
348 wordOffset += wordResult->numCharacters(); 232 wordOffset += wordResult->numCharacters();
349 } 233 }
350 } 234 }
351 235
352 return advance; 236 return advance;
353 } 237 }
354 238
355 float ShapeResult::fillGlyphBufferForTextEmphasis(const ShapeResultBuffer& resul tsBuffer, 239 float ShapeResultBuffer::fillGlyphBufferForTextEmphasis(GlyphBuffer* glyphBuffer ,
356 GlyphBuffer* glyphBuffer, const TextRun& textRun, const GlyphData* emphasisD ata, 240 const TextRun& textRun, const GlyphData* emphasisData, unsigned from, unsign ed to) const
357 unsigned from, unsigned to)
358 { 241 {
359 const auto& results = resultsBuffer.results();
360 float advance = 0; 242 float advance = 0;
361 unsigned wordOffset = textRun.rtl() ? textRun.length() : 0; 243 unsigned wordOffset = textRun.rtl() ? textRun.length() : 0;
362 244
363 for (unsigned j = 0; j < results.size(); j++) { 245 for (unsigned j = 0; j < m_results.size(); j++) {
364 unsigned resolvedIndex = textRun.rtl() ? results.size() - 1 - j : j; 246 unsigned resolvedIndex = textRun.rtl() ? m_results.size() - 1 - j : j;
365 const RefPtr<ShapeResult>& wordResult = results[resolvedIndex]; 247 const RefPtr<ShapeResult>& wordResult = m_results[resolvedIndex];
366 for (unsigned i = 0; i < wordResult->m_runs.size(); i++) { 248 for (unsigned i = 0; i < wordResult->m_runs.size(); i++) {
367 unsigned resolvedOffset = wordOffset - 249 unsigned resolvedOffset = wordOffset -
368 (textRun.rtl() ? wordResult->numCharacters() : 0); 250 (textRun.rtl() ? wordResult->numCharacters() : 0);
369 advance += wordResult->fillGlyphBufferForTextEmphasisRun( 251 advance += fillGlyphBufferForTextEmphasisRun(
370 glyphBuffer, wordResult->m_runs[i].get(), textRun, emphasisData, 252 glyphBuffer, wordResult->m_runs[i].get(), textRun, emphasisData,
371 advance, from, to, resolvedOffset); 253 advance, from, to, resolvedOffset);
372 } 254 }
373 wordOffset += wordResult->numCharacters() * (textRun.rtl() ? -1 : 1); 255 wordOffset += wordResult->numCharacters() * (textRun.rtl() ? -1 : 1);
374 } 256 }
375 257
376 return advance; 258 return advance;
377 } 259 }
378 260
379 FloatRect ShapeResult::selectionRect(const ShapeResultBuffer& resultsBuffer, 261 FloatRect ShapeResultBuffer::selectionRect(TextDirection direction, float totalW idth,
380 TextDirection direction, float totalWidth, const FloatPoint& point, 262 const FloatPoint& point, int height, unsigned absoluteFrom, unsigned absolut eTo) const
381 int height, unsigned absoluteFrom, unsigned absoluteTo)
382 { 263 {
383 const auto& results = resultsBuffer.results();
384 float currentX = 0; 264 float currentX = 0;
385 float fromX = 0; 265 float fromX = 0;
386 float toX = 0; 266 float toX = 0;
387 bool foundFromX = false; 267 bool foundFromX = false;
388 bool foundToX = false; 268 bool foundToX = false;
389 269
390 if (direction == RTL) 270 if (direction == RTL)
391 currentX = totalWidth; 271 currentX = totalWidth;
392 272
393 // The absoluteFrom and absoluteTo arguments represent the start/end offset 273 // The absoluteFrom and absoluteTo arguments represent the start/end offset
394 // for the entire run, from/to are continuously updated to be relative to 274 // for the entire run, from/to are continuously updated to be relative to
395 // the current word (ShapeResult instance). 275 // the current word (ShapeResult instance).
396 int from = absoluteFrom; 276 int from = absoluteFrom;
397 int to = absoluteTo; 277 int to = absoluteTo;
398 278
399 unsigned totalNumCharacters = 0; 279 unsigned totalNumCharacters = 0;
400 for (unsigned j = 0; j < results.size(); j++) { 280 for (unsigned j = 0; j < m_results.size(); j++) {
401 const RefPtr<ShapeResult> result = results[j]; 281 const RefPtr<ShapeResult> result = m_results[j];
402 if (direction == RTL) { 282 if (direction == RTL) {
403 // Convert logical offsets to visual offsets, because results are in 283 // Convert logical offsets to visual offsets, because results are in
404 // logical order while runs are in visual order. 284 // logical order while runs are in visual order.
405 if (!foundFromX && from >= 0 && static_cast<unsigned>(from) < result ->numCharacters()) 285 if (!foundFromX && from >= 0 && static_cast<unsigned>(from) < result ->numCharacters())
406 from = result->numCharacters() - from - 1; 286 from = result->numCharacters() - from - 1;
407 if (!foundToX && to >= 0 && static_cast<unsigned>(to) < result->numC haracters()) 287 if (!foundToX && to >= 0 && static_cast<unsigned>(to) < result->numC haracters())
408 to = result->numCharacters() - to - 1; 288 to = result->numCharacters() - to - 1;
409 currentX -= result->width(); 289 currentX -= result->width();
410 } 290 }
411 for (unsigned i = 0; i < result->m_runs.size(); i++) { 291 for (unsigned i = 0; i < result->m_runs.size(); i++) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 toX = direction == RTL ? 0 : totalWidth; 331 toX = direction == RTL ? 0 : totalWidth;
452 332
453 // None of our runs is part of the selection, possibly invalid arguments. 333 // None of our runs is part of the selection, possibly invalid arguments.
454 if (!foundToX && !foundFromX) 334 if (!foundToX && !foundFromX)
455 fromX = toX = 0; 335 fromX = toX = 0;
456 if (fromX < toX) 336 if (fromX < toX)
457 return FloatRect(point.x() + fromX, point.y(), toX - fromX, height); 337 return FloatRect(point.x() + fromX, point.y(), toX - fromX, height);
458 return FloatRect(point.x() + toX, point.y(), fromX - toX, height); 338 return FloatRect(point.x() + toX, point.y(), fromX - toX, height);
459 } 339 }
460 340
461 size_t ShapeResult::byteSize() 341 int ShapeResultBuffer::offsetForPosition(const TextRun& run, float targetX) cons t
462 { 342 {
463 size_t selfByteSize = sizeof(this);
464 for (unsigned i = 0; i < m_runs.size(); ++i) {
465 selfByteSize += m_runs[i]->byteSize();
466 }
467 return selfByteSize;
468 }
469
470 int ShapeResult::offsetForPosition(const ShapeResultBuffer& resultsBuffer,
471 const TextRun& run, float targetX)
472 {
473 const auto& results = resultsBuffer.results();
474 unsigned totalOffset; 343 unsigned totalOffset;
475 if (run.rtl()) { 344 if (run.rtl()) {
476 totalOffset = run.length(); 345 totalOffset = run.length();
477 for (unsigned i = results.size(); i; --i) { 346 for (unsigned i = m_results.size(); i; --i) {
478 const RefPtr<ShapeResult>& wordResult = results[i - 1]; 347 const RefPtr<ShapeResult>& wordResult = m_results[i - 1];
479 if (!wordResult) 348 if (!wordResult)
480 continue; 349 continue;
481 totalOffset -= wordResult->numCharacters(); 350 totalOffset -= wordResult->numCharacters();
482 if (targetX >= 0 && targetX <= wordResult->width()) { 351 if (targetX >= 0 && targetX <= wordResult->width()) {
483 int offsetForWord = wordResult->offsetForPosition(targetX); 352 int offsetForWord = wordResult->offsetForPosition(targetX);
484 return totalOffset + offsetForWord; 353 return totalOffset + offsetForWord;
485 } 354 }
486 targetX -= wordResult->width(); 355 targetX -= wordResult->width();
487 } 356 }
488 } else { 357 } else {
489 totalOffset = 0; 358 totalOffset = 0;
490 for (const auto& wordResult : results) { 359 for (const auto& wordResult : m_results) {
491 if (!wordResult) 360 if (!wordResult)
492 continue; 361 continue;
493 int offsetForWord = wordResult->offsetForPosition(targetX); 362 int offsetForWord = wordResult->offsetForPosition(targetX);
494 ASSERT(offsetForWord >= 0); 363 ASSERT(offsetForWord >= 0);
495 totalOffset += offsetForWord; 364 totalOffset += offsetForWord;
496 if (targetX >= 0 && targetX <= wordResult->width()) 365 if (targetX >= 0 && targetX <= wordResult->width())
497 return totalOffset; 366 return totalOffset;
498 targetX -= wordResult->width(); 367 targetX -= wordResult->width();
499 } 368 }
500 } 369 }
501 return totalOffset; 370 return totalOffset;
502 } 371 }
503 372
504 int ShapeResult::offsetForPosition(float targetX)
505 {
506 int charactersSoFar = 0;
507 float currentX = 0;
508
509 if (m_direction == RTL) {
510 charactersSoFar = m_numCharacters;
511 for (unsigned i = 0; i < m_runs.size(); ++i) {
512 if (!m_runs[i])
513 continue;
514 charactersSoFar -= m_runs[i]->m_numCharacters;
515 float nextX = currentX + m_runs[i]->m_width;
516 float offsetForRun = targetX - currentX;
517 if (offsetForRun >= 0 && offsetForRun <= m_runs[i]->m_width) {
518 // The x value in question is within this script run.
519 const unsigned index = m_runs[i]->characterIndexForXPosition(off setForRun);
520 return charactersSoFar + index;
521 }
522 currentX = nextX;
523 }
524 } else {
525 for (unsigned i = 0; i < m_runs.size(); ++i) {
526 if (!m_runs[i])
527 continue;
528 float nextX = currentX + m_runs[i]->m_width;
529 float offsetForRun = targetX - currentX;
530 if (offsetForRun >= 0 && offsetForRun <= m_runs[i]->m_width) {
531 const unsigned index = m_runs[i]->characterIndexForXPosition(off setForRun);
532 return charactersSoFar + index;
533 }
534 charactersSoFar += m_runs[i]->m_numCharacters;
535 currentX = nextX;
536 }
537 }
538
539 return charactersSoFar;
540 }
541
542 void ShapeResult::fallbackFonts(HashSet<const SimpleFontData*>* fallback) const
543 {
544 ASSERT(fallback);
545 ASSERT(m_primaryFont);
546 for (unsigned i = 0; i < m_runs.size(); ++i) {
547 if (m_runs[i] && m_runs[i]->m_fontData != m_primaryFont
548 && !m_runs[i]->m_fontData->isTextOrientationFallbackOf(m_primaryFont .get())) {
549 fallback->add(m_runs[i]->m_fontData.get());
550 }
551 }
552 }
553
554 } // namespace blink 373 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698