Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |