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

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

Issue 1160623002: Avoid resetting the metrics-list/character offset for each text box (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 6 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 | Annotate | Revision Log
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 21 matching lines...) Expand all
32 // Set to a value > 0 to dump the text fragments 32 // Set to a value > 0 to dump the text fragments
33 #define DUMP_TEXT_FRAGMENTS 0 33 #define DUMP_TEXT_FRAGMENTS 0
34 34
35 namespace blink { 35 namespace blink {
36 36
37 SVGTextLayoutEngine::SVGTextLayoutEngine(Vector<SVGTextLayoutAttributes*>& layou tAttributes) 37 SVGTextLayoutEngine::SVGTextLayoutEngine(Vector<SVGTextLayoutAttributes*>& layou tAttributes)
38 : m_layoutAttributes(layoutAttributes) 38 : m_layoutAttributes(layoutAttributes)
39 , m_layoutAttributesPosition(0) 39 , m_layoutAttributesPosition(0)
40 , m_logicalCharacterOffset(0) 40 , m_logicalCharacterOffset(0)
41 , m_logicalMetricsListOffset(0) 41 , m_logicalMetricsListOffset(0)
42 , m_visualCharacterOffset(0)
43 , m_visualMetricsListOffset(0)
44 , m_x(0) 42 , m_x(0)
45 , m_y(0) 43 , m_y(0)
46 , m_dx(0) 44 , m_dx(0)
47 , m_dy(0) 45 , m_dy(0)
48 , m_isVerticalText(false) 46 , m_isVerticalText(false)
49 , m_inPathLayout(false) 47 , m_inPathLayout(false)
50 , m_textPathCalculator(0) 48 , m_textPathCalculator(0)
51 , m_textPathLength(0) 49 , m_textPathLength(0)
52 , m_textPathCurrentOffset(0) 50 , m_textPathCurrentOffset(0)
53 , m_textPathSpacing(0) 51 , m_textPathSpacing(0)
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 m_dy += dy; 103 m_dy += dy;
106 } 104 }
107 105
108 return; 106 return;
109 } 107 }
110 108
111 m_dx = dx; 109 m_dx = dx;
112 m_dy = dy; 110 m_dy = dy;
113 } 111 }
114 112
115 void SVGTextLayoutEngine::recordTextFragment(SVGInlineTextBox* textBox, const Ve ctor<SVGTextMetrics>& textMetricsValues) 113 void SVGTextLayoutEngine::recordTextFragment(SVGInlineTextBox* textBox)
116 { 114 {
117 ASSERT(!m_currentTextFragment.length); 115 ASSERT(!m_currentTextFragment.length);
118 ASSERT(m_visualMetricsListOffset > 0);
119 116
120 // Figure out length of fragment. 117 // Figure out length of fragment.
121 m_currentTextFragment.length = m_visualCharacterOffset - m_currentTextFragme nt.characterOffset; 118 m_currentTextFragment.length = m_visualMetricsIterator.characterOffset() - m _currentTextFragment.characterOffset;
122 119
123 // Figure out fragment metrics. 120 // Figure out fragment metrics.
124 const SVGTextMetrics& lastCharacterMetrics = textMetricsValues.at(m_visualMe tricsListOffset - 1); 121 const unsigned visualMetricsListOffset = m_visualMetricsIterator.metricsList Offset();
122 const Vector<SVGTextMetrics>& textMetricsValues = m_visualMetricsIterator.me tricsList();
123 const SVGTextMetrics& lastCharacterMetrics = textMetricsValues.at(visualMetr icsListOffset - 1);
125 m_currentTextFragment.width = lastCharacterMetrics.width(); 124 m_currentTextFragment.width = lastCharacterMetrics.width();
126 m_currentTextFragment.height = lastCharacterMetrics.height(); 125 m_currentTextFragment.height = lastCharacterMetrics.height();
127 126
128 if (m_currentTextFragment.length > 1) { 127 if (m_currentTextFragment.length > 1) {
129 // SVGTextLayoutAttributesBuilder assures that the length of the range i s equal to the sum of the individual lengths of the glyphs. 128 // SVGTextLayoutAttributesBuilder assures that the length of the range i s equal to the sum of the individual lengths of the glyphs.
130 float length = 0; 129 float length = 0;
131 if (m_isVerticalText) { 130 if (m_isVerticalText) {
132 for (unsigned i = m_currentTextFragment.metricsListOffset; i < m_vis ualMetricsListOffset; ++i) 131 for (unsigned i = m_currentTextFragment.metricsListOffset; i < visua lMetricsListOffset; ++i)
133 length += textMetricsValues.at(i).height(); 132 length += textMetricsValues.at(i).height();
134 m_currentTextFragment.height = length; 133 m_currentTextFragment.height = length;
135 } else { 134 } else {
136 for (unsigned i = m_currentTextFragment.metricsListOffset; i < m_vis ualMetricsListOffset; ++i) 135 for (unsigned i = m_currentTextFragment.metricsListOffset; i < visua lMetricsListOffset; ++i)
137 length += textMetricsValues.at(i).width(); 136 length += textMetricsValues.at(i).width();
138 m_currentTextFragment.width = length; 137 m_currentTextFragment.width = length;
139 } 138 }
140 } 139 }
141 140
142 textBox->textFragments().append(m_currentTextFragment); 141 textBox->textFragments().append(m_currentTextFragment);
143 m_currentTextFragment = SVGTextFragment(); 142 m_currentTextFragment = SVGTextFragment();
144 } 143 }
145 144
146 bool SVGTextLayoutEngine::parentDefinesTextLength(LayoutObject* parent) const 145 bool SVGTextLayoutEngine::parentDefinesTextLength(LayoutObject* parent) const
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 unsigned fragmentCount = fragments.size(); 300 unsigned fragmentCount = fragments.size();
302 for (unsigned i = 0; i < fragmentCount; ++i) { 301 for (unsigned i = 0; i < fragmentCount; ++i) {
303 ASSERT(fragments[i].lengthAdjustTransform.isIdentity()); 302 ASSERT(fragments[i].lengthAdjustTransform.isIdentity());
304 fragments[i].lengthAdjustTransform = textBoxTransformation; 303 fragments[i].lengthAdjustTransform = textBoxTransformation;
305 } 304 }
306 } 305 }
307 306
308 boxes.clear(); 307 boxes.clear();
309 } 308 }
310 309
311 void SVGTextLayoutEngine::finishLayout() 310 void SVGTextLayoutEngine::finishLayout()
pdr. 2015/05/27 03:11:18 m_metricsList feels like a use after free waiting
fs 2015/05/27 12:53:13 I'm not too worried about life-times myself - if t
312 { 311 {
313 // After all text fragments are stored in their correpsonding SVGInlineTextB oxes, we can layout individual text chunks. 312 // After all text fragments are stored in their correpsonding SVGInlineTextB oxes, we can layout individual text chunks.
314 // Chunk layouting is only performed for line layout boxes, not for path lay out, where it has already been done. 313 // Chunk layouting is only performed for line layout boxes, not for path lay out, where it has already been done.
315 m_chunkLayoutBuilder.layoutTextChunks(m_lineLayoutBoxes); 314 m_chunkLayoutBuilder.layoutTextChunks(m_lineLayoutBoxes);
316 315
317 // Finalize transform matrices, after the chunk layout corrections have been applied, and all fragment x/y positions are finalized. 316 // Finalize transform matrices, after the chunk layout corrections have been applied, and all fragment x/y positions are finalized.
318 if (!m_lineLayoutBoxes.isEmpty()) { 317 if (!m_lineLayoutBoxes.isEmpty()) {
319 #if DUMP_TEXT_FRAGMENTS > 0 318 #if DUMP_TEXT_FRAGMENTS > 0
320 fprintf(stderr, "Line layout: "); 319 fprintf(stderr, "Line layout: ");
321 dumpTextBoxes(m_lineLayoutBoxes); 320 dumpTextBoxes(m_lineLayoutBoxes);
322 #endif 321 #endif
323 322
324 finalizeTransformMatrices(m_lineLayoutBoxes); 323 finalizeTransformMatrices(m_lineLayoutBoxes);
325 } 324 }
326 325
327 if (!m_pathLayoutBoxes.isEmpty()) { 326 if (!m_pathLayoutBoxes.isEmpty()) {
328 #if DUMP_TEXT_FRAGMENTS > 0 327 #if DUMP_TEXT_FRAGMENTS > 0
329 fprintf(stderr, "Path layout: "); 328 fprintf(stderr, "Path layout: ");
330 dumpTextBoxes(m_pathLayoutBoxes); 329 dumpTextBoxes(m_pathLayoutBoxes);
331 #endif 330 #endif
332 331
333 finalizeTransformMatrices(m_pathLayoutBoxes); 332 finalizeTransformMatrices(m_pathLayoutBoxes);
334 } 333 }
335 } 334 }
336 335
336 void SVGTextLayoutEngine::updateMetricsIterator(const LayoutSVGInlineText& textL ayoutObject, unsigned startCharacterOffset)
337 {
338 const Vector<SVGTextMetrics>* metricsList = &textLayoutObject.layoutAttribut es()->textMetricsValues();
f(malita) 2015/05/27 01:53:49 Let's keep the prev ASSERT(!metricsList->isEmpty()
fs 2015/05/27 12:53:13 Added.
339 if (&m_visualMetricsIterator.metricsList() != metricsList)
pdr. 2015/05/27 03:11:18 Instead of relying on the metrics list address, ca
fs 2015/05/27 12:53:13 Done, except I left the "Visual" part out (it's co
340 m_visualMetricsIterator.reset(metricsList);
341
342 if (m_visualMetricsIterator.characterOffset() == startCharacterOffset)
343 return;
344
345 // TODO(fs): We could walk backwards through the metrics list in these cases .
346 if (m_visualMetricsIterator.characterOffset() > startCharacterOffset)
347 m_visualMetricsIterator.reset(metricsList);
348
349 while (m_visualMetricsIterator.characterOffset() < startCharacterOffset)
350 m_visualMetricsIterator.next();
351 }
352
337 bool SVGTextLayoutEngine::currentLogicalCharacterAttributes(SVGTextLayoutAttribu tes*& logicalAttributes) 353 bool SVGTextLayoutEngine::currentLogicalCharacterAttributes(SVGTextLayoutAttribu tes*& logicalAttributes)
338 { 354 {
339 if (m_layoutAttributesPosition == m_layoutAttributes.size()) 355 if (m_layoutAttributesPosition == m_layoutAttributes.size())
340 return false; 356 return false;
341 357
342 logicalAttributes = m_layoutAttributes[m_layoutAttributesPosition]; 358 logicalAttributes = m_layoutAttributes[m_layoutAttributesPosition];
343 ASSERT(logicalAttributes); 359 ASSERT(logicalAttributes);
344 360
345 if (m_logicalCharacterOffset != logicalAttributes->context()->textLength()) 361 if (m_logicalCharacterOffset != logicalAttributes->context()->textLength())
346 return true; 362 return true;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 } 394 }
379 395
380 // Stop if we found the next valid logical text metrics object. 396 // Stop if we found the next valid logical text metrics object.
381 return true; 397 return true;
382 } 398 }
383 399
384 ASSERT_NOT_REACHED(); 400 ASSERT_NOT_REACHED();
385 return true; 401 return true;
386 } 402 }
387 403
388 bool SVGTextLayoutEngine::currentVisualCharacterMetrics(SVGInlineTextBox* textBo x, const Vector<SVGTextMetrics>& visualMetricsValues, SVGTextMetrics& visualMetr ics)
389 {
390 ASSERT(!visualMetricsValues.isEmpty());
391 unsigned textMetricsSize = visualMetricsValues.size();
392 unsigned boxStart = textBox->start();
393 unsigned boxLength = textBox->len();
394
395 while (m_visualMetricsListOffset < textMetricsSize) {
396 // Advance to text box start location.
397 if (m_visualCharacterOffset < boxStart) {
398 advanceToNextVisualCharacter(visualMetricsValues[m_visualMetricsList Offset]);
399 continue;
400 }
401
402 // Stop if we've finished processing this text box.
403 if (m_visualCharacterOffset >= boxStart + boxLength)
404 return false;
405
406 visualMetrics = visualMetricsValues[m_visualMetricsListOffset];
407 return true;
408 }
409
410 return false;
411 }
412
413 void SVGTextLayoutEngine::advanceToNextLogicalCharacter(const SVGTextMetrics& lo gicalMetrics) 404 void SVGTextLayoutEngine::advanceToNextLogicalCharacter(const SVGTextMetrics& lo gicalMetrics)
414 { 405 {
415 ++m_logicalMetricsListOffset; 406 ++m_logicalMetricsListOffset;
416 m_logicalCharacterOffset += logicalMetrics.length(); 407 m_logicalCharacterOffset += logicalMetrics.length();
417 } 408 }
418 409
419 void SVGTextLayoutEngine::advanceToNextVisualCharacter(const SVGTextMetrics& vis ualMetrics)
420 {
421 ++m_visualMetricsListOffset;
422 m_visualCharacterOffset += visualMetrics.length();
423 }
424
425 void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, cons t LayoutSVGInlineText& text, const ComputedStyle& style) 410 void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, cons t LayoutSVGInlineText& text, const ComputedStyle& style)
426 { 411 {
427 if (m_inPathLayout && !m_textPathCalculator) 412 if (m_inPathLayout && !m_textPathCalculator)
428 return; 413 return;
429 414
430 LayoutObject* textParent = text.parent(); 415 LayoutObject* textParent = text.parent();
431 bool definesTextLength = textParent ? parentDefinesTextLength(textParent) : false; 416 bool definesTextLength = textParent ? parentDefinesTextLength(textParent) : false;
432 417
433 const SVGComputedStyle& svgStyle = style.svgStyle(); 418 const SVGComputedStyle& svgStyle = style.svgStyle();
434 419
435 m_visualMetricsListOffset = 0; 420 // Find the start of the current text box in the metrics list.
436 m_visualCharacterOffset = 0; 421 updateMetricsIterator(text, textBox->start());
pdr. 2015/05/27 03:11:18 Do you think something like m_visualMetricsIterato
fs 2015/05/27 12:53:13 Done.
437
438 const Vector<SVGTextMetrics>& visualMetricsValues = text.layoutAttributes()- >textMetricsValues();
439 ASSERT(!visualMetricsValues.isEmpty());
440 422
441 const Font& font = style.font(); 423 const Font& font = style.font();
442 424
443 SVGTextLayoutEngineSpacing spacingLayout(font, style.effectiveZoom()); 425 SVGTextLayoutEngineSpacing spacingLayout(font, style.effectiveZoom());
444 SVGTextLayoutEngineBaseline baselineLayout(font, style.effectiveZoom()); 426 SVGTextLayoutEngineBaseline baselineLayout(font, style.effectiveZoom());
445 427
446 bool didStartTextFragment = false; 428 bool didStartTextFragment = false;
447 bool applySpacingToNextCharacter = false; 429 bool applySpacingToNextCharacter = false;
448 430
449 float lastAngle = 0; 431 float lastAngle = 0;
450 float baselineShift = baselineLayout.calculateBaselineShift(style); 432 float baselineShift = baselineLayout.calculateBaselineShift(style);
451 baselineShift -= baselineLayout.calculateAlignmentBaselineShift(m_isVertical Text, &text); 433 baselineShift -= baselineLayout.calculateAlignmentBaselineShift(m_isVertical Text, &text);
452 434
453 // Main layout algorithm. 435 // Main layout algorithm.
454 while (true) { 436 const unsigned boxEndOffset = textBox->start() + textBox->len();
455 // Find the start of the current text box in this list, respecting ligat ures. 437 while (m_visualMetricsIterator.characterOffset() < boxEndOffset) {
456 SVGTextMetrics visualMetrics(SVGTextMetrics::SkippedSpaceMetrics); 438 const SVGTextMetrics& visualMetrics = m_visualMetricsIterator.metrics();
457 if (!currentVisualCharacterMetrics(textBox, visualMetricsValues, visualM etrics))
458 break;
459
460 if (visualMetrics.isEmpty()) { 439 if (visualMetrics.isEmpty()) {
461 advanceToNextVisualCharacter(visualMetrics); 440 m_visualMetricsIterator.next();
462 continue; 441 continue;
463 } 442 }
464 443
465 SVGTextLayoutAttributes* logicalAttributes = 0; 444 SVGTextLayoutAttributes* logicalAttributes = 0;
466 if (!currentLogicalCharacterAttributes(logicalAttributes)) 445 if (!currentLogicalCharacterAttributes(logicalAttributes))
467 break; 446 break;
468 447
469 ASSERT(logicalAttributes); 448 ASSERT(logicalAttributes);
470 SVGTextMetrics logicalMetrics(SVGTextMetrics::SkippedSpaceMetrics); 449 SVGTextMetrics logicalMetrics(SVGTextMetrics::SkippedSpaceMetrics);
471 if (!currentLogicalCharacterMetrics(logicalAttributes, logicalMetrics)) 450 if (!currentLogicalCharacterMetrics(logicalAttributes, logicalMetrics))
472 break; 451 break;
473 452
474 SVGCharacterDataMap& characterDataMap = logicalAttributes->characterData Map(); 453 SVGCharacterDataMap& characterDataMap = logicalAttributes->characterData Map();
475 SVGCharacterData data; 454 SVGCharacterData data;
476 SVGCharacterDataMap::iterator it = characterDataMap.find(m_logicalCharac terOffset + 1); 455 SVGCharacterDataMap::iterator it = characterDataMap.find(m_logicalCharac terOffset + 1);
477 if (it != characterDataMap.end()) 456 if (it != characterDataMap.end())
478 data = it->value; 457 data = it->value;
479 458
480 float x = data.x; 459 float x = data.x;
481 float y = data.y; 460 float y = data.y;
482 461
483 // When we've advanced to the box start offset, determine using the orig inal x/y values, 462 // When we've advanced to the box start offset, determine using the orig inal x/y values,
484 // whether this character starts a new text chunk, before doing any furt her processing. 463 // whether this character starts a new text chunk, before doing any furt her processing.
485 if (m_visualCharacterOffset == textBox->start()) 464 if (m_visualMetricsIterator.characterOffset() == textBox->start())
486 textBox->setStartsNewTextChunk(logicalAttributes->context()->charact erStartsNewTextChunk(m_logicalCharacterOffset)); 465 textBox->setStartsNewTextChunk(logicalAttributes->context()->charact erStartsNewTextChunk(m_logicalCharacterOffset));
487 466
488 float angle = SVGTextLayoutAttributes::isEmptyValue(data.rotate) ? 0 : d ata.rotate; 467 float angle = SVGTextLayoutAttributes::isEmptyValue(data.rotate) ? 0 : d ata.rotate;
489 468
490 // Calculate glyph orientation angle. 469 // Calculate glyph orientation angle.
491 UChar currentCharacter = text.characterAt(m_visualCharacterOffset); 470 UChar currentCharacter = text.characterAt(m_visualMetricsIterator.charac terOffset());
492 float orientationAngle = baselineLayout.calculateGlyphOrientationAngle(m _isVerticalText, svgStyle, currentCharacter); 471 float orientationAngle = baselineLayout.calculateGlyphOrientationAngle(m _isVerticalText, svgStyle, currentCharacter);
493 472
494 // Calculate glyph advance & x/y orientation shifts. 473 // Calculate glyph advance & x/y orientation shifts.
495 float xOrientationShift = 0; 474 float xOrientationShift = 0;
496 float yOrientationShift = 0; 475 float yOrientationShift = 0;
497 float glyphAdvance = baselineLayout.calculateGlyphAdvanceAndOrientation( m_isVerticalText, visualMetrics, orientationAngle, xOrientationShift, yOrientati onShift); 476 float glyphAdvance = baselineLayout.calculateGlyphAdvanceAndOrientation( m_isVerticalText, visualMetrics, orientationAngle, xOrientationShift, yOrientati onShift);
498 477
499 // Assign current text position to x/y values, if needed. 478 // Assign current text position to x/y values, if needed.
500 updateCharacterPositionIfNeeded(x, y); 479 updateCharacterPositionIfNeeded(x, y);
501 480
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 513
535 // Calculate current offset along path. 514 // Calculate current offset along path.
536 textPathOffset = m_textPathCurrentOffset + scaledGlyphAdvance / 2; 515 textPathOffset = m_textPathCurrentOffset + scaledGlyphAdvance / 2;
537 516
538 // Move to next character. 517 // Move to next character.
539 m_textPathCurrentOffset += scaledGlyphAdvance + m_textPathSpacing + spacing * m_textPathScaling; 518 m_textPathCurrentOffset += scaledGlyphAdvance + m_textPathSpacing + spacing * m_textPathScaling;
540 519
541 // Skip character, if we're before the path. 520 // Skip character, if we're before the path.
542 if (textPathOffset < 0) { 521 if (textPathOffset < 0) {
543 advanceToNextLogicalCharacter(logicalMetrics); 522 advanceToNextLogicalCharacter(logicalMetrics);
544 advanceToNextVisualCharacter(visualMetrics); 523 m_visualMetricsIterator.next();
545 continue; 524 continue;
546 } 525 }
547 526
548 // Stop processing, if the next character lies behind the path. 527 // Stop processing, if the next character lies behind the path.
549 if (textPathOffset > m_textPathLength) 528 if (textPathOffset > m_textPathLength)
550 break; 529 break;
551 530
552 FloatPoint point; 531 FloatPoint point;
553 bool ok = m_textPathCalculator->pointAndNormalAtLength(textPathOffse t, point, angle); 532 bool ok = m_textPathCalculator->pointAndNormalAtLength(textPathOffse t, point, angle);
554 ASSERT_UNUSED(ok, ok); 533 ASSERT_UNUSED(ok, ok);
(...skipping 14 matching lines...) Expand all
569 y += m_dy; 548 y += m_dy;
570 } 549 }
571 550
572 // Determine whether we have to start a new fragment. 551 // Determine whether we have to start a new fragment.
573 bool shouldStartNewFragment = m_dx || m_dy || m_isVerticalText || m_inPa thLayout || angle || angle != lastAngle 552 bool shouldStartNewFragment = m_dx || m_dy || m_isVerticalText || m_inPa thLayout || angle || angle != lastAngle
574 || orientationAngle || applySpacingToNextCharacter || definesTextLen gth; 553 || orientationAngle || applySpacingToNextCharacter || definesTextLen gth;
575 554
576 // If we already started a fragment, close it now. 555 // If we already started a fragment, close it now.
577 if (didStartTextFragment && shouldStartNewFragment) { 556 if (didStartTextFragment && shouldStartNewFragment) {
578 applySpacingToNextCharacter = false; 557 applySpacingToNextCharacter = false;
579 recordTextFragment(textBox, visualMetricsValues); 558 recordTextFragment(textBox);
580 } 559 }
581 560
582 // Eventually start a new fragment, if not yet done. 561 // Eventually start a new fragment, if not yet done.
583 if (!didStartTextFragment || shouldStartNewFragment) { 562 if (!didStartTextFragment || shouldStartNewFragment) {
584 ASSERT(!m_currentTextFragment.characterOffset); 563 ASSERT(!m_currentTextFragment.characterOffset);
585 ASSERT(!m_currentTextFragment.length); 564 ASSERT(!m_currentTextFragment.length);
586 565
587 didStartTextFragment = true; 566 didStartTextFragment = true;
588 m_currentTextFragment.characterOffset = m_visualCharacterOffset; 567 m_currentTextFragment.characterOffset = m_visualMetricsIterator.char acterOffset();
589 m_currentTextFragment.metricsListOffset = m_visualMetricsListOffset; 568 m_currentTextFragment.metricsListOffset = m_visualMetricsIterator.me tricsListOffset();
590 m_currentTextFragment.x = x; 569 m_currentTextFragment.x = x;
591 m_currentTextFragment.y = y; 570 m_currentTextFragment.y = y;
592 571
593 // Build fragment transformation. 572 // Build fragment transformation.
594 if (angle) 573 if (angle)
595 m_currentTextFragment.transform.rotate(angle); 574 m_currentTextFragment.transform.rotate(angle);
596 575
597 if (xOrientationShift || yOrientationShift) 576 if (xOrientationShift || yOrientationShift)
598 m_currentTextFragment.transform.translate(xOrientationShift, yOr ientationShift); 577 m_currentTextFragment.transform.translate(xOrientationShift, yOr ientationShift);
599 578
(...skipping 22 matching lines...) Expand all
622 601
623 if (m_isVerticalText) 602 if (m_isVerticalText)
624 xNew -= baselineShift; 603 xNew -= baselineShift;
625 else 604 else
626 yNew += baselineShift; 605 yNew += baselineShift;
627 606
628 updateCurrentTextPosition(xNew, yNew, glyphAdvance + spacing); 607 updateCurrentTextPosition(xNew, yNew, glyphAdvance + spacing);
629 } 608 }
630 609
631 advanceToNextLogicalCharacter(logicalMetrics); 610 advanceToNextLogicalCharacter(logicalMetrics);
632 advanceToNextVisualCharacter(visualMetrics); 611 m_visualMetricsIterator.next();
633 lastAngle = angle; 612 lastAngle = angle;
634 } 613 }
635 614
636 if (!didStartTextFragment) 615 if (!didStartTextFragment)
637 return; 616 return;
638 617
639 // Close last open fragment, if needed. 618 // Close last open fragment, if needed.
640 recordTextFragment(textBox, visualMetricsValues); 619 recordTextFragment(textBox);
641 } 620 }
642 621
643 } 622 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698