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

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

Issue 1883553004: Refactor the current text position update in SVGTextLayoutEngine (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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) 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 20 matching lines...) Expand all
31 #include "core/svg/SVGLengthContext.h" 31 #include "core/svg/SVGLengthContext.h"
32 #include "core/svg/SVGTextContentElement.h" 32 #include "core/svg/SVGTextContentElement.h"
33 33
34 namespace blink { 34 namespace blink {
35 35
36 SVGTextLayoutEngine::SVGTextLayoutEngine(Vector<SVGTextLayoutAttributes*>& layou tAttributes) 36 SVGTextLayoutEngine::SVGTextLayoutEngine(Vector<SVGTextLayoutAttributes*>& layou tAttributes)
37 : m_layoutAttributes(layoutAttributes) 37 : m_layoutAttributes(layoutAttributes)
38 , m_layoutAttributesPosition(0) 38 , m_layoutAttributesPosition(0)
39 , m_logicalCharacterOffset(0) 39 , m_logicalCharacterOffset(0)
40 , m_logicalMetricsListOffset(0) 40 , m_logicalMetricsListOffset(0)
41 , m_x(0)
42 , m_y(0)
43 , m_dx(0)
44 , m_dy(0)
45 , m_isVerticalText(false) 41 , m_isVerticalText(false)
46 , m_inPathLayout(false) 42 , m_inPathLayout(false)
47 , m_textLengthSpacingInEffect(false) 43 , m_textLengthSpacingInEffect(false)
48 , m_textPath(nullptr) 44 , m_textPath(nullptr)
49 , m_textPathCurrentOffset(0) 45 , m_textPathCurrentOffset(0)
46 , m_textPathDisplacement(0)
50 , m_textPathSpacing(0) 47 , m_textPathSpacing(0)
51 , m_textPathScaling(1) 48 , m_textPathScaling(1)
52 { 49 {
53 ASSERT(!m_layoutAttributes.isEmpty()); 50 ASSERT(!m_layoutAttributes.isEmpty());
54 } 51 }
55 52
56 SVGTextLayoutEngine::~SVGTextLayoutEngine() = default; 53 SVGTextLayoutEngine::~SVGTextLayoutEngine() = default;
57 54
58 void SVGTextLayoutEngine::updateCharacterPositionIfNeeded(float& x, float& y) 55 bool SVGTextLayoutEngine::setCurrentTextPositionIfNeeded(const SVGCharacterData& data)
59 { 56 {
60 if (m_inPathLayout) 57 bool hasX = !SVGTextLayoutAttributes::isEmptyValue(data.x);
61 return; 58 if (hasX)
59 m_ctp.setX(data.x);
62 60
63 // Replace characters x/y position, with the current text position plus any 61 bool hasY = !SVGTextLayoutAttributes::isEmptyValue(data.y);
64 // relative adjustments, if it doesn't specify an absolute position itself. 62 if (hasY)
65 if (SVGTextLayoutAttributes::isEmptyValue(x)) 63 m_ctp.setY(data.y);
66 x = m_x + m_dx;
67 64
68 if (SVGTextLayoutAttributes::isEmptyValue(y)) 65 // If there's an absolute x/y position available, it marks the beginning of
69 y = m_y + m_dy; 66 // a new position along the path.
70 67 if (m_inPathLayout) {
71 m_dx = 0; 68 // TODO(fs): If a new chunk (== absolute position) is defined while in
72 m_dy = 0; 69 // path layout mode, alignment should be based on that chunk and not
70 // the path as a whole. (Re: the addition of m_textPathStartOffset
71 // below.)
72 if (m_isVerticalText) {
73 if (hasY)
74 m_textPathCurrentOffset = data.y + m_textPathStartOffset;
75 } else {
76 if (hasX)
77 m_textPathCurrentOffset = data.x + m_textPathStartOffset;
78 }
79 }
80 return hasX || hasY;
73 } 81 }
74 82
75 void SVGTextLayoutEngine::updateCurrentTextPosition(float x, float y, float glyp hAdvance) 83 void SVGTextLayoutEngine::advanceCurrentTextPosition(float glyphAdvance)
76 { 84 {
77 // Update current text position after processing the character. 85 // TODO(fs): m_textPathCurrentOffset should preferably also be updated
78 if (m_isVerticalText) { 86 // here, but that requires a bit more untangling yet.
79 m_x = x; 87 if (m_isVerticalText)
80 m_y = y + glyphAdvance; 88 m_ctp.setY(m_ctp.y() + glyphAdvance);
81 } else { 89 else
82 m_x = x + glyphAdvance; 90 m_ctp.setX(m_ctp.x() + glyphAdvance);
83 m_y = y;
84 }
85 } 91 }
86 92
87 void SVGTextLayoutEngine::updateRelativePositionAdjustmentsIfNeeded(float dx, fl oat dy) 93 bool SVGTextLayoutEngine::applyRelativePositionAdjustmentsIfNeeded(const SVGChar acterData& data)
88 { 94 {
89 // Update relative positioning information. 95 FloatPoint delta;
90 if (SVGTextLayoutAttributes::isEmptyValue(dx) && SVGTextLayoutAttributes::is EmptyValue(dy)) 96 bool hasDx = !SVGTextLayoutAttributes::isEmptyValue(data.dx);
91 return; 97 if (hasDx)
98 delta.setX(data.dx);
92 99
93 if (SVGTextLayoutAttributes::isEmptyValue(dx)) 100 bool hasDy = !SVGTextLayoutAttributes::isEmptyValue(data.dy);
94 dx = 0; 101 if (hasDy)
95 if (SVGTextLayoutAttributes::isEmptyValue(dy)) 102 delta.setY(data.dy);
96 dy = 0; 103
104 // Apply dx/dy value adjustments to current text position, if needed.
105 m_ctp.moveBy(delta);
97 106
98 if (m_inPathLayout) { 107 if (m_inPathLayout) {
99 if (m_isVerticalText) { 108 if (m_isVerticalText)
100 m_dx += dx; 109 delta = delta.transposedPoint();
101 m_dy = dy;
102 } else {
103 m_dx = dx;
104 m_dy += dy;
105 }
106 110
107 return; 111 m_textPathCurrentOffset += delta.x();
112 m_textPathDisplacement += delta.y();
108 } 113 }
109 114 return hasDx || hasDy;
110 m_dx = dx;
111 m_dy = dy;
112 } 115 }
113 116
114 void SVGTextLayoutEngine::computeCurrentFragmentMetrics(SVGInlineTextBox* textBo x) 117 void SVGTextLayoutEngine::computeCurrentFragmentMetrics(SVGInlineTextBox* textBo x)
115 { 118 {
116 LineLayoutSVGInlineText textLineLayout = LineLayoutSVGInlineText(textBox->ge tLineLayoutItem()); 119 LineLayoutSVGInlineText textLineLayout = LineLayoutSVGInlineText(textBox->ge tLineLayoutItem());
117 TextRun run = textBox->constructTextRun(textLineLayout.styleRef(), m_current TextFragment); 120 TextRun run = textBox->constructTextRun(textLineLayout.styleRef(), m_current TextFragment);
118 121
119 float scalingFactor = textLineLayout.scalingFactor(); 122 float scalingFactor = textLineLayout.scalingFactor();
120 ASSERT(scalingFactor); 123 ASSERT(scalingFactor);
121 const Font& scaledFont = textLineLayout.scaledFont(); 124 const Font& scaledFont = textLineLayout.scaledFont();
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 // Find the start of the current text box in the metrics list. 341 // Find the start of the current text box in the metrics list.
339 m_visualMetricsIterator.advanceToTextStart(textLineLayout, textBox->start()) ; 342 m_visualMetricsIterator.advanceToTextStart(textLineLayout, textBox->start()) ;
340 343
341 const Font& font = style.font(); 344 const Font& font = style.font();
342 345
343 SVGTextLayoutEngineSpacing spacingLayout(font, style.effectiveZoom()); 346 SVGTextLayoutEngineSpacing spacingLayout(font, style.effectiveZoom());
344 SVGTextLayoutEngineBaseline baselineLayout(font, style.effectiveZoom()); 347 SVGTextLayoutEngineBaseline baselineLayout(font, style.effectiveZoom());
345 348
346 bool didStartTextFragment = false; 349 bool didStartTextFragment = false;
347 bool applySpacingToNextCharacter = false; 350 bool applySpacingToNextCharacter = false;
351 bool needsFragmentPerGlyph = m_isVerticalText || m_inPathLayout || m_textLen gthSpacingInEffect;
348 352
349 float lastAngle = 0; 353 float lastAngle = 0;
350 float baselineShift = baselineLayout.calculateBaselineShift(style); 354 float baselineShiftValue = baselineLayout.calculateBaselineShift(style);
351 baselineShift -= baselineLayout.calculateAlignmentBaselineShift(m_isVertical Text, textLineLayout); 355 baselineShiftValue -= baselineLayout.calculateAlignmentBaselineShift(m_isVer ticalText, textLineLayout);
356 FloatPoint baselineShift;
357 if (m_isVerticalText)
358 baselineShift.setX(baselineShiftValue);
359 else
360 baselineShift.setY(-baselineShiftValue);
352 361
353 // Main layout algorithm. 362 // Main layout algorithm.
354 const unsigned boxEndOffset = textBox->start() + textBox->len(); 363 const unsigned boxEndOffset = textBox->start() + textBox->len();
355 while (!m_visualMetricsIterator.isAtEnd() && m_visualMetricsIterator.charact erOffset() < boxEndOffset) { 364 while (!m_visualMetricsIterator.isAtEnd() && m_visualMetricsIterator.charact erOffset() < boxEndOffset) {
356 const SVGTextMetrics& visualMetrics = m_visualMetricsIterator.metrics(); 365 const SVGTextMetrics& visualMetrics = m_visualMetricsIterator.metrics();
357 if (visualMetrics.isEmpty()) { 366 if (visualMetrics.isEmpty()) {
358 m_visualMetricsIterator.next(); 367 m_visualMetricsIterator.next();
359 continue; 368 continue;
360 } 369 }
361 370
362 SVGTextLayoutAttributes* logicalAttributes = nullptr; 371 SVGTextLayoutAttributes* logicalAttributes = nullptr;
363 if (!currentLogicalCharacterAttributes(logicalAttributes)) 372 if (!currentLogicalCharacterAttributes(logicalAttributes))
364 break; 373 break;
365 374
366 ASSERT(logicalAttributes); 375 ASSERT(logicalAttributes);
367 SVGTextMetrics logicalMetrics(SVGTextMetrics::SkippedSpaceMetrics); 376 SVGTextMetrics logicalMetrics(SVGTextMetrics::SkippedSpaceMetrics);
368 if (!currentLogicalCharacterMetrics(logicalAttributes, logicalMetrics)) 377 if (!currentLogicalCharacterMetrics(logicalAttributes, logicalMetrics))
369 break; 378 break;
370 379
371 SVGCharacterDataMap& characterDataMap = logicalAttributes->characterData Map(); 380 SVGCharacterDataMap& characterDataMap = logicalAttributes->characterData Map();
372 SVGCharacterData data; 381 SVGCharacterData data;
373 SVGCharacterDataMap::iterator it = characterDataMap.find(m_logicalCharac terOffset + 1); 382 SVGCharacterDataMap::iterator it = characterDataMap.find(m_logicalCharac terOffset + 1);
374 if (it != characterDataMap.end()) 383 if (it != characterDataMap.end())
375 data = it->value; 384 data = it->value;
376 385
377 float x = data.x; 386 // TODO(fs): Use the return value to eliminate the additional
378 float y = data.y; 387 // hash-lookup below when determining if this text box should be tagged
388 // as starting a new text chunk.
389 setCurrentTextPositionIfNeeded(data);
379 390
380 // When we've advanced to the box start offset, determine using the orig inal x/y values, 391 // When we've advanced to the box start offset, determine using the orig inal x/y values,
pdr. 2016/04/14 01:05:51 This code is sandwiched between setCurrentTextPosi
fs 2016/04/14 08:56:42 As I tried to note in the TODO above, I intend for
381 // whether this character starts a new text chunk, before doing any furt her processing. 392 // whether this character starts a new text chunk, before doing any furt her processing.
382 if (m_visualMetricsIterator.characterOffset() == textBox->start()) 393 if (m_visualMetricsIterator.characterOffset() == textBox->start())
383 textBox->setStartsNewTextChunk(logicalAttributes->context()->charact erStartsNewTextChunk(m_logicalCharacterOffset)); 394 textBox->setStartsNewTextChunk(logicalAttributes->context()->charact erStartsNewTextChunk(m_logicalCharacterOffset));
384 395
385 float angle = SVGTextLayoutAttributes::isEmptyValue(data.rotate) ? 0 : d ata.rotate; 396 bool hasRelativePosition = applyRelativePositionAdjustmentsIfNeeded(data );
386 397
387 // Calculate glyph orientation angle. 398 // Determine the orientation of the current glyph.
388 // Font::width() calculates the resolved FontOrientation for each charac ter, 399 // Font::width() calculates the resolved FontOrientation for each charac ter,
389 // but is not exposed today to avoid the API complexity. 400 // but that value is not exposed today to avoid the API complexity.
390 UChar32 currentCharacter = textLineLayout.codepointAt(m_visualMetricsIte rator.characterOffset()); 401 UChar32 currentCharacter = textLineLayout.codepointAt(m_visualMetricsIte rator.characterOffset());
391 FontOrientation fontOrientation = font.getFontDescription().orientation( ); 402 FontOrientation fontOrientation = font.getFontDescription().orientation( );
392 fontOrientation = adjustOrientationForCharacterInMixedVertical(fontOrien tation, currentCharacter); 403 fontOrientation = adjustOrientationForCharacterInMixedVertical(fontOrien tation, currentCharacter);
393 404
394 // Calculate glyph advance. 405 // Calculate glyph advance.
395 // Shaping engine takes care of x/y orientation shifts for different fon tOrientation values. 406 // The shaping engine takes care of x/y orientation shifts for different fontOrientation values.
396 float glyphAdvance = visualMetrics.advance(fontOrientation); 407 float glyphAdvance = visualMetrics.advance(fontOrientation);
397 408
398 // Assign current text position to x/y values, if needed. 409 // Calculate CSS 'letter-spacing' and 'word-spacing' for the character, if needed.
399 updateCharacterPositionIfNeeded(x, y);
400
401 // Apply dx/dy value adjustments to current text position, if needed.
402 updateRelativePositionAdjustmentsIfNeeded(data.dx, data.dy);
403
404 // Calculate CSS 'letter-spacing' and 'word-spacing' for next character, if needed.
405 float spacing = spacingLayout.calculateCSSSpacing(currentCharacter); 410 float spacing = spacingLayout.calculateCSSSpacing(currentCharacter);
406 411
407 float textPathShiftX = 0; 412 FloatPoint textPathShift;
408 float textPathShiftY = 0; 413 float angle = 0;
414 FloatPoint position;
409 if (m_inPathLayout) { 415 if (m_inPathLayout) {
410 float scaledGlyphAdvance = glyphAdvance * m_textPathScaling; 416 float scaledGlyphAdvance = glyphAdvance * m_textPathScaling;
411 if (m_isVerticalText) { 417 // Setup translations that move to the glyph midpoint.
412 // If there's an absolute y position available, it marks the beg inning of a new position along the path. 418 textPathShift.set(-scaledGlyphAdvance / 2, m_textPathDisplacement);
413 if (!SVGTextLayoutAttributes::isEmptyValue(y)) 419 if (m_isVerticalText)
414 m_textPathCurrentOffset = y + m_textPathStartOffset; 420 textPathShift = textPathShift.transposedPoint();
415 421 textPathShift += baselineShift;
416 m_textPathCurrentOffset += m_dy;
417 m_dy = 0;
418
419 // Apply dx/dy correction and setup translations that move to th e glyph midpoint.
420 textPathShiftX += m_dx + baselineShift;
421 textPathShiftY -= scaledGlyphAdvance / 2;
422 } else {
423 // If there's an absolute x position available, it marks the beg inning of a new position along the path.
424 if (!SVGTextLayoutAttributes::isEmptyValue(x))
425 m_textPathCurrentOffset = x + m_textPathStartOffset;
426
427 m_textPathCurrentOffset += m_dx;
428 m_dx = 0;
429
430 // Apply dx/dy correction and setup translations that move to th e glyph midpoint.
431 textPathShiftX -= scaledGlyphAdvance / 2;
432 textPathShiftY += m_dy - baselineShift;
433 }
434 422
435 // Calculate current offset along path. 423 // Calculate current offset along path.
436 float textPathOffset = m_textPathCurrentOffset + scaledGlyphAdvance / 2; 424 float textPathOffset = m_textPathCurrentOffset + scaledGlyphAdvance / 2;
437 425
438 // Move to next character. 426 // Move to next character.
439 m_textPathCurrentOffset += scaledGlyphAdvance + m_textPathSpacing + spacing * m_textPathScaling; 427 m_textPathCurrentOffset += scaledGlyphAdvance + m_textPathSpacing + spacing * m_textPathScaling;
440 428
441 FloatPoint point; 429 PathPositionMapper::PositionType positionType = m_textPath->pointAnd NormalAtLength(textPathOffset, position, angle);
442 PathPositionMapper::PositionType positionType = m_textPath->pointAnd NormalAtLength(textPathOffset, point, angle);
443 430
444 // Skip character, if we're before the path. 431 // Skip character, if we're before the path.
445 if (positionType == PathPositionMapper::BeforePath) { 432 if (positionType == PathPositionMapper::BeforePath) {
446 advanceToNextLogicalCharacter(logicalMetrics); 433 advanceToNextLogicalCharacter(logicalMetrics);
447 m_visualMetricsIterator.next(); 434 m_visualMetricsIterator.next();
448 continue; 435 continue;
449 } 436 }
450 437
451 // Stop processing if the next character lies behind the path. 438 // Stop processing if the next character lies behind the path.
452 if (positionType == PathPositionMapper::AfterPath) 439 if (positionType == PathPositionMapper::AfterPath)
453 break; 440 break;
454 441
455 x = point.x();
456 y = point.y();
457
458 // For vertical text on path, the actual angle has to be rotated 90 degrees anti-clockwise, not the orientation angle! 442 // For vertical text on path, the actual angle has to be rotated 90 degrees anti-clockwise, not the orientation angle!
459 if (m_isVerticalText) 443 if (m_isVerticalText)
460 angle -= 90; 444 angle -= 90;
461 } else { 445 } else {
462 // Apply all previously calculated shift values. 446 position = m_ctp;
463 if (m_isVerticalText) 447 position += baselineShift;
464 x += baselineShift;
465 else
466 y -= baselineShift;
467
468 x += m_dx;
469 y += m_dy;
470 } 448 }
471 449
450 if (!SVGTextLayoutAttributes::isEmptyValue(data.rotate))
451 angle += data.rotate;
452
472 // Determine whether we have to start a new fragment. 453 // Determine whether we have to start a new fragment.
473 bool shouldStartNewFragment = m_dx || m_dy || m_isVerticalText || m_inPa thLayout || angle || angle != lastAngle 454 bool shouldStartNewFragment = needsFragmentPerGlyph || hasRelativePositi on
474 || applySpacingToNextCharacter || m_textLengthSpacingInEffect; 455 || angle || angle != lastAngle || applySpacingToNextCharacter;
475 456
476 // If we already started a fragment, close it now. 457 // If we already started a fragment, close it now.
477 if (didStartTextFragment && shouldStartNewFragment) { 458 if (didStartTextFragment && shouldStartNewFragment) {
478 applySpacingToNextCharacter = false; 459 applySpacingToNextCharacter = false;
479 recordTextFragment(textBox); 460 recordTextFragment(textBox);
480 } 461 }
481 462
482 // Eventually start a new fragment, if not yet done. 463 // Eventually start a new fragment, if not yet done.
483 if (!didStartTextFragment || shouldStartNewFragment) { 464 if (!didStartTextFragment || shouldStartNewFragment) {
484 ASSERT(!m_currentTextFragment.characterOffset); 465 ASSERT(!m_currentTextFragment.characterOffset);
485 ASSERT(!m_currentTextFragment.length); 466 ASSERT(!m_currentTextFragment.length);
486 467
487 didStartTextFragment = true; 468 didStartTextFragment = true;
488 m_currentTextFragment.characterOffset = m_visualMetricsIterator.char acterOffset(); 469 m_currentTextFragment.characterOffset = m_visualMetricsIterator.char acterOffset();
489 m_currentTextFragment.metricsListOffset = m_visualMetricsIterator.me tricsListOffset(); 470 m_currentTextFragment.metricsListOffset = m_visualMetricsIterator.me tricsListOffset();
490 m_currentTextFragment.x = x; 471 m_currentTextFragment.x = position.x();
491 m_currentTextFragment.y = y; 472 m_currentTextFragment.y = position.y();
492 473
493 // Build fragment transformation. 474 // Build fragment transformation.
494 if (angle) 475 if (angle)
495 m_currentTextFragment.transform.rotate(angle); 476 m_currentTextFragment.transform.rotate(angle);
496 477
497 if (textPathShiftX || textPathShiftY) 478 if (textPathShift.x() || textPathShift.y())
498 m_currentTextFragment.transform.translate(textPathShiftX, textPa thShiftY); 479 m_currentTextFragment.transform.translate(textPathShift.x(), tex tPathShift.y());
499 480
500 // In vertical text, always rotate by 90 degrees regardless of fontO rientation. 481 // For vertical text, always rotate by 90 degrees regardless of font Orientation.
501 // Shaping engine takes care of the necessary orientation. 482 // The shaping engine takes care of the necessary orientation.
502 if (m_isVerticalText) 483 if (m_isVerticalText)
503 m_currentTextFragment.transform.rotate(90); 484 m_currentTextFragment.transform.rotate(90);
504 485
505 m_currentTextFragment.isVertical = m_isVerticalText; 486 m_currentTextFragment.isVertical = m_isVerticalText;
506 m_currentTextFragment.isTextOnPath = m_inPathLayout && m_textPathSca ling != 1; 487 m_currentTextFragment.isTextOnPath = m_inPathLayout && m_textPathSca ling != 1;
507 if (m_currentTextFragment.isTextOnPath) 488 if (m_currentTextFragment.isTextOnPath)
508 m_currentTextFragment.lengthAdjustScale = m_textPathScaling; 489 m_currentTextFragment.lengthAdjustScale = m_textPathScaling;
509 } 490 }
510 491
511 // Update current text position, after processing of the current charact er finished. 492 // Advance current text position after processing of the current charact er finished.
512 if (m_inPathLayout) { 493 advanceCurrentTextPosition(glyphAdvance + spacing);
513 updateCurrentTextPosition(x, y, glyphAdvance);
514 } else {
515 // Apply CSS 'kerning', 'letter-spacing' and 'word-spacing' to next character, if needed.
516 if (spacing)
517 applySpacingToNextCharacter = true;
518 494
519 float xNew = x - m_dx; 495 // Apply CSS 'letter-spacing' and 'word-spacing' to the next character, if needed.
520 float yNew = y - m_dy; 496 if (!m_inPathLayout && spacing)
521 497 applySpacingToNextCharacter = true;
522 if (m_isVerticalText)
523 xNew -= baselineShift;
524 else
525 yNew += baselineShift;
526
527 updateCurrentTextPosition(xNew, yNew, glyphAdvance + spacing);
528 }
529 498
530 advanceToNextLogicalCharacter(logicalMetrics); 499 advanceToNextLogicalCharacter(logicalMetrics);
531 m_visualMetricsIterator.next(); 500 m_visualMetricsIterator.next();
532 lastAngle = angle; 501 lastAngle = angle;
533 } 502 }
534 503
535 if (!didStartTextFragment) 504 if (!didStartTextFragment)
536 return; 505 return;
537 506
538 // Close last open fragment, if needed. 507 // Close last open fragment, if needed.
539 recordTextFragment(textBox); 508 recordTextFragment(textBox);
540 } 509 }
541 510
542 } // namespace blink 511 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698