Changeset 136729 in webkit
- Timestamp:
- Dec 5, 2012 12:17:30 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 9 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r136726 r136729 1 2012-12-05 Bear Travis <betravis@adobe.com> 2 3 [CSS Exclusions] Enable shape-inside for multiple-segment polygons 4 https://bugs.webkit.org/show_bug.cgi?id=91878 5 6 Reviewed by David Hyatt. 7 8 Adding tests for multiple segment polygons. These tests make sure that text can be 9 properly broken up into multiple segments per line to fit into a shape-inside. 10 11 * fast/exclusions/shape-inside/shape-inside-multiple-segments-001-expected.html: Added. 12 * fast/exclusions/shape-inside/shape-inside-multiple-segments-001.html: Added. 13 * fast/exclusions/shape-inside/shape-inside-multiple-segments-002-expected.html: Added. 14 * fast/exclusions/shape-inside/shape-inside-multiple-segments-002.html: Added. 15 * fast/exclusions/shape-inside/shape-inside-multiple-segments-003-expected.html: Added. 16 * fast/exclusions/shape-inside/shape-inside-multiple-segments-003.html: Added. 17 * fast/exclusions/shape-inside/shape-inside-multiple-segments-004-expected.html: Added. 18 * fast/exclusions/shape-inside/shape-inside-multiple-segments-004.html: Added. 19 1 20 2012-12-05 Roger Fong <roger_fong@apple.com> 2 21 -
trunk/Source/WebCore/ChangeLog
r136728 r136729 1 2012-12-05 Bear Travis <betravis@adobe.com> 2 3 [CSS Exclusions] Enable shape-inside for multiple-segment polygons 4 https://bugs.webkit.org/show_bug.cgi?id=91878 5 6 Reviewed by David Hyatt. 7 8 Patch adding support for multiple-segment polygons for shape-insides from 9 the CSS Exclusions specification. The layout code has been modified to first 10 support dividing text into multiple segments per line, and then to lay out 11 multiple segments per line box. 12 13 Tests: fast/exclusions/shape-inside/shape-inside-multiple-segments-001.html 14 fast/exclusions/shape-inside/shape-inside-multiple-segments-002.html 15 fast/exclusions/shape-inside/shape-inside-multiple-segments-003.html 16 fast/exclusions/shape-inside/shape-inside-multiple-segments-004.html 17 18 * platform/text/BidiResolver.h: 19 (WebCore::BidiCharacterRun::BidiCharacterRun): 20 (BidiCharacterRun): Added a 'startsSegment' bitfield to track whether a 21 run begins a new segment. The field is here, rather than in BidiRun, in 22 order to save space. See Bug 100173. 23 * rendering/BidiRun.h: 24 (WebCore::BidiRun::BidiRun): 25 (BidiRun): Set the initial value for 'startsSegment'. 26 * rendering/ExclusionShapeInsideInfo.cpp: 27 (WebCore::ExclusionShapeInsideInfo::computeSegmentsForLine): Clear the 28 segment ranges when computing segments for a new line. 29 * rendering/ExclusionShapeInsideInfo.h: 30 (LineSegmentRange): Added a new type to track segment offsets. 31 (WebCore::ExclusionShapeInsideInfo::segmentRanges): Added a getter for 32 the line segment ranges vector. 33 * rendering/InlineFlowBox.cpp: 34 (WebCore::InlineFlowBox::placeBoxesInInlineDirection): Modified to call 35 a refactored box placement algorithm that takes a beginning and end position. 36 (WebCore::InlineFlowBox::placeBoxRangeInInlineDirection): Similar to the 37 placeBoxes method, but takes an end position that may occur before the end 38 of the line. 39 * rendering/RenderBlock.cpp: 40 (WebCore::RenderBlock::exclusionShapeInsideInfo): Factored out calls 41 to ExclusionShapeInsideInfo to the .cpp file, as ExclusionShapeInsideInfo 42 requires InlineIterator.h, which would create a circular dependency in 43 ExclusionShapeInsideInfo.h. 44 * rendering/RenderBlock.h: 45 (WebCore::RenderBlock::exclusionShapeInsideInfo): Modified to call 46 exclusionShapeInsideInfo to be non-inline. 47 * rendering/RenderBlockLineLayout.cpp: 48 (WebCore::LineWidth::LineWidth): LineWidth now uses the number of computed 49 segmentRanges to determine which LineSegment to use when calculating width. 50 (WebCore::RenderBlock::createLineBoxes): Now takes a boolean to determine 51 whether or not it can share the same parentBox as its siblings (segments 52 must be able to position themselves separately in the RootInlineBox). 53 (WebCore::RenderBlock::constructLine): 54 (WebCore::computeExpansionForJustifiedText): Do include runs that start new 55 segments when calculating justification for the current segment. 56 (WebCore::RenderBlock::computeInlineDirectionPositionsForLine): Modified to 57 use the computeInlineDirectionPositionsForSegment, which can position 58 multiple segments of text per line. 59 (WebCore::RenderBlock::computeInlineDirectionPositionsForSegment): Positions 60 the given segment of text and calculates its layout offsets. 61 (WebCore::constructBidiRuns): Modified some variables from 'endOfLine' to 'endOfSegment'. 62 (WebCore::constructBidiRunsForLine): Construct the bidi runs for each segment in 63 the given line. 64 (WebCore::RenderBlock::layoutRunsAndFloatsInRange): Call constructBidiRunsForLine. 65 (WebCore::RenderBlock::LineBreaker::nextLineBreak): Moved the line breaking code 66 to break segments, with nextLineBreak iterating over segment breaks for the entire line. 67 (WebCore::RenderBlock::LineBreaker::nextSegmentBreak): Calculates how much text a 68 segment can hold. This code was originally in nextLineBreak. 69 1 70 2012-12-05 Stephen White <senorblanco@chromium.org> 2 71 -
trunk/Source/WebCore/platform/text/BidiResolver.h
r133713 r136729 148 148 149 149 // Do not add anything apart from bitfields until after m_next. See https://bugs.webkit.org/show_bug.cgi?id=100173 150 bool m_override:1; 151 bool m_hasHyphen:1; // Used by BidiRun subclass which is a layering violation but enables us to save 8 bytes per object on 64-bit. 150 bool m_override : 1; 151 bool m_hasHyphen : 1; // Used by BidiRun subclass which is a layering violation but enables us to save 8 bytes per object on 64-bit. 152 #if ENABLE(CSS_EXCLUSIONS) 153 bool m_startsSegment : 1; // Same comment as m_hasHyphen. 154 #endif 152 155 unsigned char m_level; 153 156 BidiCharacterRun* m_next; -
trunk/Source/WebCore/rendering/BidiRun.h
r133713 r136729 40 40 , m_box(0) 41 41 { 42 m_hasHyphen = false; // Stored in base class to save space. 42 // Stored in base class to save space. 43 m_hasHyphen = false; 44 #if ENABLE(CSS_EXCLUSIONS) 45 m_startsSegment = false; 46 #endif 43 47 } 44 48 -
trunk/Source/WebCore/rendering/ExclusionShapeInsideInfo.cpp
r135314 r136729 110 110 m_lineHeight = lineHeight; 111 111 m_segments.clear(); 112 m_segmentRanges.clear(); 112 113 113 114 if (lineOverlapsShapeBounds()) { -
trunk/Source/WebCore/rendering/ExclusionShapeInsideInfo.h
r133779 r136729 35 35 #include "ExclusionShape.h" 36 36 #include "FloatRect.h" 37 #include "InlineIterator.h" 37 38 #include "LayoutUnit.h" 38 39 #include <wtf/OwnPtr.h> … … 43 44 44 45 class RenderBlock; 46 47 struct LineSegmentRange { 48 InlineIterator start; 49 InlineIterator end; 50 LineSegmentRange(InlineIterator start, InlineIterator end) 51 : start(start) 52 , end(end) 53 { 54 } 55 }; 56 typedef Vector<LineSegmentRange> SegmentRangeList; 45 57 46 58 class ExclusionShapeInsideInfo { … … 67 79 ASSERT(hasSegments()); 68 80 return m_segments; 81 } 82 SegmentRangeList& segmentRanges() { return m_segmentRanges; } 83 const SegmentRangeList& segmentRanges() const { return m_segmentRanges; } 84 const LineSegment* currentSegment() const 85 { 86 if (!hasSegments()) 87 return 0; 88 ASSERT(m_segmentRanges.size() < m_segments.size()); 89 return &m_segments[m_segmentRanges.size()]; 69 90 } 70 91 bool computeSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineHeight); … … 98 119 99 120 SegmentList m_segments; 121 SegmentRangeList m_segmentRanges; 100 122 bool m_shapeSizeDirty; 101 123 }; -
trunk/Source/WebCore/rendering/InlineFlowBox.cpp
r136640 r136729 370 370 { 371 371 // Set our x position. 372 setLogicalLeft(logicalLeft);373 372 beginPlacingBoxRangesInInlineDirection(logicalLeft); 373 374 374 float startLogicalLeft = logicalLeft; 375 375 logicalLeft += borderLogicalLeft() + paddingLogicalLeft(); … … 378 378 float maxLogicalRight = logicalLeft; 379 379 380 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { 380 placeBoxRangeInInlineDirection(firstChild(), 0, logicalLeft, minLogicalLeft, maxLogicalRight, needsWordSpacing, textBoxDataMap); 381 382 logicalLeft += borderLogicalRight() + paddingLogicalRight(); 383 endPlacingBoxRangesInInlineDirection(startLogicalLeft, logicalLeft, minLogicalLeft, maxLogicalRight); 384 return logicalLeft; 385 } 386 387 float InlineFlowBox::placeBoxRangeInInlineDirection(InlineBox* firstChild, InlineBox* lastChild, float& logicalLeft, float& minLogicalLeft, float& maxLogicalRight, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap& textBoxDataMap) 388 { 389 for (InlineBox* curr = firstChild; curr && curr != lastChild; curr = curr->nextOnLine()) { 381 390 if (curr->renderer()->isText()) { 382 391 InlineTextBox* text = toInlineTextBox(curr); … … 430 439 } 431 440 } 432 433 logicalLeft += borderLogicalRight() + paddingLogicalRight();434 setLogicalWidth(logicalLeft - startLogicalLeft);435 if (knownToHaveNoOverflow() && (minLogicalLeft < startLogicalLeft || maxLogicalRight > logicalLeft))436 clearKnownToHaveNoOverflow();437 441 return logicalLeft; 438 442 } -
trunk/Source/WebCore/rendering/InlineFlowBox.h
r135750 r136729 174 174 LayoutUnit getFlowSpacingLogicalWidth(); 175 175 float placeBoxesInInlineDirection(float logicalLeft, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap&); 176 float placeBoxRangeInInlineDirection(InlineBox* firstChild, InlineBox* lastChild, float& logicalLeft, float& minLogicalLeft, float& maxLogicalRight, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap&); 177 void beginPlacingBoxRangesInInlineDirection(float logicalLeft) { setLogicalLeft(logicalLeft); } 178 void endPlacingBoxRangesInInlineDirection(float logicalLeft, float logicalRight, float minLogicalLeft, float maxLogicalRight) 179 { 180 setLogicalWidth(logicalRight - logicalLeft); 181 if (knownToHaveNoOverflow() && (minLogicalLeft < logicalLeft || maxLogicalRight > logicalRight)) 182 clearKnownToHaveNoOverflow(); 183 } 184 176 185 void computeLogicalBoxHeights(RootInlineBox*, LayoutUnit& maxPositionTop, LayoutUnit& maxPositionBottom, 177 186 int& maxAscent, int& maxDescent, bool& setMaxAscent, bool& setMaxDescent, -
trunk/Source/WebCore/rendering/RenderBlock.cpp
r136288 r136729 1398 1398 1399 1399 #if ENABLE(CSS_EXCLUSIONS) 1400 ExclusionShapeInsideInfo* RenderBlock::exclusionShapeInsideInfo() const 1401 { 1402 return style()->shapeInside() && ExclusionShapeInsideInfo::isExclusionShapeInsideInfoEnabledForRenderBlock(this) ? ExclusionShapeInsideInfo::exclusionShapeInsideInfoForRenderBlock(this) : 0; 1403 } 1404 1400 1405 void RenderBlock::updateExclusionShapeInsideInfoAfterStyleChange(const ExclusionShapeValue* shapeInside, const ExclusionShapeValue* oldShapeInside) 1401 1406 { -
trunk/Source/WebCore/rendering/RenderBlock.h
r136288 r136729 36 36 37 37 #if ENABLE(CSS_EXCLUSIONS) 38 #include "ExclusionShapeInsideInfo.h"39 38 #include "ExclusionShapeValue.h" 40 39 #endif … … 54 53 class LineInfo; 55 54 class RenderRubyRun; 55 #if ENABLE(CSS_EXCLUSIONS) 56 class BasicShape; 57 class ExclusionShapeInsideInfo; 58 #endif 56 59 class TextLayout; 57 60 class WordMeasurement; … … 426 429 427 430 #if ENABLE(CSS_EXCLUSIONS) 428 ExclusionShapeInsideInfo* exclusionShapeInsideInfo() const 429 { 430 return style()->shapeInside() && ExclusionShapeInsideInfo::isExclusionShapeInsideInfoEnabledForRenderBlock(this) ? ExclusionShapeInsideInfo::exclusionShapeInsideInfoForRenderBlock(this) : 0; 431 } 431 ExclusionShapeInsideInfo* exclusionShapeInsideInfo() const; 432 432 #endif 433 433 … … 764 764 void reset(); 765 765 766 InlineIterator nextSegmentBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements&); 766 767 void skipTrailingWhitespace(InlineIterator&, const LineInfo&); 767 768 void skipLeadingWhitespace(InlineBidiResolver&, LineInfo&, FloatingObject* lastFloatFromPreviousLine, LineWidth&); … … 780 781 781 782 RootInlineBox* constructLine(BidiRunList<BidiRun>&, const LineInfo&); 782 InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox );783 InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox, bool startsNewSegment); 783 784 784 785 void setMarginsForRubyRun(BidiRun*, RenderRubyRun*, RenderObject*, const LineInfo&); 785 786 787 BidiRun* computeInlineDirectionPositionsForSegment(RootInlineBox*, const LineInfo&, ETextAlign, float& logicalLeft, 788 float& availableLogicalWidth, BidiRun* firstRun, BidiRun* trailingSpaceRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache&, WordMeasurements&); 786 789 void computeInlineDirectionPositionsForLine(RootInlineBox*, const LineInfo&, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&, WordMeasurements&); 787 790 void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&); -
trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp
r136034 r136729 89 89 #if ENABLE(CSS_EXCLUSIONS) 90 90 ExclusionShapeInsideInfo* exclusionShapeInsideInfo = layoutExclusionShapeInsideInfo(m_block); 91 // FIXME: Bug 91878: Add support for multiple segments, currently we only support one 92 if (exclusionShapeInsideInfo && exclusionShapeInsideInfo->hasSegments()) 93 m_segment = &exclusionShapeInsideInfo->segments()[0]; 91 if (exclusionShapeInsideInfo) 92 m_segment = exclusionShapeInsideInfo->currentSegment(); 94 93 #endif 95 94 updateAvailableWidth(); … … 451 450 } 452 451 453 InlineFlowBox* RenderBlock::createLineBoxes(RenderObject* obj, const LineInfo& lineInfo, InlineBox* childBox )452 InlineFlowBox* RenderBlock::createLineBoxes(RenderObject* obj, const LineInfo& lineInfo, InlineBox* childBox, bool startNewSegment) 454 453 { 455 454 // See if we have an unconstructed line box for this object that is also … … 474 473 bool constructedNewBox = false; 475 474 bool allowedToConstructNewBox = !hasDefaultLineBoxContain || !inlineFlow || inlineFlow->alwaysCreateLineBoxes(); 476 bool canUseExistingParentBox = parentBox && !parentIsConstructedOrHaveNext(parentBox); 475 bool mustCreateBoxesToRoot = startNewSegment && !(parentBox && parentBox->isRootInlineBox()); 476 bool canUseExistingParentBox = parentBox && !parentIsConstructedOrHaveNext(parentBox) && !mustCreateBoxesToRoot; 477 477 if (allowedToConstructNewBox && !canUseExistingParentBox) { 478 478 // We need to make a new box for this render object. Once … … 571 571 // If we have no parent box yet, or if the run is not simply a sibling, 572 572 // then we need to construct inline boxes as necessary to properly enclose the 573 // run's inline box. 574 if (!parentBox || parentBox->renderer() != r->m_object->parent()) 573 // run's inline box. Segments can only be siblings at the root level, as 574 // they are positioned separately. 575 #if ENABLE(CSS_EXCLUSIONS) 576 bool runStartsSegment = r->m_startsSegment; 577 #else 578 bool runStartsSegment = false; 579 #endif 580 if (!parentBox || parentBox->renderer() != r->m_object->parent() || runStartsSegment) 575 581 // Create new inline boxes all the way back to the appropriate insertion point. 576 parentBox = createLineBoxes(r->m_object->parent(), lineInfo, box );582 parentBox = createLineBoxes(r->m_object->parent(), lineInfo, box, runStartsSegment); 577 583 else { 578 584 // Append the inline box to this line. … … 809 815 size_t i = 0; 810 816 for (BidiRun* r = firstRun; r; r = r->next()) { 817 #if ENABLE(CSS_EXCLUSIONS) 818 // This method is called once per segment, do not move past the current segment. 819 if (r->m_startsSegment) 820 break; 821 #endif 811 822 if (!r->m_box || r == trailingSpaceRun) 812 823 continue; … … 884 895 // box is only affected if it is the first child of its parent element." 885 896 bool firstLine = lineInfo.isFirstLine() && !(isAnonymousBlock() && parent()->firstChild() != this); 886 float logicalLeft = pixelSnappedLogicalLeftOffsetForLine(logicalHeight(), firstLine, lineLogicalHeight); 887 float logicalRight = pixelSnappedLogicalRightOffsetForLine(logicalHeight(), firstLine, lineLogicalHeight); 897 float lineLogicalLeft = pixelSnappedLogicalLeftOffsetForLine(logicalHeight(), firstLine, lineLogicalHeight); 898 float lineLogicalRight = pixelSnappedLogicalRightOffsetForLine(logicalHeight(), firstLine, lineLogicalHeight); 899 float availableLogicalWidth; 900 bool needsWordSpacing; 888 901 #if ENABLE(CSS_EXCLUSIONS) 889 902 ExclusionShapeInsideInfo* exclusionShapeInsideInfo = layoutExclusionShapeInsideInfo(this); 890 903 if (exclusionShapeInsideInfo && exclusionShapeInsideInfo->hasSegments()) { 891 logicalLeft = max<float>(roundToInt(exclusionShapeInsideInfo->segments()[0].logicalLeft), logicalLeft); 892 logicalRight = min<float>(floorToInt(exclusionShapeInsideInfo->segments()[0].logicalRight), logicalRight); 904 BidiRun* segmentStart = firstRun; 905 const SegmentList& segments = exclusionShapeInsideInfo->segments(); 906 float logicalLeft = max<float>(roundToInt(segments[0].logicalLeft), lineLogicalLeft); 907 float logicalRight = min<float>(floorToInt(segments[0].logicalRight), lineLogicalRight); 908 float startLogicalLeft = logicalLeft; 909 float endLogicalRight = logicalLeft; 910 float minLogicalLeft = logicalLeft; 911 float maxLogicalRight = logicalLeft; 912 lineBox->beginPlacingBoxRangesInInlineDirection(logicalLeft); 913 for (size_t i = 0; i < segments.size(); i++) { 914 if (i) { 915 logicalLeft = max<float>(roundToInt(segments[i].logicalLeft), lineLogicalLeft); 916 logicalRight = min<float>(floorToInt(segments[i].logicalRight), lineLogicalRight); 917 } 918 availableLogicalWidth = logicalRight - logicalLeft; 919 BidiRun* newSegmentStart = computeInlineDirectionPositionsForSegment(lineBox, lineInfo, textAlign, logicalLeft, availableLogicalWidth, segmentStart, trailingSpaceRun, textBoxDataMap, verticalPositionCache, wordMeasurements); 920 needsWordSpacing = false; 921 endLogicalRight = lineBox->placeBoxRangeInInlineDirection(segmentStart->m_box, newSegmentStart ? newSegmentStart->m_box : 0, logicalLeft, minLogicalLeft, maxLogicalRight, needsWordSpacing, textBoxDataMap); 922 if (!newSegmentStart || !newSegmentStart->next()) 923 break; 924 ASSERT(newSegmentStart->m_startsSegment); 925 // Discard the empty segment start marker bidi runs 926 segmentStart = newSegmentStart->next(); 927 } 928 lineBox->endPlacingBoxRangesInInlineDirection(startLogicalLeft, endLogicalRight, minLogicalLeft, maxLogicalRight); 929 return; 893 930 } 894 931 #endif 895 float availableLogicalWidth = logicalRight - logicalLeft; 896 932 availableLogicalWidth = lineLogicalRight - lineLogicalLeft; 933 computeInlineDirectionPositionsForSegment(lineBox, lineInfo, textAlign, lineLogicalLeft, availableLogicalWidth, firstRun, trailingSpaceRun, textBoxDataMap, verticalPositionCache, wordMeasurements); 934 // The widths of all runs are now known. We can now place every inline box (and 935 // compute accurate widths for the inline flow boxes). 936 needsWordSpacing = false; 937 lineBox->placeBoxesInInlineDirection(lineLogicalLeft, needsWordSpacing, textBoxDataMap); 938 } 939 940 BidiRun* RenderBlock::computeInlineDirectionPositionsForSegment(RootInlineBox* lineBox, const LineInfo& lineInfo, ETextAlign textAlign, float& logicalLeft, 941 float& availableLogicalWidth, BidiRun* firstRun, BidiRun* trailingSpaceRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache, 942 WordMeasurements& wordMeasurements) 943 { 897 944 bool needsWordSpacing = false; 898 945 float totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth(); … … 902 949 RenderObject* previousObject = 0; 903 950 904 for (BidiRun* r = firstRun; r; r = r->next()) { 951 BidiRun* r = firstRun; 952 for (; r; r = r->next()) { 953 #if ENABLE(CSS_EXCLUSIONS) 954 // Once we have reached the start of the next segment, we have finished 955 // computing the positions for this segment's contents. 956 if (r->m_startsSegment) 957 break; 958 #endif 905 959 if (!r->m_box || r->m_object->isOutOfFlowPositioned() || r->m_box->isLineBreak()) 906 960 continue; // Positioned objects are only participating to figure out their … … 952 1006 computeExpansionForJustifiedText(firstRun, trailingSpaceRun, expansionOpportunities, expansionOpportunityCount, totalLogicalWidth, availableLogicalWidth); 953 1007 954 // The widths of all runs are now known. We can now place every inline box (and 955 // compute accurate widths for the inline flow boxes). 956 needsWordSpacing = false; 957 lineBox->placeBoxesInInlineDirection(logicalLeft, needsWordSpacing, textBoxDataMap); 1008 return r; 958 1009 } 959 1010 … … 1102 1153 1103 1154 // FIXME: BidiResolver should have this logic. 1104 static inline void constructBidiRuns (InlineBidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfLine, VisualDirectionOverride override, bool previousLineBrokeCleanly)1155 static inline void constructBidiRunsForSegment(InlineBidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfRuns, VisualDirectionOverride override, bool previousLineBrokeCleanly) 1105 1156 { 1106 1157 // FIXME: We should pass a BidiRunList into createBidiRunsForLine instead … … 1108 1159 ASSERT(&topResolver.runs() == &bidiRuns); 1109 1160 RenderObject* currentRoot = topResolver.position().root(); 1110 topResolver.createBidiRunsForLine(endOf Line, override, previousLineBrokeCleanly);1161 topResolver.createBidiRunsForLine(endOfRuns, override, previousLineBrokeCleanly); 1111 1162 1112 1163 while (!topResolver.isolatedRuns().isEmpty()) { … … 1148 1199 // FIXME: What should end and previousLineBrokeCleanly be? 1149 1200 // rniwa says previousLineBrokeCleanly is just a WinIE hack and could always be false here? 1150 isolatedResolver.createBidiRunsForLine(endOf Line, NoVisualOverride, previousLineBrokeCleanly);1201 isolatedResolver.createBidiRunsForLine(endOfRuns, NoVisualOverride, previousLineBrokeCleanly); 1151 1202 // Note that we do not delete the runs from the resolver. 1152 1203 // We're not guaranteed to get any BidiRuns in the previous step. If we don't, we allow the placeholder … … 1163 1214 } 1164 1215 } 1216 } 1217 1218 static inline void constructBidiRunsForLine(const RenderBlock* block, InlineBidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfLine, VisualDirectionOverride override, bool previousLineBrokeCleanly) 1219 { 1220 #if !ENABLE(CSS_EXCLUSIONS) 1221 UNUSED_PARAM(block); 1222 constructBidiRunsForSegment(topResolver, bidiRuns, endOfLine, override, previousLineBrokeCleanly); 1223 #else 1224 ExclusionShapeInsideInfo* exclusionShapeInsideInfo = layoutExclusionShapeInsideInfo(block); 1225 if (!exclusionShapeInsideInfo || !exclusionShapeInsideInfo->hasSegments()) { 1226 constructBidiRunsForSegment(topResolver, bidiRuns, endOfLine, override, previousLineBrokeCleanly); 1227 return; 1228 } 1229 1230 const SegmentRangeList& segmentRanges = exclusionShapeInsideInfo->segmentRanges(); 1231 ASSERT(segmentRanges.size()); 1232 1233 for (size_t i = 0; i < segmentRanges.size(); i++) { 1234 InlineIterator segmentStart = segmentRanges[i].start; 1235 InlineIterator segmentEnd = segmentRanges[i].end; 1236 if (i) { 1237 ASSERT(segmentStart.m_obj); 1238 BidiRun* segmentMarker = createRun(segmentStart.m_pos, segmentStart.m_pos, segmentStart.m_obj, topResolver); 1239 segmentMarker->m_startsSegment = true; 1240 bidiRuns.addRun(segmentMarker); 1241 // Do not collapse midpoints between segments 1242 topResolver.midpointState().betweenMidpoints = false; 1243 } 1244 topResolver.setPosition(segmentStart, numberOfIsolateAncestors(segmentStart)); 1245 constructBidiRunsForSegment(topResolver, bidiRuns, segmentEnd, override, previousLineBrokeCleanly); 1246 } 1247 #endif 1165 1248 } 1166 1249 … … 1462 1545 // FIXME: This ownership is reversed. We should own the BidiRunList and pass it to createBidiRunsForLine. 1463 1546 BidiRunList<BidiRun>& bidiRuns = resolver.runs(); 1464 constructBidiRuns (resolver, bidiRuns, end, override, layoutState.lineInfo().previousLineBrokeCleanly());1547 constructBidiRunsForLine(this, resolver, bidiRuns, end, override, layoutState.lineInfo().previousLineBrokeCleanly()); 1465 1548 ASSERT(resolver.position() == end); 1466 1549 … … 2323 2406 2324 2407 InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wordMeasurements) 2408 { 2409 #if !ENABLE(CSS_EXCLUSIONS) 2410 return nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements); 2411 #else 2412 ExclusionShapeInsideInfo* exclusionShapeInsideInfo = layoutExclusionShapeInsideInfo(m_block); 2413 if (!exclusionShapeInsideInfo || !exclusionShapeInsideInfo->hasSegments()) 2414 return nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements); 2415 2416 InlineIterator end = resolver.position(); 2417 InlineIterator oldEnd = end; 2418 2419 const SegmentList& segments = exclusionShapeInsideInfo->segments(); 2420 SegmentRangeList& segmentRanges = exclusionShapeInsideInfo->segmentRanges(); 2421 2422 for (unsigned i = 0; i < segments.size(); i++) { 2423 InlineIterator segmentStart = resolver.position(); 2424 end = nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements); 2425 2426 ASSERT(segmentRanges.size() == i); 2427 if (resolver.position() == end) { 2428 // Nothing fit this segment 2429 segmentRanges.append(LineSegmentRange(segmentStart, segmentStart)); 2430 resolver.setPositionIgnoringNestedIsolates(segmentStart); 2431 } else { 2432 // Note that resolver.position is already skipping some of the white space at the beginning of the line, 2433 // so that's why segmentStart might be different than resolver.position(). 2434 LineSegmentRange range(resolver.position(), end); 2435 segmentRanges.append(range); 2436 resolver.setPosition(end, numberOfIsolateAncestors(end)); 2437 2438 if (lineInfo.previousLineBrokeCleanly()) { 2439 // If we hit a new line break, just stop adding anything to this line. 2440 break; 2441 } 2442 } 2443 } 2444 resolver.setPositionIgnoringNestedIsolates(oldEnd); 2445 return end; 2446 #endif 2447 } 2448 2449 InlineIterator RenderBlock::LineBreaker::nextSegmentBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wordMeasurements) 2325 2450 { 2326 2451 reset(); … … 2905 3030 } 2906 3031 3032 // FIXME Bug 100049: We do not need to consume input in a multi-segment line 3033 // unless no segment will. 2907 3034 // make sure we consume at least one char/object. 2908 3035 if (lBreak == resolver.position())
Note: See TracChangeset
for help on using the changeset viewer.