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

Side by Side Diff: third_party/WebKit/Source/core/layout/svg/SVGTextQuery.cpp

Issue 1773353003: Use precomputed text metrics instead of recomputing them in SVGTextQuery (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Minor cleanup and english fixes Created 4 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
« no previous file with comments | « third_party/WebKit/LayoutTests/svg/text/lengthAdjust-text-metrics-expected.txt ('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 /*
2 * Copyright (C) Research In Motion Limited 2010-2012. All rights reserved. 2 * Copyright (C) Research In Motion Limited 2010-2012. All rights reserved.
3 * 3 *
4 * This library is free software; you can redistribute it and/or 4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public 5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either 6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version. 7 * version 2 of the License, or (at your option) any later version.
8 * 8 *
9 * This library is distributed in the hope that it will be useful, 9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 return false; 249 return false;
250 } 250 }
251 251
252 float SVGTextQuery::textLength() const 252 float SVGTextQuery::textLength() const
253 { 253 {
254 TextLengthData data; 254 TextLengthData data;
255 logicalQuery(m_queryRootLayoutObject, &data, textLengthCallback); 255 logicalQuery(m_queryRootLayoutObject, &data, textLengthCallback);
256 return data.textLength; 256 return data.textLength;
257 } 257 }
258 258
259 const SVGTextMetrics& findMetricsForCharacter(const Vector<SVGTextMetrics>& text MetricsValues, const SVGTextFragment& fragment, unsigned startInFragment)
260 {
261 // Find the text metrics cell that starts at or contains the character at |s tartInFragment|.
262 unsigned textMetricsOffset = fragment.metricsListOffset;
263 unsigned fragmentOffset = 0;
264 while (fragmentOffset < fragment.length) {
265 const SVGTextMetrics& metrics = textMetricsValues[textMetricsOffset++];
266 unsigned glyphEnd = fragmentOffset + metrics.length();
267 if (startInFragment < glyphEnd)
268 break;
269 fragmentOffset = glyphEnd;
270 }
271 return textMetricsValues[textMetricsOffset - 1];
272 }
273
274 static float calculateGlyphRange(const QueryData* queryData, const SVGTextFragme nt& fragment, unsigned start, unsigned end)
275 {
276 float glyphRange = 0;
277 if (end <= start)
fs 2016/03/09 09:55:42 Nit: I believe this should be uncommon enough here
pdr. 2016/03/09 19:13:50 SGTM, done.
278 return glyphRange;
279
280 const Vector<SVGTextMetrics>& textMetricsValues = queryData->textLineLayout. layoutAttributes()->textMetricsValues();
281 for (unsigned character = start; character < end; character++) {
282 SVGTextMetrics metrics = findMetricsForCharacter(textMetricsValues, frag ment, character);
fs 2016/03/09 09:55:42 Nit: const SVGTextMetrics&
pdr. 2016/03/09 19:13:50 Done.
283 glyphRange += queryData->isVerticalText ? metrics.height() : metrics.wid th();
284 }
285 return glyphRange;
286 }
287
259 // subStringLength() implementation 288 // subStringLength() implementation
260 struct SubStringLengthData : QueryData { 289 struct SubStringLengthData : QueryData {
261 SubStringLengthData(unsigned queryStartPosition, unsigned queryLength) 290 SubStringLengthData(unsigned queryStartPosition, unsigned queryLength)
262 : startPosition(queryStartPosition) 291 : startPosition(queryStartPosition)
263 , length(queryLength) 292 , length(queryLength)
264 , subStringLength(0) 293 , subStringLength(0)
265 { 294 {
266 } 295 }
267 296
268 unsigned startPosition; 297 unsigned startPosition;
269 unsigned length; 298 unsigned length;
270 299
271 float subStringLength; 300 float subStringLength;
272 }; 301 };
273 302
274 static bool subStringLengthCallback(QueryData* queryData, const SVGTextFragment& fragment) 303 static bool subStringLengthCallback(QueryData* queryData, const SVGTextFragment& fragment)
275 { 304 {
276 SubStringLengthData* data = static_cast<SubStringLengthData*>(queryData); 305 SubStringLengthData* data = static_cast<SubStringLengthData*>(queryData);
277 306
278 int startPosition = data->startPosition; 307 int startPosition = data->startPosition;
279 int endPosition = startPosition + data->length; 308 int endPosition = startPosition + data->length;
280 if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startP osition, endPosition)) 309 if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startP osition, endPosition))
281 return false; 310 return false;
282 311
283 SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->te xtLineLayout, fragment.characterOffset + startPosition, endPosition - startPosit ion, queryData->textBox->direction()); 312 data->subStringLength += calculateGlyphRange(queryData, fragment, startPosit ion, endPosition);
284 data->subStringLength += queryData->isVerticalText ? metrics.height() : metr ics.width();
285 return false; 313 return false;
286 } 314 }
287 315
288 float SVGTextQuery::subStringLength(unsigned startPosition, unsigned length) con st 316 float SVGTextQuery::subStringLength(unsigned startPosition, unsigned length) con st
289 { 317 {
290 SubStringLengthData data(startPosition, length); 318 SubStringLengthData data(startPosition, length);
291 logicalQuery(m_queryRootLayoutObject, &data, subStringLengthCallback); 319 logicalQuery(m_queryRootLayoutObject, &data, subStringLengthCallback);
292 return data.subStringLength; 320 return data.subStringLength;
293 } 321 }
294 322
295 // startPositionOfCharacter() implementation 323 // startPositionOfCharacter() implementation
296 struct StartPositionOfCharacterData : QueryData { 324 struct StartPositionOfCharacterData : QueryData {
297 StartPositionOfCharacterData(unsigned queryPosition) 325 StartPositionOfCharacterData(unsigned queryPosition)
298 : position(queryPosition) 326 : position(queryPosition)
299 { 327 {
300 } 328 }
301 329
302 unsigned position; 330 unsigned position;
303 FloatPoint startPosition; 331 FloatPoint startPosition;
304 }; 332 };
305 333
306 static FloatPoint calculateGlyphPositionWithoutTransform(const QueryData* queryD ata, const SVGTextFragment& fragment, int offsetInFragment) 334 static FloatPoint calculateGlyphPositionWithoutTransform(const QueryData* queryD ata, const SVGTextFragment& fragment, int offsetInFragment)
307 { 335 {
308 float glyphOffsetInDirection = 0; 336 float glyphOffsetInDirection = calculateGlyphRange(queryData, fragment, 0, o ffsetInFragment);
309 if (offsetInFragment) {
310 SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData ->textLineLayout, fragment.characterOffset, offsetInFragment, queryData->textBox ->direction());
311 if (queryData->isVerticalText)
312 glyphOffsetInDirection = metrics.height();
313 else
314 glyphOffsetInDirection = metrics.width();
315 }
316 337
317 if (!queryData->textBox->isLeftToRightDirection()) { 338 if (!queryData->textBox->isLeftToRightDirection()) {
318 float fragmentExtent = queryData->isVerticalText ? fragment.height : fra gment.width; 339 float fragmentExtent = queryData->isVerticalText ? fragment.height : fra gment.width;
319 glyphOffsetInDirection = fragmentExtent - glyphOffsetInDirection; 340 glyphOffsetInDirection = fragmentExtent - glyphOffsetInDirection;
320 } 341 }
321 342
322 FloatPoint glyphPosition(fragment.x, fragment.y); 343 FloatPoint glyphPosition(fragment.x, fragment.y);
323 if (queryData->isVerticalText) 344 if (queryData->isVerticalText)
324 glyphPosition.move(0, glyphOffsetInDirection); 345 glyphPosition.move(0, glyphOffsetInDirection);
325 else 346 else
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 struct ExtentOfCharacterData : QueryData { 455 struct ExtentOfCharacterData : QueryData {
435 ExtentOfCharacterData(unsigned queryPosition) 456 ExtentOfCharacterData(unsigned queryPosition)
436 : position(queryPosition) 457 : position(queryPosition)
437 { 458 {
438 } 459 }
439 460
440 unsigned position; 461 unsigned position;
441 FloatRect extent; 462 FloatRect extent;
442 }; 463 };
443 464
444 const SVGTextMetrics& findMetricsForCharacter(const Vector<SVGTextMetrics>& text MetricsValues, const SVGTextFragment& fragment, unsigned startInFragment)
445 {
446 // Find the text metrics cell that start at or contain the character at |sta rtInFragment|.
447 unsigned textMetricsOffset = fragment.metricsListOffset;
448 unsigned fragmentOffset = 0;
449 while (fragmentOffset < fragment.length) {
450 const SVGTextMetrics& metrics = textMetricsValues[textMetricsOffset++];
451 unsigned glyphEnd = fragmentOffset + metrics.length();
452 if (startInFragment < glyphEnd)
453 break;
454 fragmentOffset = glyphEnd;
455 }
456 return textMetricsValues[textMetricsOffset - 1];
457 }
458
459 static inline void calculateGlyphBoundaries(const QueryData* queryData, const SV GTextFragment& fragment, int startPosition, FloatRect& extent) 465 static inline void calculateGlyphBoundaries(const QueryData* queryData, const SV GTextFragment& fragment, int startPosition, FloatRect& extent)
460 { 466 {
461 float scalingFactor = queryData->textLineLayout.scalingFactor(); 467 float scalingFactor = queryData->textLineLayout.scalingFactor();
462 ASSERT(scalingFactor); 468 ASSERT(scalingFactor);
463 469
464 FloatPoint glyphPosition = calculateGlyphPositionWithoutTransform(queryData, fragment, startPosition); 470 FloatPoint glyphPosition = calculateGlyphPositionWithoutTransform(queryData, fragment, startPosition);
465 glyphPosition.move(0, -queryData->textLineLayout.scaledFont().fontMetrics(). floatAscent() / scalingFactor); 471 glyphPosition.move(0, -queryData->textLineLayout.scaledFont().fontMetrics(). floatAscent() / scalingFactor);
466 extent.setLocation(glyphPosition); 472 extent.setLocation(glyphPosition);
467 473
468 // Use the SVGTextMetrics computed by SVGTextMetricsBuilder (which spends 474 // Use the SVGTextMetrics computed by SVGTextMetricsBuilder (which spends
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 } 608 }
603 609
604 int SVGTextQuery::characterNumberAtPosition(const FloatPoint& position) const 610 int SVGTextQuery::characterNumberAtPosition(const FloatPoint& position) const
605 { 611 {
606 CharacterNumberAtPositionData data(position); 612 CharacterNumberAtPositionData data(position);
607 spatialQuery(m_queryRootLayoutObject, &data, characterNumberAtPositionCallba ck); 613 spatialQuery(m_queryRootLayoutObject, &data, characterNumberAtPositionCallba ck);
608 return data.characterNumberWithin(m_queryRootLayoutObject); 614 return data.characterNumberWithin(m_queryRootLayoutObject);
609 } 615 }
610 616
611 } // namespace blink 617 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/svg/text/lengthAdjust-text-metrics-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698