OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) |
3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ight reserved. | 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ight reserved. |
4 * Copyright (C) 2010 Google Inc. All rights reserved. | 4 * Copyright (C) 2010 Google Inc. All rights reserved. |
5 * | 5 * |
6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
10 * | 10 * |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 | 47 |
48 using namespace std; | 48 using namespace std; |
49 using namespace WTF; | 49 using namespace WTF; |
50 using namespace Unicode; | 50 using namespace Unicode; |
51 | 51 |
52 namespace WebCore { | 52 namespace WebCore { |
53 | 53 |
54 // We don't let our line box tree for a single line get any deeper than this. | 54 // We don't let our line box tree for a single line get any deeper than this. |
55 const unsigned cMaxLineDepth = 200; | 55 const unsigned cMaxLineDepth = 200; |
56 | 56 |
| 57 struct RenderTextInfo { |
| 58 // Destruction of m_layout requires TextLayout to be a complete type, so the
constructor and destructor are made non-inline to avoid compilation errors. |
| 59 RenderTextInfo(); |
| 60 ~RenderTextInfo(); |
| 61 |
| 62 RenderText* m_text; |
| 63 OwnPtr<TextLayout> m_layout; |
| 64 LazyLineBreakIterator m_lineBreakIterator; |
| 65 const Font* m_font; |
| 66 }; |
| 67 |
| 68 class LineBreaker { |
| 69 public: |
| 70 LineBreaker(RenderBlock* block) |
| 71 : m_block(block) |
| 72 { |
| 73 reset(); |
| 74 } |
| 75 |
| 76 InlineIterator nextLineBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&
, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines
, WordMeasurements&); |
| 77 |
| 78 bool lineWasHyphenated() { return m_hyphenated; } |
| 79 const Vector<RenderBox*>& positionedObjects() { return m_positionedObjects;
} |
| 80 EClear clear() { return m_clear; } |
| 81 private: |
| 82 void reset(); |
| 83 |
| 84 InlineIterator nextSegmentBreak(InlineBidiResolver&, LineInfo&, RenderTextIn
fo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLi
nes, WordMeasurements&); |
| 85 void skipTrailingWhitespace(InlineIterator&, const LineInfo&); |
| 86 void skipLeadingWhitespace(InlineBidiResolver&, LineInfo&, FloatingObject* l
astFloatFromPreviousLine, LineWidth&); |
| 87 |
| 88 RenderBlock* m_block; |
| 89 bool m_hyphenated; |
| 90 EClear m_clear; |
| 91 Vector<RenderBox*> m_positionedObjects; |
| 92 }; |
| 93 |
57 static LayoutUnit logicalHeightForLine(const RenderBlock* block, bool isFirstLin
e, LayoutUnit replacedHeight = 0) | 94 static LayoutUnit logicalHeightForLine(const RenderBlock* block, bool isFirstLin
e, LayoutUnit replacedHeight = 0) |
58 { | 95 { |
59 if (!block->document().inNoQuirksMode() && replacedHeight) | 96 if (!block->document().inNoQuirksMode() && replacedHeight) |
60 return replacedHeight; | 97 return replacedHeight; |
61 | 98 |
62 if (!(block->style(isFirstLine)->lineBoxContain() & LineBoxContainBlock)) | 99 if (!(block->style(isFirstLine)->lineBoxContain() & LineBoxContainBlock)) |
63 return 0; | 100 return 0; |
64 | 101 |
65 return max<LayoutUnit>(replacedHeight, block->lineHeight(isFirstLine, block-
>isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLi
neBoxes)); | 102 return max<LayoutUnit>(replacedHeight, block->lineHeight(isFirstLine, block-
>isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLi
neBoxes)); |
66 } | 103 } |
(...skipping 1527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1594 newLine(clear); | 1631 newLine(clear); |
1595 } | 1632 } |
1596 } | 1633 } |
1597 } | 1634 } |
1598 | 1635 |
1599 layoutRunsAndFloatsInRange(layoutState, resolver, cleanLineStart, cleanLineB
idiStatus, consecutiveHyphenatedLines); | 1636 layoutRunsAndFloatsInRange(layoutState, resolver, cleanLineStart, cleanLineB
idiStatus, consecutiveHyphenatedLines); |
1600 linkToEndLineIfNeeded(layoutState); | 1637 linkToEndLineIfNeeded(layoutState); |
1601 repaintDirtyFloats(layoutState.floats()); | 1638 repaintDirtyFloats(layoutState.floats()); |
1602 } | 1639 } |
1603 | 1640 |
1604 RenderBlock::RenderTextInfo::RenderTextInfo() | 1641 RenderTextInfo::RenderTextInfo() |
1605 : m_text(0) | 1642 : m_text(0) |
1606 , m_font(0) | 1643 , m_font(0) |
1607 { | 1644 { |
1608 } | 1645 } |
1609 | 1646 |
1610 RenderBlock::RenderTextInfo::~RenderTextInfo() | 1647 RenderTextInfo::~RenderTextInfo() |
1611 { | 1648 { |
1612 } | 1649 } |
1613 | 1650 |
1614 // Before restarting the layout loop with a new logicalHeight, remove all floats
that were added and reset the resolver. | 1651 // Before restarting the layout loop with a new logicalHeight, remove all floats
that were added and reset the resolver. |
1615 inline const InlineIterator& RenderBlock::restartLayoutRunsAndFloatsInRange(Layo
utUnit oldLogicalHeight, LayoutUnit newLogicalHeight, FloatingObject* lastFloat
FromPreviousLine, InlineBidiResolver& resolver, const InlineIterator& oldEnd) | 1652 inline const InlineIterator& RenderBlock::restartLayoutRunsAndFloatsInRange(Layo
utUnit oldLogicalHeight, LayoutUnit newLogicalHeight, FloatingObject* lastFloat
FromPreviousLine, InlineBidiResolver& resolver, const InlineIterator& oldEnd) |
1616 { | 1653 { |
1617 removeFloatingObjectsBelow(lastFloatFromPreviousLine, oldLogicalHeight); | 1654 removeFloatingObjectsBelow(lastFloatFromPreviousLine, oldLogicalHeight); |
1618 setLogicalHeight(newLogicalHeight); | 1655 setLogicalHeight(newLogicalHeight); |
1619 resolver.setPositionIgnoringNestedIsolates(oldEnd); | 1656 resolver.setPositionIgnoringNestedIsolates(oldEnd); |
1620 return oldEnd; | 1657 return oldEnd; |
(...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2517 | 2554 |
2518 return !it.atEnd(); | 2555 return !it.atEnd(); |
2519 } | 2556 } |
2520 | 2557 |
2521 // FIXME: The entire concept of the skipTrailingWhitespace function is flawed, s
ince we really need to be building | 2558 // FIXME: The entire concept of the skipTrailingWhitespace function is flawed, s
ince we really need to be building |
2522 // line boxes even for containers that may ultimately collapse away. Otherwise w
e'll never get positioned | 2559 // line boxes even for containers that may ultimately collapse away. Otherwise w
e'll never get positioned |
2523 // elements quite right. In other words, we need to build this function's work i
nto the normal line | 2560 // elements quite right. In other words, we need to build this function's work i
nto the normal line |
2524 // object iteration process. | 2561 // object iteration process. |
2525 // NB. this function will insert any floating elements that would otherwise | 2562 // NB. this function will insert any floating elements that would otherwise |
2526 // be skipped but it will not position them. | 2563 // be skipped but it will not position them. |
2527 void RenderBlock::LineBreaker::skipTrailingWhitespace(InlineIterator& iterator,
const LineInfo& lineInfo) | 2564 void LineBreaker::skipTrailingWhitespace(InlineIterator& iterator, const LineInf
o& lineInfo) |
2528 { | 2565 { |
2529 while (!iterator.atEnd() && !requiresLineBox(iterator, lineInfo, TrailingWhi
tespace)) { | 2566 while (!iterator.atEnd() && !requiresLineBox(iterator, lineInfo, TrailingWhi
tespace)) { |
2530 RenderObject* object = iterator.m_obj; | 2567 RenderObject* object = iterator.m_obj; |
2531 if (object->isOutOfFlowPositioned()) | 2568 if (object->isOutOfFlowPositioned()) |
2532 setStaticPositions(m_block, toRenderBox(object)); | 2569 setStaticPositions(m_block, toRenderBox(object)); |
2533 else if (object->isFloating()) | 2570 else if (object->isFloating()) |
2534 m_block->insertFloatingObject(toRenderBox(object)); | 2571 m_block->insertFloatingObject(toRenderBox(object)); |
2535 iterator.increment(); | 2572 iterator.increment(); |
2536 } | 2573 } |
2537 } | 2574 } |
2538 | 2575 |
2539 void RenderBlock::LineBreaker::skipLeadingWhitespace(InlineBidiResolver& resolve
r, LineInfo& lineInfo, | 2576 void LineBreaker::skipLeadingWhitespace(InlineBidiResolver& resolver, LineInfo&
lineInfo, |
2540 FloatingObject* lastFloatFr
omPreviousLine, LineWidth& width) | 2577 FloatingObject* lastFloatFr
omPreviousLine, LineWidth& width) |
2541 { | 2578 { |
2542 while (!resolver.position().atEnd() && !requiresLineBox(resolver.position(),
lineInfo, LeadingWhitespace)) { | 2579 while (!resolver.position().atEnd() && !requiresLineBox(resolver.position(),
lineInfo, LeadingWhitespace)) { |
2543 RenderObject* object = resolver.position().m_obj; | 2580 RenderObject* object = resolver.position().m_obj; |
2544 if (object->isOutOfFlowPositioned()) { | 2581 if (object->isOutOfFlowPositioned()) { |
2545 setStaticPositions(m_block, toRenderBox(object)); | 2582 setStaticPositions(m_block, toRenderBox(object)); |
2546 if (object->style()->isOriginalDisplayInlineType()) { | 2583 if (object->style()->isOriginalDisplayInlineType()) { |
2547 resolver.runs().addRun(createRun(0, 1, object, resolver)); | 2584 resolver.runs().addRun(createRun(0, 1, object, resolver)); |
2548 lineInfo.incrementRunsFromLeadingWhitespace(); | 2585 lineInfo.incrementRunsFromLeadingWhitespace(); |
2549 } | 2586 } |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2681 unsigned length = m_whitespace->textLength(); | 2718 unsigned length = m_whitespace->textLength(); |
2682 unsigned pos = length >= 2 ? length - 2 : UINT_MAX; | 2719 unsigned pos = length >= 2 ? length - 2 : UINT_MAX; |
2683 InlineIterator endMid(0, m_whitespace, pos); | 2720 InlineIterator endMid(0, m_whitespace, pos); |
2684 startIgnoringSpaces(lineMidpointState, endMid); | 2721 startIgnoringSpaces(lineMidpointState, endMid); |
2685 for (size_t i = 0; i < m_boxes.size(); ++i) { | 2722 for (size_t i = 0; i < m_boxes.size(); ++i) { |
2686 ensureLineBoxInsideIgnoredSpaces(lineMidpointState, m_boxes[i]); | 2723 ensureLineBoxInsideIgnoredSpaces(lineMidpointState, m_boxes[i]); |
2687 } | 2724 } |
2688 } | 2725 } |
2689 } | 2726 } |
2690 | 2727 |
2691 void RenderBlock::LineBreaker::reset() | 2728 void LineBreaker::reset() |
2692 { | 2729 { |
2693 m_positionedObjects.clear(); | 2730 m_positionedObjects.clear(); |
2694 m_hyphenated = false; | 2731 m_hyphenated = false; |
2695 m_clear = CNONE; | 2732 m_clear = CNONE; |
2696 } | 2733 } |
2697 | 2734 |
2698 InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resol
ver, LineInfo& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFlo
atFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wordM
easurements) | 2735 InlineIterator LineBreaker::nextLineBreak(InlineBidiResolver& resolver, LineInfo
& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPreviou
sLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wordMeasurements) |
2699 { | 2736 { |
2700 ShapeInsideInfo* shapeInsideInfo = m_block->layoutShapeInsideInfo(); | 2737 ShapeInsideInfo* shapeInsideInfo = m_block->layoutShapeInsideInfo(); |
2701 | 2738 |
2702 if (!shapeInsideInfo || !shapeInsideInfo->lineOverlapsShapeBounds()) | 2739 if (!shapeInsideInfo || !shapeInsideInfo->lineOverlapsShapeBounds()) |
2703 return nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFro
mPreviousLine, consecutiveHyphenatedLines, wordMeasurements); | 2740 return nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFro
mPreviousLine, consecutiveHyphenatedLines, wordMeasurements); |
2704 | 2741 |
2705 InlineIterator end = resolver.position(); | 2742 InlineIterator end = resolver.position(); |
2706 InlineIterator oldEnd = end; | 2743 InlineIterator oldEnd = end; |
2707 | 2744 |
2708 if (!shapeInsideInfo->hasSegments()) { | 2745 if (!shapeInsideInfo->hasSegments()) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2743 } | 2780 } |
2744 resolver.setPositionIgnoringNestedIsolates(oldEnd); | 2781 resolver.setPositionIgnoringNestedIsolates(oldEnd); |
2745 return end; | 2782 return end; |
2746 } | 2783 } |
2747 | 2784 |
2748 static inline bool iteratorIsBeyondEndOfRenderCombineText(const InlineIterator&
iter, RenderCombineText* renderer) | 2785 static inline bool iteratorIsBeyondEndOfRenderCombineText(const InlineIterator&
iter, RenderCombineText* renderer) |
2749 { | 2786 { |
2750 return iter.m_obj == renderer && iter.m_pos >= renderer->textLength(); | 2787 return iter.m_obj == renderer && iter.m_pos >= renderer->textLength(); |
2751 } | 2788 } |
2752 | 2789 |
2753 InlineIterator RenderBlock::LineBreaker::nextSegmentBreak(InlineBidiResolver& re
solver, LineInfo& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* last
FloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wo
rdMeasurements) | 2790 InlineIterator LineBreaker::nextSegmentBreak(InlineBidiResolver& resolver, LineI
nfo& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPrev
iousLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wordMeasurement
s) |
2754 { | 2791 { |
2755 reset(); | 2792 reset(); |
2756 | 2793 |
2757 ASSERT(resolver.position().root() == m_block); | 2794 ASSERT(resolver.position().root() == m_block); |
2758 | 2795 |
2759 bool appliedStartWidth = resolver.position().m_pos > 0; | 2796 bool appliedStartWidth = resolver.position().m_pos > 0; |
2760 bool includeEndWidth = true; | 2797 bool includeEndWidth = true; |
2761 LineMidpointState& lineMidpointState = resolver.midpointState(); | 2798 LineMidpointState& lineMidpointState = resolver.midpointState(); |
2762 | 2799 |
2763 LineWidth width(m_block, lineInfo.isFirstLine(), requiresIndent(lineInfo.isF
irstLine(), lineInfo.previousLineBrokeCleanly(), m_block->style())); | 2800 LineWidth width(m_block, lineInfo.isFirstLine(), requiresIndent(lineInfo.isF
irstLine(), lineInfo.previousLineBrokeCleanly(), m_block->style())); |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3007 renderTextInfo.m_lineBreakIterator.resetStringAndReleaseIterator
(t->text(), style->locale()); | 3044 renderTextInfo.m_lineBreakIterator.resetStringAndReleaseIterator
(t->text(), style->locale()); |
3008 } else if (renderTextInfo.m_layout && renderTextInfo.m_font != &f) { | 3045 } else if (renderTextInfo.m_layout && renderTextInfo.m_font != &f) { |
3009 renderTextInfo.m_font = &f; | 3046 renderTextInfo.m_font = &f; |
3010 renderTextInfo.m_layout = f.createLayout(t, width.currentWidth()
, collapseWhiteSpace); | 3047 renderTextInfo.m_layout = f.createLayout(t, width.currentWidth()
, collapseWhiteSpace); |
3011 } | 3048 } |
3012 | 3049 |
3013 TextLayout* textLayout = renderTextInfo.m_layout.get(); | 3050 TextLayout* textLayout = renderTextInfo.m_layout.get(); |
3014 | 3051 |
3015 // Non-zero only when kerning is enabled and TextLayout isn't used,
in which case we measure | 3052 // Non-zero only when kerning is enabled and TextLayout isn't used,
in which case we measure |
3016 // words with their trailing space, then subtract its width. | 3053 // words with their trailing space, then subtract its width. |
3017 float wordTrailingSpaceWidth = (f.typesettingFeatures() & Kerning) &
& !textLayout ? f.width(constructTextRun(t, f, &space, 1, style)) + wordSpacing
: 0; | 3054 float wordTrailingSpaceWidth = (f.typesettingFeatures() & Kerning) &
& !textLayout ? f.width(RenderBlock::constructTextRun(t, f, &space, 1, style)) +
wordSpacing : 0; |
3018 | 3055 |
3019 UChar lastCharacter = renderTextInfo.m_lineBreakIterator.lastCharact
er(); | 3056 UChar lastCharacter = renderTextInfo.m_lineBreakIterator.lastCharact
er(); |
3020 UChar secondToLastCharacter = renderTextInfo.m_lineBreakIterator.sec
ondToLastCharacter(); | 3057 UChar secondToLastCharacter = renderTextInfo.m_lineBreakIterator.sec
ondToLastCharacter(); |
3021 for (; current.m_pos < t->textLength(); current.fastIncrementInTextN
ode()) { | 3058 for (; current.m_pos < t->textLength(); current.fastIncrementInTextN
ode()) { |
3022 bool previousCharacterIsSpace = currentCharacterIsSpace; | 3059 bool previousCharacterIsSpace = currentCharacterIsSpace; |
3023 bool previousCharacterShouldCollapseIfPreWap = currentCharacterS
houldCollapseIfPreWap; | 3060 bool previousCharacterShouldCollapseIfPreWap = currentCharacterS
houldCollapseIfPreWap; |
3024 UChar c = current.current(); | 3061 UChar c = current.current(); |
3025 currentCharacterShouldCollapseIfPreWap = currentCharacterIsSpace
= c == ' ' || c == '\t' || (!preserveNewline && (c == '\n')); | 3062 currentCharacterShouldCollapseIfPreWap = currentCharacterIsSpace
= c == ' ' || c == '\t' || (!preserveNewline && (c == '\n')); |
3026 | 3063 |
3027 if (!collapseWhiteSpace || !currentCharacterIsSpace) | 3064 if (!collapseWhiteSpace || !currentCharacterIsSpace) |
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3522 lineGridBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, ver
ticalPositionCache); | 3559 lineGridBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, ver
ticalPositionCache); |
3523 | 3560 |
3524 setLineGridBox(lineGridBox); | 3561 setLineGridBox(lineGridBox); |
3525 | 3562 |
3526 // FIXME: If any of the characteristics of the box change compared to the ol
d one, then we need to do a deep dirtying | 3563 // FIXME: If any of the characteristics of the box change compared to the ol
d one, then we need to do a deep dirtying |
3527 // (similar to what happens when the page height changes). Ideally, though,
we only do this if someone is actually snapping | 3564 // (similar to what happens when the page height changes). Ideally, though,
we only do this if someone is actually snapping |
3528 // to this grid. | 3565 // to this grid. |
3529 } | 3566 } |
3530 | 3567 |
3531 } | 3568 } |
OLD | NEW |