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

Side by Side Diff: Source/core/layout/LayoutText.cpp

Issue 1043643002: Switch line layout to LayoutUnit. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: rebaseline 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 * (C) 1999 Lars Knoll (knoll@kde.org) 2 * (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 2000 Dirk Mueller (mueller@kde.org) 3 * (C) 2000 Dirk Mueller (mueller@kde.org)
4 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. 4 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
5 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) 5 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
6 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) 6 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 plainTextBuilder.append(text); 315 plainTextBuilder.append(text);
316 if (textBox->nextTextBox() && textBox->nextTextBox()->start() > textBox- >end() && text.length() && !text.right(1).containsOnlyWhitespace()) 316 if (textBox->nextTextBox() && textBox->nextTextBox()->start() > textBox- >end() && text.length() && !text.right(1).containsOnlyWhitespace())
317 plainTextBuilder.append(spaceCharacter); 317 plainTextBuilder.append(spaceCharacter);
318 } 318 }
319 return plainTextBuilder.toString(); 319 return plainTextBuilder.toString();
320 } 320 }
321 321
322 void LayoutText::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumu latedOffset) const 322 void LayoutText::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumu latedOffset) const
323 { 323 {
324 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) 324 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
325 rects.append(enclosingIntRect(FloatRect(FloatPoint(accumulatedOffset) + box->topLeft().toFloatPoint(), box->size().toFloatSize()))); 325 rects.append(enclosingIntRect(LayoutRect(LayoutPoint(accumulatedOffset) + box->topLeft(), box->size())));
326 } 326 }
327 327
328 static FloatRect localQuadForTextBox(InlineTextBox* box, unsigned start, unsigne d end, bool useSelectionHeight) 328 static FloatRect localQuadForTextBox(InlineTextBox* box, unsigned start, unsigne d end, bool useSelectionHeight)
329 { 329 {
330 unsigned realEnd = std::min(box->end() + 1, end); 330 unsigned realEnd = std::min(box->end() + 1, end);
331 LayoutRect r = box->localSelectionRect(start, realEnd); 331 LayoutRect r = box->localSelectionRect(start, realEnd);
332 if (r.height()) { 332 if (r.height()) {
333 if (!useSelectionHeight) { 333 if (!useSelectionHeight) {
334 // Change the height and y position (or width and x for vertical tex t) 334 // Change the height and y position (or width and x for vertical tex t)
335 // because selectionRect uses selection-specific values. 335 // because selectionRect uses selection-specific values.
(...skipping 18 matching lines...) Expand all
354 // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take unsigneds, but 354 // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take unsigneds, but
355 // that would cause many ripple effects, so for now we'll just clamp our uns igned parameters to INT_MAX. 355 // that would cause many ripple effects, so for now we'll just clamp our uns igned parameters to INT_MAX.
356 ASSERT(end == UINT_MAX || end <= INT_MAX); 356 ASSERT(end == UINT_MAX || end <= INT_MAX);
357 ASSERT(start <= INT_MAX); 357 ASSERT(start <= INT_MAX);
358 start = std::min(start, static_cast<unsigned>(INT_MAX)); 358 start = std::min(start, static_cast<unsigned>(INT_MAX));
359 end = std::min(end, static_cast<unsigned>(INT_MAX)); 359 end = std::min(end, static_cast<unsigned>(INT_MAX));
360 360
361 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 361 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
362 // Note: box->end() returns the index of the last character, not the ind ex past it 362 // Note: box->end() returns the index of the last character, not the ind ex past it
363 if (start <= box->start() && box->end() < end) { 363 if (start <= box->start() && box->end() < end) {
364 FloatRect r = box->calculateBoundaries().toFloatRect(); 364 FloatRect r(box->calculateBoundaries());
365 if (useSelectionHeight) { 365 if (useSelectionHeight) {
366 LayoutRect selectionRect = box->localSelectionRect(start, end); 366 LayoutRect selectionRect = box->localSelectionRect(start, end);
367 if (box->isHorizontal()) { 367 if (box->isHorizontal()) {
368 r.setHeight(selectionRect.height().toFloat()); 368 r.setHeight(selectionRect.height().toFloat());
369 r.setY(selectionRect.y().toFloat()); 369 r.setY(selectionRect.y().toFloat());
370 } else { 370 } else {
371 r.setWidth(selectionRect.width().toFloat()); 371 r.setWidth(selectionRect.width().toFloat());
372 r.setX(selectionRect.x().toFloat()); 372 r.setX(selectionRect.x().toFloat());
373 } 373 }
374 } 374 }
(...skipping 27 matching lines...) Expand all
402 if (ellipsisEndPosition >= truncation && ellipsisStartPosition <= trunca tion) 402 if (ellipsisEndPosition >= truncation && ellipsisStartPosition <= trunca tion)
403 return ellipsis->selectionRect(); 403 return ellipsis->selectionRect();
404 } 404 }
405 405
406 return IntRect(); 406 return IntRect();
407 } 407 }
408 408
409 void LayoutText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed, Clippin gOption option) const 409 void LayoutText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed, Clippin gOption option) const
410 { 410 {
411 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 411 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
412 FloatRect boundaries = box->calculateBoundaries().toFloatRect(); 412 FloatRect boundaries(box->calculateBoundaries());
413 413
414 // Shorten the width of this text box if it ends in an ellipsis. 414 // Shorten the width of this text box if it ends in an ellipsis.
415 // FIXME: ellipsisRectForBox should switch to return FloatRect soon with the subpixellayout branch. 415 // FIXME: ellipsisRectForBox should switch to return FloatRect soon with the subpixellayout branch.
416 IntRect ellipsisRect = (option == ClipToEllipsis) ? ellipsisRectForBox(b ox, 0, textLength()) : IntRect(); 416 IntRect ellipsisRect = (option == ClipToEllipsis) ? ellipsisRectForBox(b ox, 0, textLength()) : IntRect();
417 if (!ellipsisRect.isEmpty()) { 417 if (!ellipsisRect.isEmpty()) {
418 if (style()->isHorizontalWritingMode()) 418 if (style()->isHorizontalWritingMode())
419 boundaries.setWidth(ellipsisRect.maxX() - boundaries.x()); 419 boundaries.setWidth(ellipsisRect.maxX() - boundaries.x());
420 else 420 else
421 boundaries.setHeight(ellipsisRect.maxY() - boundaries.y()); 421 boundaries.setHeight(ellipsisRect.maxY() - boundaries.y());
422 } 422 }
(...skipping 14 matching lines...) Expand all
437 // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take unsigneds, but 437 // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take unsigneds, but
438 // that would cause many ripple effects, so for now we'll just clamp our uns igned parameters to INT_MAX. 438 // that would cause many ripple effects, so for now we'll just clamp our uns igned parameters to INT_MAX.
439 ASSERT(end == UINT_MAX || end <= INT_MAX); 439 ASSERT(end == UINT_MAX || end <= INT_MAX);
440 ASSERT(start <= INT_MAX); 440 ASSERT(start <= INT_MAX);
441 start = std::min(start, static_cast<unsigned>(INT_MAX)); 441 start = std::min(start, static_cast<unsigned>(INT_MAX));
442 end = std::min(end, static_cast<unsigned>(INT_MAX)); 442 end = std::min(end, static_cast<unsigned>(INT_MAX));
443 443
444 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 444 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
445 // Note: box->end() returns the index of the last character, not the ind ex past it 445 // Note: box->end() returns the index of the last character, not the ind ex past it
446 if (start <= box->start() && box->end() < end) { 446 if (start <= box->start() && box->end() < end) {
447 FloatRect r = box->calculateBoundaries().toFloatRect(); 447 LayoutRect r(box->calculateBoundaries());
448 if (useSelectionHeight) { 448 if (useSelectionHeight) {
449 LayoutRect selectionRect = box->localSelectionRect(start, end); 449 LayoutRect selectionRect = box->localSelectionRect(start, end);
450 if (box->isHorizontal()) { 450 if (box->isHorizontal()) {
451 r.setHeight(selectionRect.height().toFloat()); 451 r.setHeight(selectionRect.height());
452 r.setY(selectionRect.y().toFloat()); 452 r.setY(selectionRect.y());
453 } else { 453 } else {
454 r.setWidth(selectionRect.width().toFloat()); 454 r.setWidth(selectionRect.width());
455 r.setX(selectionRect.x().toFloat()); 455 r.setX(selectionRect.x());
456 } 456 }
457 } 457 }
458 quads.append(localToAbsoluteQuad(r, 0, wasFixed)); 458 quads.append(localToAbsoluteQuad(FloatRect(r), 0, wasFixed));
eae 2015/05/26 18:56:32 Not in this CL but perhaps we should add a version
szager1 2015/05/27 05:59:42 We could, but it would just be syntactic sugar, be
459 } else { 459 } else {
460 FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHe ight); 460 FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHe ight);
461 if (!rect.isZero()) 461 if (!rect.isZero())
462 quads.append(localToAbsoluteQuad(rect, 0, wasFixed)); 462 quads.append(localToAbsoluteQuad(rect, 0, wasFixed));
463 } 463 }
464 } 464 }
465 } 465 }
466 466
467 enum ShouldAffinityBeDownstream { AlwaysDownstream, AlwaysUpstream, UpstreamIfPo sitionIsNotAtStart }; 467 enum ShouldAffinityBeDownstream { AlwaysDownstream, AlwaysUpstream, UpstreamIfPo sitionIsNotAtStart };
468 468
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 ASSERT(inlineBox->isInlineTextBox()); 638 ASSERT(inlineBox->isInlineTextBox());
639 if (!inlineBox->isInlineTextBox()) 639 if (!inlineBox->isInlineTextBox())
640 return LayoutRect(); 640 return LayoutRect();
641 641
642 InlineTextBox* box = toInlineTextBox(inlineBox); 642 InlineTextBox* box = toInlineTextBox(inlineBox);
643 643
644 int height = box->root().selectionHeight(); 644 int height = box->root().selectionHeight();
645 int top = box->root().selectionTop(); 645 int top = box->root().selectionTop();
646 646
647 // Go ahead and round left to snap it to the nearest pixel. 647 // Go ahead and round left to snap it to the nearest pixel.
648 float left = box->positionForOffset(caretOffset); 648 LayoutUnit left = box->positionForOffset(caretOffset);
649 649
650 // Distribute the caret's width to either side of the offset. 650 // Distribute the caret's width to either side of the offset.
651 int caretWidthLeftOfOffset = caretWidth / 2; 651 LayoutUnit caretWidthLeftOfOffset = caretWidth() / 2;
652 left -= caretWidthLeftOfOffset; 652 left -= caretWidthLeftOfOffset;
653 int caretWidthRightOfOffset = caretWidth - caretWidthLeftOfOffset; 653 LayoutUnit caretWidthRightOfOffset = caretWidth() - caretWidthLeftOfOffset;
654 654
655 left = roundf(left); 655 left = left.round();
656 656
657 float rootLeft = box->root().logicalLeft(); 657 LayoutUnit rootLeft = box->root().logicalLeft();
658 float rootRight = box->root().logicalRight(); 658 LayoutUnit rootRight = box->root().logicalRight();
659 659
660 // FIXME: should we use the width of the root inline box or the 660 // FIXME: should we use the width of the root inline box or the
661 // width of the containing block for this? 661 // width of the containing block for this?
662 if (extraWidthToEndOfLine) 662 if (extraWidthToEndOfLine)
663 *extraWidthToEndOfLine = (box->root().logicalWidth() + rootLeft) - (left + 1); 663 *extraWidthToEndOfLine = (box->root().logicalWidth() + rootLeft) - (left + 1);
664 664
665 LayoutBlock* cb = containingBlock(); 665 LayoutBlock* cb = containingBlock();
666 const ComputedStyle& cbStyle = cb->styleRef(); 666 const ComputedStyle& cbStyle = cb->styleRef();
667 667
668 float leftEdge; 668 LayoutUnit leftEdge;
669 float rightEdge; 669 LayoutUnit rightEdge;
670 leftEdge = std::min<float>(0, rootLeft); 670 leftEdge = std::min(LayoutUnit(), rootLeft);
671 rightEdge = std::max<float>(cb->logicalWidth().toFloat(), rootRight); 671 rightEdge = std::max(cb->logicalWidth(), rootRight);
672 672
673 bool rightAligned = false; 673 bool rightAligned = false;
674 switch (cbStyle.textAlign()) { 674 switch (cbStyle.textAlign()) {
675 case RIGHT: 675 case RIGHT:
676 case WEBKIT_RIGHT: 676 case WEBKIT_RIGHT:
677 rightAligned = true; 677 rightAligned = true;
678 break; 678 break;
679 case LEFT: 679 case LEFT:
680 case WEBKIT_LEFT: 680 case WEBKIT_LEFT:
681 case CENTER: 681 case CENTER:
682 case WEBKIT_CENTER: 682 case WEBKIT_CENTER:
683 break; 683 break;
684 case JUSTIFY: 684 case JUSTIFY:
685 case TASTART: 685 case TASTART:
686 rightAligned = !cbStyle.isLeftToRightDirection(); 686 rightAligned = !cbStyle.isLeftToRightDirection();
687 break; 687 break;
688 case TAEND: 688 case TAEND:
689 rightAligned = cbStyle.isLeftToRightDirection(); 689 rightAligned = cbStyle.isLeftToRightDirection();
690 break; 690 break;
691 } 691 }
692 692
693 // for unicode-bidi: plaintext, use inlineBoxBidiLevel() to test the correct direction for the cursor. 693 // for unicode-bidi: plaintext, use inlineBoxBidiLevel() to test the correct direction for the cursor.
694 if (rightAligned && style()->unicodeBidi() == Plaintext) { 694 if (rightAligned && style()->unicodeBidi() == Plaintext) {
695 if (inlineBox->bidiLevel()%2 != 1) 695 if (inlineBox->bidiLevel()%2 != 1)
696 rightAligned = false; 696 rightAligned = false;
697 } 697 }
698 698
699 if (rightAligned) { 699 if (rightAligned) {
700 left = std::max(left, leftEdge); 700 left = std::max(left, leftEdge);
701 left = std::min(left, rootRight - caretWidth); 701 left = std::min(left, rootRight - caretWidth());
702 } else { 702 } else {
703 left = std::min(left, rightEdge - caretWidthRightOfOffset); 703 left = std::min(left, rightEdge - caretWidthRightOfOffset);
704 left = std::max(left, rootLeft); 704 left = std::max(left, rootLeft);
705 } 705 }
706 706
707 return LayoutRect(style()->isHorizontalWritingMode() ? IntRect(left, top, ca retWidth, height) : IntRect(top, left, height, caretWidth)); 707 return LayoutRect(style()->isHorizontalWritingMode() ? IntRect(left, top, ca retWidth(), height) : IntRect(top, left, height, caretWidth()));
708 } 708 }
709 709
710 ALWAYS_INLINE float LayoutText::widthFromCache(const Font& f, int start, int len , float xPos, TextDirection textDirection, HashSet<const SimpleFontData*>* fallb ackFonts, GlyphOverflow* glyphOverflow) const 710 ALWAYS_INLINE float LayoutText::widthFromCache(const Font& f, int start, int len , float xPos, TextDirection textDirection, HashSet<const SimpleFontData*>* fallb ackFonts, GlyphOverflow* glyphOverflow) const
711 { 711 {
712 if (style()->hasTextCombine() && isCombineText()) { 712 if (style()->hasTextCombine() && isCombineText()) {
713 const LayoutTextCombine* combineText = toLayoutTextCombine(this); 713 const LayoutTextCombine* combineText = toLayoutTextCombine(this);
714 if (combineText->isCombined()) 714 if (combineText->isCombined())
715 return combineText->combinedTextWidth(f); 715 return combineText->combinedTextWidth(f);
716 } 716 }
717 717
718 TextRun run = constructTextRun(const_cast<LayoutText*>(this), f, this, start , len, styleRef(), textDirection); 718 TextRun run = constructTextRun(const_cast<LayoutText*>(this), f, this, start , len, styleRef(), textDirection);
719 run.setCharactersLength(textLength() - start); 719 run.setCharactersLength(textLength() - start);
720 ASSERT(run.charactersLength() >= run.length()); 720 ASSERT(run.charactersLength() >= run.length());
721 run.setCodePath(canUseSimpleFontCodePath() ? TextRun::ForceSimple : TextRun: :ForceComplex); 721 run.setCodePath(canUseSimpleFontCodePath() ? TextRun::ForceSimple : TextRun: :ForceComplex);
722 run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize()); 722 run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize());
723 run.setXPos(xPos); 723 run.setXPos(xPos);
724 return f.width(run, fallbackFonts, glyphOverflow); 724 return f.width(run, fallbackFonts, glyphOverflow);
725 } 725 }
726 726
727 void LayoutText::trimmedPrefWidths(FloatWillBeLayoutUnit leadWidth, 727 void LayoutText::trimmedPrefWidths(LayoutUnit leadWidthLayoutUnit,
728 FloatWillBeLayoutUnit& firstLineMinWidth, bool& hasBreakableStart, 728 LayoutUnit& firstLineMinWidth, bool& hasBreakableStart,
729 FloatWillBeLayoutUnit& lastLineMinWidth, bool& hasBreakableEnd, 729 LayoutUnit& lastLineMinWidth, bool& hasBreakableEnd,
730 bool& hasBreakableChar, bool& hasBreak, 730 bool& hasBreakableChar, bool& hasBreak,
731 FloatWillBeLayoutUnit& firstLineMaxWidth, FloatWillBeLayoutUnit& lastLineMax Width, 731 LayoutUnit& firstLineMaxWidth, LayoutUnit& lastLineMaxWidth,
732 FloatWillBeLayoutUnit& minWidth, FloatWillBeLayoutUnit& maxWidth, bool& stri pFrontSpaces, 732 LayoutUnit& minWidth, LayoutUnit& maxWidth, bool& stripFrontSpaces,
733 TextDirection direction) 733 TextDirection direction)
734 { 734 {
735 float floatMinWidth = 0.0f, floatMaxWidth = 0.0f; 735 float floatMinWidth = 0.0f, floatMaxWidth = 0.0f;
736 float leadWidth = leadWidthLayoutUnit.toFloat();
eae 2015/05/26 18:56:31 Could you add a comment explaining leadWidth vs le
szager1 2015/05/27 05:59:42 Done.
736 737
737 bool collapseWhiteSpace = style()->collapseWhiteSpace(); 738 bool collapseWhiteSpace = style()->collapseWhiteSpace();
738 if (!collapseWhiteSpace) 739 if (!collapseWhiteSpace)
739 stripFrontSpaces = false; 740 stripFrontSpaces = false;
740 741
741 if (m_hasTab || preferredLogicalWidthsDirty()) 742 if (m_hasTab || preferredLogicalWidthsDirty())
742 computePreferredLogicalWidths(leadWidth); 743 computePreferredLogicalWidths(leadWidth);
743 744
744 hasBreakableStart = !stripFrontSpaces && m_hasBreakableStart; 745 hasBreakableStart = !stripFrontSpaces && m_hasBreakableStart;
745 hasBreakableEnd = m_hasBreakableEnd; 746 hasBreakableEnd = m_hasBreakableEnd;
746 747
747 int len = textLength(); 748 int len = textLength();
748 749
749 if (!len || (stripFrontSpaces && text().impl()->containsOnlyWhitespace())) { 750 if (!len || (stripFrontSpaces && text().impl()->containsOnlyWhitespace())) {
750 firstLineMinWidth = FloatWillBeLayoutUnit(); 751 firstLineMinWidth = LayoutUnit();
751 lastLineMinWidth = FloatWillBeLayoutUnit(); 752 lastLineMinWidth = LayoutUnit();
752 firstLineMaxWidth = FloatWillBeLayoutUnit(); 753 firstLineMaxWidth = LayoutUnit();
753 lastLineMaxWidth = FloatWillBeLayoutUnit(); 754 lastLineMaxWidth = LayoutUnit();
754 minWidth = FloatWillBeLayoutUnit(); 755 minWidth = LayoutUnit();
755 maxWidth = FloatWillBeLayoutUnit(); 756 maxWidth = LayoutUnit();
756 hasBreak = false; 757 hasBreak = false;
757 return; 758 return;
758 } 759 }
759 760
760 floatMinWidth = m_minWidth; 761 floatMinWidth = m_minWidth;
761 floatMaxWidth = m_maxWidth; 762 floatMaxWidth = m_maxWidth;
762 763
763 firstLineMinWidth = m_firstLineMinWidth; 764 firstLineMinWidth = m_firstLineMinWidth;
764 lastLineMinWidth = m_lastLineLineMinWidth; 765 lastLineMinWidth = m_lastLineLineMinWidth;
765 766
(...skipping 28 matching lines...) Expand all
794 lastLineMaxWidth = floatMaxWidth; 795 lastLineMaxWidth = floatMaxWidth;
795 for (int i = 0; i < len; i++) { 796 for (int i = 0; i < len; i++) {
796 int linelen = 0; 797 int linelen = 0;
797 while (i + linelen < len && text[i + linelen] != newlineCharacter) 798 while (i + linelen < len && text[i + linelen] != newlineCharacter)
798 linelen++; 799 linelen++;
799 800
800 if (linelen) { 801 if (linelen) {
801 lastLineMaxWidth = widthFromCache(f, i, linelen, leadWidth + las tLineMaxWidth, direction, 0, 0); 802 lastLineMaxWidth = widthFromCache(f, i, linelen, leadWidth + las tLineMaxWidth, direction, 0, 0);
802 if (firstLine) { 803 if (firstLine) {
803 firstLine = false; 804 firstLine = false;
804 leadWidth = FloatWillBeLayoutUnit(); 805 leadWidth = 0.f;
805 firstLineMaxWidth = lastLineMaxWidth; 806 firstLineMaxWidth = lastLineMaxWidth;
806 } 807 }
807 i += linelen; 808 i += linelen;
808 } else if (firstLine) { 809 } else if (firstLine) {
809 firstLineMaxWidth = FloatWillBeLayoutUnit(); 810 firstLineMaxWidth = LayoutUnit();
810 firstLine = false; 811 firstLine = false;
811 leadWidth = FloatWillBeLayoutUnit(); 812 leadWidth = 0.f;
812 } 813 }
813 814
814 if (i == len - 1) { 815 if (i == len - 1) {
815 // A <pre> run that ends with a newline, as in, e.g., 816 // A <pre> run that ends with a newline, as in, e.g.,
816 // <pre>Some text\n\n<span>More text</pre> 817 // <pre>Some text\n\n<span>More text</pre>
817 lastLineMaxWidth = FloatWillBeLayoutUnit(); 818 lastLineMaxWidth = LayoutUnit();
818 } 819 }
819 } 820 }
820 } 821 }
821 822
822 minWidth = LayoutUnit::fromFloatCeil(floatMinWidth); 823 minWidth = LayoutUnit::fromFloatCeil(floatMinWidth);
823 maxWidth = LayoutUnit::fromFloatCeil(floatMaxWidth); 824 maxWidth = LayoutUnit::fromFloatCeil(floatMaxWidth);
824 } 825 }
825 826
826 float LayoutText::minLogicalWidth() const 827 float LayoutText::minLogicalWidth() const
827 { 828 {
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after
1450 m_lastTextBox = s->prevTextBox(); 1451 m_lastTextBox = s->prevTextBox();
1451 else 1452 else
1452 s->nextTextBox()->setPreviousTextBox(s->prevTextBox()); 1453 s->nextTextBox()->setPreviousTextBox(s->prevTextBox());
1453 s->destroy(); 1454 s->destroy();
1454 return; 1455 return;
1455 } 1456 }
1456 1457
1457 m_containsReversedText |= !s->isLeftToRightDirection(); 1458 m_containsReversedText |= !s->isLeftToRightDirection();
1458 } 1459 }
1459 1460
1460 float LayoutText::width(unsigned from, unsigned len, float xPos, TextDirection t extDirection, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts, Gly phOverflow* glyphOverflow) const 1461 float LayoutText::width(unsigned from, unsigned len, LayoutUnit xPos, TextDirect ion textDirection, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts , GlyphOverflow* glyphOverflow) const
1461 { 1462 {
1462 if (from >= textLength()) 1463 if (from >= textLength())
1463 return 0; 1464 return 0;
1464 1465
1465 if (from + len > textLength()) 1466 if (from + len > textLength())
1466 len = textLength() - from; 1467 len = textLength() - from;
1467 1468
1468 return width(from, len, style(firstLine)->font(), xPos, textDirection, fallb ackFonts, glyphOverflow); 1469 return width(from, len, style(firstLine)->font(), xPos, textDirection, fallb ackFonts, glyphOverflow);
1469 } 1470 }
1470 1471
1471 float LayoutText::width(unsigned from, unsigned len, const Font& f, float xPos, TextDirection textDirection, HashSet<const SimpleFontData*>* fallbackFonts, Glyp hOverflow* glyphOverflow) const 1472 float LayoutText::width(unsigned from, unsigned len, const Font& f, LayoutUnit x Pos, TextDirection textDirection, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
1472 { 1473 {
1473 ASSERT(from + len <= textLength()); 1474 ASSERT(from + len <= textLength());
1474 if (!textLength()) 1475 if (!textLength())
1475 return 0; 1476 return 0;
1476 1477
1477 float w; 1478 float w;
1478 if (&f == &style()->font()) { 1479 if (&f == &style()->font()) {
1479 if (!style()->preserveNewline() && !from && len == textLength() && (!gly phOverflow || !glyphOverflow->computeBounds)) { 1480 if (!style()->preserveNewline() && !from && len == textLength() && (!gly phOverflow || !glyphOverflow->computeBounds)) {
1480 if (fallbackFonts) { 1481 if (fallbackFonts) {
1481 ASSERT(glyphOverflow); 1482 ASSERT(glyphOverflow);
1482 if (preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflowAnd NoFallbackFonts) { 1483 if (preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflowAnd NoFallbackFonts) {
1483 const_cast<LayoutText*>(this)->computePreferredLogicalWidths (0, *fallbackFonts, *glyphOverflow); 1484 const_cast<LayoutText*>(this)->computePreferredLogicalWidths (0, *fallbackFonts, *glyphOverflow);
1484 // We shouldn't change our mind once we "know". 1485 // We shouldn't change our mind once we "know".
1485 ASSERT(!m_knownToHaveNoOverflowAndNoFallbackFonts 1486 ASSERT(!m_knownToHaveNoOverflowAndNoFallbackFonts
1486 || (fallbackFonts->isEmpty() && glyphOverflow->isZero()) ); 1487 || (fallbackFonts->isEmpty() && glyphOverflow->isZero()) );
1487 m_knownToHaveNoOverflowAndNoFallbackFonts = fallbackFonts->i sEmpty() && glyphOverflow->isZero(); 1488 m_knownToHaveNoOverflowAndNoFallbackFonts = fallbackFonts->i sEmpty() && glyphOverflow->isZero();
1488 } 1489 }
1489 w = m_maxWidth; 1490 w = m_maxWidth;
1490 } else { 1491 } else {
1491 w = maxLogicalWidth(); 1492 w = maxLogicalWidth();
1492 } 1493 }
1493 } else { 1494 } else {
1494 w = widthFromCache(f, from, len, xPos, textDirection, fallbackFonts, glyphOverflow); 1495 w = widthFromCache(f, from, len, xPos.toFloat(), textDirection, fall backFonts, glyphOverflow);
1495 } 1496 }
1496 } else { 1497 } else {
1497 TextRun run = constructTextRun(const_cast<LayoutText*>(this), f, this, f rom, len, styleRef(), textDirection); 1498 TextRun run = constructTextRun(const_cast<LayoutText*>(this), f, this, f rom, len, styleRef(), textDirection);
1498 run.setCharactersLength(textLength() - from); 1499 run.setCharactersLength(textLength() - from);
1499 ASSERT(run.charactersLength() >= run.length()); 1500 ASSERT(run.charactersLength() >= run.length());
1500 1501
1501 run.setCodePath(canUseSimpleFontCodePath() ? TextRun::ForceSimple : Text Run::ForceComplex); 1502 run.setCodePath(canUseSimpleFontCodePath() ? TextRun::ForceSimple : Text Run::ForceComplex);
1502 run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize()); 1503 run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize());
1503 run.setXPos(xPos); 1504 run.setXPos(xPos.toFloat());
1504 w = f.width(run, fallbackFonts, glyphOverflow); 1505 w = f.width(run, fallbackFonts, glyphOverflow);
1505 } 1506 }
1506 1507
1507 return w; 1508 return w;
1508 } 1509 }
1509 1510
1510 IntRect LayoutText::linesBoundingBox() const 1511 IntRect LayoutText::linesBoundingBox() const
1511 { 1512 {
1512 IntRect result; 1513 IntRect result;
1513 1514
1514 ASSERT(!firstTextBox() == !lastTextBox()); // Either both are null or both e xist. 1515 ASSERT(!firstTextBox() == !lastTextBox()); // Either both are null or both e xist.
1515 if (firstTextBox() && lastTextBox()) { 1516 if (firstTextBox() && lastTextBox()) {
1516 // Return the width of the minimal left side and the maximal right side. 1517 // Return the width of the minimal left side and the maximal right side.
1517 float logicalLeftSide = 0; 1518 float logicalLeftSide = 0;
1518 float logicalRightSide = 0; 1519 float logicalRightSide = 0;
1519 for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBo x()) { 1520 for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBo x()) {
1520 if (curr == firstTextBox() || curr->logicalLeft() < logicalLeftSide) 1521 if (curr == firstTextBox() || curr->logicalLeft() < logicalLeftSide)
1521 logicalLeftSide = curr->logicalLeft(); 1522 logicalLeftSide = curr->logicalLeft().toFloat();
1522 if (curr == firstTextBox() || curr->logicalRight() > logicalRightSid e) 1523 if (curr == firstTextBox() || curr->logicalRight() > logicalRightSid e)
1523 logicalRightSide = curr->logicalRight(); 1524 logicalRightSide = curr->logicalRight().toFloat();
1524 } 1525 }
1525 1526
1526 bool isHorizontal = style()->isHorizontalWritingMode(); 1527 bool isHorizontal = style()->isHorizontalWritingMode();
1527 1528
1528 float x = isHorizontal ? logicalLeftSide : firstTextBox()->x().toFloat() ; 1529 float x = isHorizontal ? logicalLeftSide : firstTextBox()->x().toFloat() ;
1529 float y = isHorizontal ? firstTextBox()->y().toFloat() : logicalLeftSide ; 1530 float y = isHorizontal ? firstTextBox()->y().toFloat() : logicalLeftSide ;
1530 float width = isHorizontal ? logicalRightSide - logicalLeftSide : lastTe xtBox()->logicalBottom() - x; 1531 float width = isHorizontal ? logicalRightSide - logicalLeftSide : lastTe xtBox()->logicalBottom() - x;
1531 float height = isHorizontal ? lastTextBox()->logicalBottom() - y : logic alRightSide - logicalLeftSide; 1532 float height = isHorizontal ? lastTextBox()->logicalBottom() - y : logic alRightSide - logicalLeftSide;
1532 result = enclosingIntRect(FloatRect(x, y, width, height)); 1533 result = enclosingIntRect(FloatRect(x, y, width, height));
1533 } 1534 }
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
1855 } 1856 }
1856 1857
1857 void LayoutText::invalidateDisplayItemClients(const LayoutBoxModelObject& paintI nvalidationContainer) const 1858 void LayoutText::invalidateDisplayItemClients(const LayoutBoxModelObject& paintI nvalidationContainer) const
1858 { 1859 {
1859 LayoutObject::invalidateDisplayItemClients(paintInvalidationContainer); 1860 LayoutObject::invalidateDisplayItemClients(paintInvalidationContainer);
1860 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) 1861 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
1861 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(*box); 1862 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(*box);
1862 } 1863 }
1863 1864
1864 } // namespace blink 1865 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698