| 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 17 matching lines...) Expand all Loading... |
| 28 #include "core/rendering/RenderFlowThread.h" | 28 #include "core/rendering/RenderFlowThread.h" |
| 29 #include "core/rendering/RenderLayer.h" | 29 #include "core/rendering/RenderLayer.h" |
| 30 #include "core/rendering/RenderListMarker.h" | 30 #include "core/rendering/RenderListMarker.h" |
| 31 #include "core/rendering/RenderRegion.h" | 31 #include "core/rendering/RenderRegion.h" |
| 32 #include "core/rendering/RenderRubyRun.h" | 32 #include "core/rendering/RenderRubyRun.h" |
| 33 #include "core/rendering/RenderView.h" | 33 #include "core/rendering/RenderView.h" |
| 34 #include "core/rendering/TrailingFloatsRootInlineBox.h" | 34 #include "core/rendering/TrailingFloatsRootInlineBox.h" |
| 35 #include "core/rendering/VerticalPositionCache.h" | 35 #include "core/rendering/VerticalPositionCache.h" |
| 36 #include "core/rendering/line/BreakingContextInlineHeaders.h" | 36 #include "core/rendering/line/BreakingContextInlineHeaders.h" |
| 37 #include "core/rendering/line/LineLayoutState.h" | 37 #include "core/rendering/line/LineLayoutState.h" |
| 38 #include "core/rendering/line/LineWidth.h" |
| 38 #include "core/rendering/svg/SVGRootInlineBox.h" | 39 #include "core/rendering/svg/SVGRootInlineBox.h" |
| 39 #include "platform/text/BidiResolver.h" | 40 #include "platform/text/BidiResolver.h" |
| 40 #include "wtf/RefCountedLeakCounter.h" | 41 #include "wtf/RefCountedLeakCounter.h" |
| 41 #include "wtf/StdLibExtras.h" | 42 #include "wtf/StdLibExtras.h" |
| 42 #include "wtf/Vector.h" | 43 #include "wtf/Vector.h" |
| 43 #include "wtf/unicode/CharacterNames.h" | 44 #include "wtf/unicode/CharacterNames.h" |
| 44 | 45 |
| 45 namespace WebCore { | 46 namespace WebCore { |
| 46 | 47 |
| 47 using namespace std; | 48 using namespace std; |
| 48 using namespace WTF::Unicode; | 49 using namespace WTF::Unicode; |
| 49 | 50 |
| 50 static IndentTextOrNot requiresIndent(bool isFirstLine, bool isAfterHardLineBrea
k, RenderStyle* style) | |
| 51 { | |
| 52 if (isFirstLine) | |
| 53 return IndentText; | |
| 54 if (isAfterHardLineBreak && style->textIndentLine() == TextIndentEachLine) | |
| 55 return IndentText; | |
| 56 | |
| 57 return DoNotIndentText; | |
| 58 } | |
| 59 | |
| 60 class LineBreaker { | |
| 61 public: | |
| 62 friend class BreakingContext; | |
| 63 LineBreaker(RenderBlockFlow* block) | |
| 64 : m_block(block) | |
| 65 { | |
| 66 reset(); | |
| 67 } | |
| 68 | |
| 69 InlineIterator nextLineBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&
, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines
, WordMeasurements&); | |
| 70 | |
| 71 bool lineWasHyphenated() { return m_hyphenated; } | |
| 72 const Vector<RenderBox*>& positionedObjects() { return m_positionedObjects;
} | |
| 73 EClear clear() { return m_clear; } | |
| 74 private: | |
| 75 void reset(); | |
| 76 | |
| 77 InlineIterator nextSegmentBreak(InlineBidiResolver&, LineInfo&, RenderTextIn
fo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLi
nes, WordMeasurements&); | |
| 78 void skipLeadingWhitespace(InlineBidiResolver&, LineInfo&, FloatingObject* l
astFloatFromPreviousLine, LineWidth&); | |
| 79 | |
| 80 RenderBlockFlow* m_block; | |
| 81 bool m_hyphenated; | |
| 82 EClear m_clear; | |
| 83 Vector<RenderBox*> m_positionedObjects; | |
| 84 }; | |
| 85 | |
| 86 static RenderObject* firstRenderObjectForDirectionalityDetermination(RenderObjec
t* root, RenderObject* current = 0) | 51 static RenderObject* firstRenderObjectForDirectionalityDetermination(RenderObjec
t* root, RenderObject* current = 0) |
| 87 { | 52 { |
| 88 RenderObject* next = current; | 53 RenderObject* next = current; |
| 89 while (current) { | 54 while (current) { |
| 90 if (isIsolated(current->style()->unicodeBidi()) | 55 if (isIsolated(current->style()->unicodeBidi()) |
| 91 && (current->isRenderInline() || current->isRenderBlock())) { | 56 && (current->isRenderInline() || current->isRenderBlock())) { |
| 92 if (current != root) | 57 if (current != root) |
| 93 current = 0; | 58 current = 0; |
| 94 else | 59 else |
| 95 current = next; | 60 current = next; |
| (...skipping 1835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1931 ASSERT(inlineObj->parent() == this); | 1896 ASSERT(inlineObj->parent() == this); |
| 1932 | 1897 |
| 1933 InlineIterator it(this, inlineObj, 0); | 1898 InlineIterator it(this, inlineObj, 0); |
| 1934 // FIXME: We should pass correct value for WhitespacePosition. | 1899 // FIXME: We should pass correct value for WhitespacePosition. |
| 1935 while (!it.atEnd() && !requiresLineBox(it)) | 1900 while (!it.atEnd() && !requiresLineBox(it)) |
| 1936 it.increment(); | 1901 it.increment(); |
| 1937 | 1902 |
| 1938 return !it.atEnd(); | 1903 return !it.atEnd(); |
| 1939 } | 1904 } |
| 1940 | 1905 |
| 1941 void LineBreaker::skipLeadingWhitespace(InlineBidiResolver& resolver, LineInfo&
lineInfo, | |
| 1942 FloatingObject* lastFloatFr
omPreviousLine, LineWidth& width) | |
| 1943 { | |
| 1944 while (!resolver.position().atEnd() && !requiresLineBox(resolver.position(),
lineInfo, LeadingWhitespace)) { | |
| 1945 RenderObject* object = resolver.position().object(); | |
| 1946 if (object->isOutOfFlowPositioned()) { | |
| 1947 setStaticPositions(m_block, toRenderBox(object)); | |
| 1948 if (object->style()->isOriginalDisplayInlineType()) { | |
| 1949 resolver.runs().addRun(createRun(0, 1, object, resolver)); | |
| 1950 lineInfo.incrementRunsFromLeadingWhitespace(); | |
| 1951 } | |
| 1952 } else if (object->isFloating()) | |
| 1953 m_block->positionNewFloatOnLine(m_block->insertFloatingObject(toRend
erBox(object)), lastFloatFromPreviousLine, lineInfo, width); | |
| 1954 else if (object->isText() && object->style()->hasTextCombine() && object
->isCombineText() && !toRenderCombineText(object)->isCombined()) { | |
| 1955 toRenderCombineText(object)->combineText(); | |
| 1956 if (toRenderCombineText(object)->isCombined()) | |
| 1957 continue; | |
| 1958 } | |
| 1959 resolver.position().increment(&resolver); | |
| 1960 } | |
| 1961 resolver.commitExplicitEmbedding(); | |
| 1962 } | |
| 1963 | |
| 1964 void LineBreaker::reset() | |
| 1965 { | |
| 1966 m_positionedObjects.clear(); | |
| 1967 m_hyphenated = false; | |
| 1968 m_clear = CNONE; | |
| 1969 } | |
| 1970 | |
| 1971 InlineIterator LineBreaker::nextLineBreak(InlineBidiResolver& resolver, LineInfo
& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPreviou
sLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wordMeasurements) | |
| 1972 { | |
| 1973 ShapeInsideInfo* shapeInsideInfo = m_block->layoutShapeInsideInfo(); | |
| 1974 | |
| 1975 if (!shapeInsideInfo || !shapeInsideInfo->lineOverlapsShapeBounds()) | |
| 1976 return nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFro
mPreviousLine, consecutiveHyphenatedLines, wordMeasurements); | |
| 1977 | |
| 1978 InlineIterator end = resolver.position(); | |
| 1979 InlineIterator oldEnd = end; | |
| 1980 | |
| 1981 if (!shapeInsideInfo->hasSegments()) { | |
| 1982 end = nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFrom
PreviousLine, consecutiveHyphenatedLines, wordMeasurements); | |
| 1983 resolver.setPositionIgnoringNestedIsolates(oldEnd); | |
| 1984 return oldEnd; | |
| 1985 } | |
| 1986 | |
| 1987 const SegmentList& segments = shapeInsideInfo->segments(); | |
| 1988 SegmentRangeList& segmentRanges = shapeInsideInfo->segmentRanges(); | |
| 1989 | |
| 1990 for (unsigned i = 0; i < segments.size() && !end.atEnd(); i++) { | |
| 1991 const InlineIterator segmentStart = resolver.position(); | |
| 1992 end = nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFrom
PreviousLine, consecutiveHyphenatedLines, wordMeasurements); | |
| 1993 | |
| 1994 ASSERT(segmentRanges.size() == i); | |
| 1995 if (resolver.position().atEnd()) { | |
| 1996 segmentRanges.append(LineSegmentRange(segmentStart, end)); | |
| 1997 break; | |
| 1998 } | |
| 1999 if (resolver.position() == end) { | |
| 2000 // Nothing fit this segment | |
| 2001 end = segmentStart; | |
| 2002 segmentRanges.append(LineSegmentRange(segmentStart, segmentStart)); | |
| 2003 resolver.setPositionIgnoringNestedIsolates(segmentStart); | |
| 2004 } else { | |
| 2005 // Note that resolver.position is already skipping some of the white
space at the beginning of the line, | |
| 2006 // so that's why segmentStart might be different than resolver.posit
ion(). | |
| 2007 LineSegmentRange range(resolver.position(), end); | |
| 2008 segmentRanges.append(range); | |
| 2009 resolver.setPosition(end, numberOfIsolateAncestors(end)); | |
| 2010 | |
| 2011 if (lineInfo.previousLineBrokeCleanly()) { | |
| 2012 // If we hit a new line break, just stop adding anything to this
line. | |
| 2013 break; | |
| 2014 } | |
| 2015 } | |
| 2016 } | |
| 2017 resolver.setPositionIgnoringNestedIsolates(oldEnd); | |
| 2018 return end; | |
| 2019 } | |
| 2020 | |
| 2021 InlineIterator LineBreaker::nextSegmentBreak(InlineBidiResolver& resolver, LineI
nfo& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPrev
iousLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wordMeasurement
s) | |
| 2022 { | |
| 2023 reset(); | |
| 2024 | |
| 2025 ASSERT(resolver.position().root() == m_block); | |
| 2026 | |
| 2027 bool appliedStartWidth = resolver.position().offset() > 0; | |
| 2028 | |
| 2029 LineWidth width(*m_block, lineInfo.isFirstLine(), requiresIndent(lineInfo.is
FirstLine(), lineInfo.previousLineBrokeCleanly(), m_block->style())); | |
| 2030 | |
| 2031 skipLeadingWhitespace(resolver, lineInfo, lastFloatFromPreviousLine, width); | |
| 2032 | |
| 2033 if (resolver.position().atEnd()) | |
| 2034 return resolver.position(); | |
| 2035 | |
| 2036 BreakingContext context(resolver, lineInfo, width, renderTextInfo, lastFloat
FromPreviousLine, appliedStartWidth, m_block); | |
| 2037 | |
| 2038 while (context.currentObject()) { | |
| 2039 context.initializeForCurrentObject(); | |
| 2040 if (context.currentObject()->isBR()) { | |
| 2041 context.handleBR(m_clear); | |
| 2042 } else if (context.currentObject()->isOutOfFlowPositioned()) { | |
| 2043 context.handleOutOfFlowPositioned(m_positionedObjects); | |
| 2044 } else if (context.currentObject()->isFloating()) { | |
| 2045 context.handleFloat(); | |
| 2046 } else if (context.currentObject()->isRenderInline()) { | |
| 2047 context.handleEmptyInline(); | |
| 2048 } else if (context.currentObject()->isReplaced()) { | |
| 2049 context.handleReplaced(); | |
| 2050 } else if (context.currentObject()->isText()) { | |
| 2051 if (context.handleText(wordMeasurements, m_hyphenated)) { | |
| 2052 // We've hit a hard text line break. Our line break iterator is
updated, so go ahead and early return. | |
| 2053 return context.lineBreak(); | |
| 2054 } | |
| 2055 } else { | |
| 2056 ASSERT_NOT_REACHED(); | |
| 2057 } | |
| 2058 | |
| 2059 if (context.atEnd()) | |
| 2060 return context.handleEndOfLine(); | |
| 2061 | |
| 2062 context.commitAndUpdateLineBreakIfNeeded(); | |
| 2063 | |
| 2064 if (context.atEnd()) | |
| 2065 return context.handleEndOfLine(); | |
| 2066 | |
| 2067 context.increment(); | |
| 2068 } | |
| 2069 | |
| 2070 context.clearLineBreakIfFitsOnLine(); | |
| 2071 | |
| 2072 return context.handleEndOfLine(); | |
| 2073 } | |
| 2074 | 1906 |
| 2075 void RenderBlockFlow::addOverflowFromInlineChildren() | 1907 void RenderBlockFlow::addOverflowFromInlineChildren() |
| 2076 { | 1908 { |
| 2077 LayoutUnit endPadding = hasOverflowClip() ? paddingEnd() : LayoutUnit(); | 1909 LayoutUnit endPadding = hasOverflowClip() ? paddingEnd() : LayoutUnit(); |
| 2078 // FIXME: Need to find another way to do this, since scrollbars could show w
hen we don't want them to. | 1910 // FIXME: Need to find another way to do this, since scrollbars could show w
hen we don't want them to. |
| 2079 if (hasOverflowClip() && !endPadding && node() && node()->isRootEditableElem
ent() && style()->isLeftToRightDirection()) | 1911 if (hasOverflowClip() && !endPadding && node() && node()->isRootEditableElem
ent() && style()->isLeftToRightDirection()) |
| 2080 endPadding = 1; | 1912 endPadding = 1; |
| 2081 for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox())
{ | 1913 for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox())
{ |
| 2082 addLayoutOverflow(curr->paddedLayoutOverflowRect(endPadding)); | 1914 addLayoutOverflow(curr->paddedLayoutOverflowRect(endPadding)); |
| 2083 LayoutRect visualOverflow = curr->visualOverflowRect(curr->lineTop(), cu
rr->lineBottom()); | 1915 LayoutRect visualOverflow = curr->visualOverflowRect(curr->lineTop(), cu
rr->lineBottom()); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2245 lineGridBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, ver
ticalPositionCache); | 2077 lineGridBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, ver
ticalPositionCache); |
| 2246 | 2078 |
| 2247 setLineGridBox(lineGridBox); | 2079 setLineGridBox(lineGridBox); |
| 2248 | 2080 |
| 2249 // FIXME: If any of the characteristics of the box change compared to the ol
d one, then we need to do a deep dirtying | 2081 // FIXME: If any of the characteristics of the box change compared to the ol
d one, then we need to do a deep dirtying |
| 2250 // (similar to what happens when the page height changes). Ideally, though,
we only do this if someone is actually snapping | 2082 // (similar to what happens when the page height changes). Ideally, though,
we only do this if someone is actually snapping |
| 2251 // to this grid. | 2083 // to this grid. |
| 2252 } | 2084 } |
| 2253 | 2085 |
| 2254 } | 2086 } |
| OLD | NEW |