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

Side by Side Diff: Source/core/rendering/RenderBlockLineLayout.cpp

Issue 209443007: Remove shape-inside support (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fix more (all?) tests Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 592 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 // CSS3 "text-indent", "each-line" affects the first line of the block conta iner as well as each line after a forced line break, 603 // CSS3 "text-indent", "each-line" affects the first line of the block conta iner as well as each line after a forced line break,
604 // but does not affect lines after a soft wrap break. 604 // but does not affect lines after a soft wrap break.
605 bool isFirstLine = lineInfo.isFirstLine() && !(isAnonymousBlock() && parent( )->firstChild() != this); 605 bool isFirstLine = lineInfo.isFirstLine() && !(isAnonymousBlock() && parent( )->firstChild() != this);
606 bool isAfterHardLineBreak = lineBox->prevRootBox() && lineBox->prevRootBox() ->endsWithBreak(); 606 bool isAfterHardLineBreak = lineBox->prevRootBox() && lineBox->prevRootBox() ->endsWithBreak();
607 IndentTextOrNot shouldIndentText = requiresIndent(isFirstLine, isAfterHardLi neBreak, style()); 607 IndentTextOrNot shouldIndentText = requiresIndent(isFirstLine, isAfterHardLi neBreak, style());
608 float lineLogicalLeft; 608 float lineLogicalLeft;
609 float lineLogicalRight; 609 float lineLogicalRight;
610 float availableLogicalWidth; 610 float availableLogicalWidth;
611 updateLogicalInlinePositions(this, lineLogicalLeft, lineLogicalRight, availa bleLogicalWidth, isFirstLine, shouldIndentText, 0); 611 updateLogicalInlinePositions(this, lineLogicalLeft, lineLogicalRight, availa bleLogicalWidth, isFirstLine, shouldIndentText, 0);
612 bool needsWordSpacing; 612 bool needsWordSpacing;
613 ShapeInsideInfo* shapeInsideInfo = layoutShapeInsideInfo();
614 if (shapeInsideInfo && shapeInsideInfo->hasSegments()) {
615 BidiRun* segmentStart = firstRun;
616 const SegmentList& segments = shapeInsideInfo->segments();
617 float logicalLeft = max<float>(segments[0].logicalLeft, lineLogicalLeft) ;
618 float logicalRight = min<float>(segments[0].logicalRight, lineLogicalRig ht);
619 float startLogicalLeft = logicalLeft;
620 float endLogicalRight = logicalLeft;
621 float minLogicalLeft = logicalLeft;
622 float maxLogicalRight = logicalLeft;
623 lineBox->beginPlacingBoxRangesInInlineDirection(logicalLeft);
624 for (size_t i = 0; i < segments.size(); i++) {
625 if (i) {
626 logicalLeft = max<float>(segments[i].logicalLeft, lineLogicalLef t);
627 logicalRight = min<float>(segments[i].logicalRight, lineLogicalR ight);
628 }
629 availableLogicalWidth = logicalRight - logicalLeft;
630 BidiRun* newSegmentStart = computeInlineDirectionPositionsForSegment (lineBox, lineInfo, textAlign, logicalLeft, availableLogicalWidth, segmentStart, trailingSpaceRun, textBoxDataMap, verticalPositionCache, wordMeasurements);
631 needsWordSpacing = false;
632 endLogicalRight = lineBox->placeBoxRangeInInlineDirection(segmentSta rt->m_box, newSegmentStart ? newSegmentStart->m_box : 0, logicalLeft, minLogical Left, maxLogicalRight, needsWordSpacing, textBoxDataMap);
633 if (!newSegmentStart || !newSegmentStart->next())
634 break;
635 ASSERT(newSegmentStart->m_startsSegment);
636 // Discard the empty segment start marker bidi runs
637 segmentStart = newSegmentStart->next();
638 }
639 lineBox->endPlacingBoxRangesInInlineDirection(startLogicalLeft, endLogic alRight, minLogicalLeft, maxLogicalRight);
640 return;
641 }
642 613
643 if (firstRun && firstRun->m_object->isReplaced()) { 614 if (firstRun && firstRun->m_object->isReplaced()) {
644 RenderBox* renderBox = toRenderBox(firstRun->m_object); 615 RenderBox* renderBox = toRenderBox(firstRun->m_object);
645 updateLogicalInlinePositions(this, lineLogicalLeft, lineLogicalRight, av ailableLogicalWidth, isFirstLine, shouldIndentText, renderBox->logicalHeight()); 616 updateLogicalInlinePositions(this, lineLogicalLeft, lineLogicalRight, av ailableLogicalWidth, isFirstLine, shouldIndentText, renderBox->logicalHeight());
646 } 617 }
647 618
648 computeInlineDirectionPositionsForSegment(lineBox, lineInfo, textAlign, line LogicalLeft, availableLogicalWidth, firstRun, trailingSpaceRun, textBoxDataMap, verticalPositionCache, wordMeasurements); 619 computeInlineDirectionPositionsForSegment(lineBox, lineInfo, textAlign, line LogicalLeft, availableLogicalWidth, firstRun, trailingSpaceRun, textBoxDataMap, verticalPositionCache, wordMeasurements);
649 // The widths of all runs are now known. We can now place every inline box ( and 620 // The widths of all runs are now known. We can now place every inline box ( and
650 // compute accurate widths for the inline flow boxes). 621 // compute accurate widths for the inline flow boxes).
651 needsWordSpacing = false; 622 needsWordSpacing = false;
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
852 } 823 }
853 } 824 }
854 825
855 static inline bool segmentIsEmpty(const InlineIterator& segmentStart, const Inli neIterator& segmentEnd) 826 static inline bool segmentIsEmpty(const InlineIterator& segmentStart, const Inli neIterator& segmentEnd)
856 { 827 {
857 return segmentStart == segmentEnd; 828 return segmentStart == segmentEnd;
858 } 829 }
859 830
860 static inline void constructBidiRunsForLine(const RenderBlockFlow* block, Inline BidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfLine, VisualDirectionOverride override, bool previousLineBrokeCleanly, boo l isNewUBAParagraph) 831 static inline void constructBidiRunsForLine(const RenderBlockFlow* block, Inline BidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfLine, VisualDirectionOverride override, bool previousLineBrokeCleanly, boo l isNewUBAParagraph)
861 { 832 {
862 ShapeInsideInfo* shapeInsideInfo = block->layoutShapeInsideInfo(); 833 constructBidiRunsForSegment(topResolver, bidiRuns, endOfLine, override, prev iousLineBrokeCleanly, isNewUBAParagraph);
863 if (!shapeInsideInfo || !shapeInsideInfo->hasSegments()) {
864 constructBidiRunsForSegment(topResolver, bidiRuns, endOfLine, override, previousLineBrokeCleanly, isNewUBAParagraph);
865 return;
866 }
867
868 const SegmentRangeList& segmentRanges = shapeInsideInfo->segmentRanges();
869 ASSERT(segmentRanges.size());
870
871 for (size_t i = 0; i < segmentRanges.size(); i++) {
872 LineSegmentIterator iterator = segmentRanges[i].start;
873 InlineIterator segmentStart(iterator.root, iterator.object, iterator.off set);
874 iterator = segmentRanges[i].end;
875 InlineIterator segmentEnd(iterator.root, iterator.object, iterator.offse t);
876 if (i) {
877 ASSERT(segmentStart.object());
878 BidiRun* segmentMarker = createRun(segmentStart.offset(), segmentSta rt.offset(), segmentStart.object(), topResolver);
879 segmentMarker->m_startsSegment = true;
880 bidiRuns.addRun(segmentMarker);
881 // Do not collapse midpoints between segments
882 topResolver.midpointState().setBetweenMidpoints(false);
883 }
884 if (!segmentIsEmpty(segmentStart, segmentEnd)) {
885 topResolver.setPosition(segmentStart, numberOfIsolateAncestors(segme ntStart));
886 constructBidiRunsForSegment(topResolver, bidiRuns, segmentEnd, overr ide, previousLineBrokeCleanly, isNewUBAParagraph);
887 }
888 }
889 } 834 }
890 835
891 // This function constructs line boxes for all of the text runs in the resolver and computes their position. 836 // This function constructs line boxes for all of the text runs in the resolver and computes their position.
892 RootInlineBox* RenderBlockFlow::createLineBoxesFromBidiRuns(unsigned bidiLevel, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end, LineInfo& lineInfo, V erticalPositionCache& verticalPositionCache, BidiRun* trailingSpaceRun, WordMeas urements& wordMeasurements) 837 RootInlineBox* RenderBlockFlow::createLineBoxesFromBidiRuns(unsigned bidiLevel, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end, LineInfo& lineInfo, V erticalPositionCache& verticalPositionCache, BidiRun* trailingSpaceRun, WordMeas urements& wordMeasurements)
893 { 838 {
894 if (!bidiRuns.runCount()) 839 if (!bidiRuns.runCount())
895 return 0; 840 return 0;
896 841
897 // FIXME: Why is this only done when we had runs? 842 // FIXME: Why is this only done when we had runs?
898 lineInfo.setLastLine(!end.object()); 843 lineInfo.setLastLine(!end.object());
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1005 950
1006 // Before restarting the layout loop with a new logicalHeight, remove all floats that were added and reset the resolver. 951 // Before restarting the layout loop with a new logicalHeight, remove all floats that were added and reset the resolver.
1007 inline const InlineIterator& RenderBlockFlow::restartLayoutRunsAndFloatsInRange( LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight, FloatingObject* lastF loatFromPreviousLine, InlineBidiResolver& resolver, const InlineIterator& oldEn d) 952 inline const InlineIterator& RenderBlockFlow::restartLayoutRunsAndFloatsInRange( LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight, FloatingObject* lastF loatFromPreviousLine, InlineBidiResolver& resolver, const InlineIterator& oldEn d)
1008 { 953 {
1009 removeFloatingObjectsBelow(lastFloatFromPreviousLine, oldLogicalHeight); 954 removeFloatingObjectsBelow(lastFloatFromPreviousLine, oldLogicalHeight);
1010 setLogicalHeight(newLogicalHeight); 955 setLogicalHeight(newLogicalHeight);
1011 resolver.setPositionIgnoringNestedIsolates(oldEnd); 956 resolver.setPositionIgnoringNestedIsolates(oldEnd);
1012 return oldEnd; 957 return oldEnd;
1013 } 958 }
1014 959
1015 static inline LayoutUnit adjustLogicalLineTop(ShapeInsideInfo* shapeInsideInfo, InlineIterator start, InlineIterator end, const WordMeasurements& wordMeasuremen ts)
1016 {
1017 if (!shapeInsideInfo || end != start)
1018 return 0;
1019
1020 float minWidth = firstPositiveWidth(wordMeasurements);
1021 ASSERT(minWidth || wordMeasurements.isEmpty());
1022 if (minWidth > 0 && shapeInsideInfo->adjustLogicalLineTop(minWidth))
1023 return shapeInsideInfo->logicalLineTop();
1024
1025 return shapeInsideInfo->shapeLogicalBottom();
1026 }
1027
1028 static inline void pushShapeContentOverflowBelowTheContentBox(RenderBlockFlow* b lock, ShapeInsideInfo* shapeInsideInfo, LayoutUnit lineTop, LayoutUnit lineHeigh t)
1029 {
1030 ASSERT(shapeInsideInfo);
1031
1032 LayoutUnit logicalLineBottom = lineTop + lineHeight;
1033 LayoutUnit shapeLogicalBottom = shapeInsideInfo->shapeLogicalBottom();
1034 LayoutUnit shapeContainingBlockHeight = shapeInsideInfo->shapeContainingBloc kHeight();
1035
1036 bool isOverflowPositionedAlready = (shapeContainingBlockHeight - shapeInside Info->owner().borderAndPaddingAfter() + lineHeight) <= lineTop;
1037
1038 // If the last line overlaps with the shape, we don't need the segments anym ore
1039 if (lineTop < shapeLogicalBottom && shapeLogicalBottom < logicalLineBottom)
1040 shapeInsideInfo->clearSegments();
1041 if (logicalLineBottom <= shapeLogicalBottom || !shapeContainingBlockHeight | | isOverflowPositionedAlready)
1042 return;
1043
1044 LayoutUnit newLogicalHeight = block->logicalHeight() + (shapeContainingBlock Height - (lineTop + shapeInsideInfo->owner().borderAndPaddingAfter()));
1045 block->setLogicalHeight(newLogicalHeight);
1046 }
1047
1048 void RenderBlockFlow::updateShapeAndSegmentsForCurrentLine(ShapeInsideInfo*& sha peInsideInfo, const LayoutSize& logicalOffsetFromShapeContainer, LineLayoutState & layoutState)
1049 {
1050 if (layoutState.flowThread())
1051 return updateShapeAndSegmentsForCurrentLineInFlowThread(shapeInsideInfo, layoutState);
1052
1053 if (!shapeInsideInfo)
1054 return;
1055
1056 LayoutUnit lineTop = logicalHeight() + logicalOffsetFromShapeContainer.heigh t();
1057 LayoutUnit lineLeft = logicalOffsetFromShapeContainer.width();
1058 LayoutUnit lineHeight = this->lineHeight(layoutState.lineInfo().isFirstLine( ), isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInterior LineBoxes);
1059
1060 // FIXME: Bug 95361: It is possible for a line to grow beyond lineHeight, in which case these segments may be incorrect.
1061 shapeInsideInfo->updateSegmentsForLine(LayoutSize(lineLeft, lineTop), lineHe ight);
1062
1063 pushShapeContentOverflowBelowTheContentBox(this, shapeInsideInfo, lineTop, l ineHeight);
1064 }
1065
1066 void RenderBlockFlow::updateShapeAndSegmentsForCurrentLineInFlowThread(ShapeInsi deInfo*& shapeInsideInfo, LineLayoutState& layoutState)
1067 {
1068 ASSERT(layoutState.flowThread());
1069
1070 RenderRegion* currentRegion = regionAtBlockOffset(logicalHeight());
1071 if (!currentRegion || !currentRegion->logicalHeight())
1072 return;
1073
1074 shapeInsideInfo = currentRegion->shapeInsideInfo();
1075
1076 RenderRegion* nextRegion = 0;
1077 if (!currentRegion->isLastRegion()) {
1078 RenderRegionList regionList = layoutState.flowThread()->renderRegionList ();
1079 RenderRegionList::const_iterator it = regionList.find(currentRegion);
1080 nextRegion = *(++it);
1081 }
1082
1083 // We only want to deal regions with shapes, so we check if the next region has a shape
1084 if (!shapeInsideInfo && nextRegion && !nextRegion->shapeInsideInfo())
1085 return;
1086
1087 LayoutUnit lineHeight = this->lineHeight(layoutState.lineInfo().isFirstLine( ), isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInterior LineBoxes);
1088 LayoutUnit logicalLineTopInFlowThread = logicalHeight() + offsetFromLogicalT opOfFirstPage();
1089 LayoutUnit logicalLineBottomInFlowThread = logicalLineTopInFlowThread + line Height;
1090 LayoutUnit logicalRegionTopInFlowThread = currentRegion->logicalTopForFlowTh readContent();
1091 LayoutUnit logicalRegionBottomInFlowThread = logicalRegionTopInFlowThread + currentRegion->logicalHeight() - currentRegion->borderAndPaddingBefore() - curre ntRegion->borderAndPaddingAfter();
1092
1093 LayoutUnit shapeBottomInFlowThread = LayoutUnit::max();
1094 if (shapeInsideInfo)
1095 shapeBottomInFlowThread = shapeInsideInfo->shapeLogicalBottom() + curren tRegion->logicalTopForFlowThreadContent();
1096
1097 bool lineOverLapsWithShapeBottom = shapeBottomInFlowThread < logicalLineBott omInFlowThread;
1098 bool lineTopAdjustedIntoNextRegion = layoutState.adjustedLogicalLineTop() >= currentRegion->logicalHeight();
1099 bool lineOverLapsWithRegionBottom = logicalLineBottomInFlowThread > logicalR egionBottomInFlowThread || lineTopAdjustedIntoNextRegion;
1100 bool overFlowsToNextRegion = nextRegion && (lineOverLapsWithShapeBottom || l ineOverLapsWithRegionBottom);
1101
1102 // If the line is between two shapes/regions we position the line to the top of the next shape/region
1103 if (overFlowsToNextRegion) {
1104 ASSERT(currentRegion != nextRegion);
1105 LayoutUnit deltaToNextRegion = logicalRegionBottomInFlowThread - logical LineTopInFlowThread;
1106 setLogicalHeight(logicalHeight() + deltaToNextRegion);
1107
1108 currentRegion = nextRegion;
1109 shapeInsideInfo = currentRegion->shapeInsideInfo();
1110
1111 logicalLineTopInFlowThread = logicalHeight() + offsetFromLogicalTopOfFir stPage();
1112 logicalLineBottomInFlowThread = logicalLineTopInFlowThread + lineHeight;
1113 logicalRegionTopInFlowThread = currentRegion->logicalTopForFlowThreadCon tent();
1114 logicalRegionBottomInFlowThread = logicalRegionTopInFlowThread + current Region->logicalHeight() - currentRegion->borderAndPaddingBefore() - currentRegio n->borderAndPaddingAfter();
1115
1116 if (lineTopAdjustedIntoNextRegion)
1117 layoutState.setAdjustedLogicalLineTop(0);
1118 }
1119
1120 if (!shapeInsideInfo)
1121 return;
1122
1123 bool isFirstLineInRegion = logicalLineBottomInFlowThread <= (logicalRegionTo pInFlowThread + lineHeight);
1124 bool isFirstLineAdjusted = (logicalLineTopInFlowThread - logicalRegionTopInF lowThread) < (layoutState.adjustedLogicalLineTop() - currentRegion->borderAndPad dingBefore());
1125 // We position the first line to the top of the shape in the region or to th e previously adjusted position in the shape
1126 if (isFirstLineInRegion || isFirstLineAdjusted) {
1127 LayoutUnit shapeTopOffset = layoutState.adjustedLogicalLineTop();
1128 if (!shapeTopOffset && (shapeInsideInfo->shapeLogicalTop() > 0))
1129 shapeTopOffset = shapeInsideInfo->shapeLogicalTop();
1130
1131 LayoutUnit shapePositionInFlowThread = currentRegion->logicalTopForFlowT hreadContent() + shapeTopOffset;
1132 LayoutUnit shapeTopLineTopDelta = shapePositionInFlowThread - logicalLin eTopInFlowThread - currentRegion->borderAndPaddingBefore();
1133
1134 setLogicalHeight(logicalHeight() + shapeTopLineTopDelta);
1135 logicalLineTopInFlowThread += shapeTopLineTopDelta;
1136 layoutState.setAdjustedLogicalLineTop(0);
1137 }
1138
1139 LayoutUnit lineTop = logicalLineTopInFlowThread - currentRegion->logicalTopF orFlowThreadContent() + currentRegion->borderAndPaddingBefore();
1140 // FIXME: Shape inside on a region does not yet take into account its paddin g for nested flow blocks
1141 shapeInsideInfo->updateSegmentsForLine(LayoutSize(0, lineTop), lineHeight);
1142
1143 if (currentRegion->isLastRegion())
1144 pushShapeContentOverflowBelowTheContentBox(this, shapeInsideInfo, lineTo p, lineHeight);
1145 }
1146
1147 bool RenderBlockFlow::adjustLogicalLineTopAndLogicalHeightIfNeeded(ShapeInsideIn fo* shapeInsideInfo, LayoutUnit absoluteLogicalTop, LineLayoutState& layoutState , InlineBidiResolver& resolver, FloatingObject* lastFloatFromPreviousLine, Inlin eIterator& end, WordMeasurements& wordMeasurements)
1148 {
1149 LayoutUnit adjustedLogicalLineTop = adjustLogicalLineTop(shapeInsideInfo, re solver.position(), end, wordMeasurements);
1150
1151 if (shapeInsideInfo && containsFloats()) {
1152 lastFloatFromPreviousLine = m_floatingObjects->set().last();
1153 if (!wordMeasurements.size()) {
1154 LayoutUnit floatLogicalTopOffset = shapeInsideInfo->computeFirstFitP ositionForFloat(logicalSizeForFloat(lastFloatFromPreviousLine));
1155 if (logicalHeight() < floatLogicalTopOffset)
1156 adjustedLogicalLineTop = floatLogicalTopOffset;
1157 }
1158 }
1159
1160 if (!adjustedLogicalLineTop)
1161 return false;
1162
1163 LayoutUnit newLogicalHeight = adjustedLogicalLineTop - absoluteLogicalTop;
1164
1165 if (layoutState.flowThread()) {
1166 layoutState.setAdjustedLogicalLineTop(adjustedLogicalLineTop);
1167 newLogicalHeight = logicalHeight();
1168 }
1169
1170 end = restartLayoutRunsAndFloatsInRange(logicalHeight(), newLogicalHeight, l astFloatFromPreviousLine, resolver, end);
1171 return true;
1172 }
1173
1174 void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, I nlineBidiResolver& resolver, const InlineIterator& cleanLineStart, const BidiSta tus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines) 960 void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, I nlineBidiResolver& resolver, const InlineIterator& cleanLineStart, const BidiSta tus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines)
1175 { 961 {
1176 RenderStyle* styleToUse = style(); 962 RenderStyle* styleToUse = style();
1177 bool paginated = view()->layoutState() && view()->layoutState()->isPaginated (); 963 bool paginated = view()->layoutState() && view()->layoutState()->isPaginated ();
1178 LineMidpointState& lineMidpointState = resolver.midpointState(); 964 LineMidpointState& lineMidpointState = resolver.midpointState();
1179 InlineIterator endOfLine = resolver.position(); 965 InlineIterator endOfLine = resolver.position();
1180 bool checkForEndLineMatch = layoutState.endLine(); 966 bool checkForEndLineMatch = layoutState.endLine();
1181 RenderTextInfo renderTextInfo; 967 RenderTextInfo renderTextInfo;
1182 VerticalPositionCache verticalPositionCache; 968 VerticalPositionCache verticalPositionCache;
1183 969
1184 LineBreaker lineBreaker(this); 970 LineBreaker lineBreaker(this);
1185 971
1186 LayoutSize logicalOffsetFromShapeContainer; 972 LayoutSize logicalOffsetFromShapeContainer;
1187 ShapeInsideInfo* shapeInsideInfo = layoutShapeInsideInfo();
1188 if (shapeInsideInfo) {
1189 ASSERT(&shapeInsideInfo->owner() == this || allowsShapeInsideInfoSharing (&shapeInsideInfo->owner()));
1190 if (shapeInsideInfo != this->shapeInsideInfo()) {
1191 // FIXME Bug 100284: If subsequent LayoutStates are pushed, we will have to add
1192 // their offsets from the original shape-inside container.
1193 logicalOffsetFromShapeContainer = logicalOffsetFromShapeAncestorCont ainer(&shapeInsideInfo->owner());
1194 }
1195 // Begin layout at the logical top of our shape inside.
1196 if (logicalHeight() + logicalOffsetFromShapeContainer.height() < shapeIn sideInfo->shapeLogicalTop()) {
1197 LayoutUnit logicalHeight = shapeInsideInfo->shapeLogicalTop() - logi calOffsetFromShapeContainer.height();
1198 if (layoutState.flowThread())
1199 logicalHeight -= shapeInsideInfo->owner().borderAndPaddingBefore ();
1200 setLogicalHeight(logicalHeight);
1201 }
1202 }
1203 973
1204 while (!endOfLine.atEnd()) { 974 while (!endOfLine.atEnd()) {
1205 // FIXME: Is this check necessary before the first iteration or can it b e moved to the end? 975 // FIXME: Is this check necessary before the first iteration or can it b e moved to the end?
1206 if (checkForEndLineMatch) { 976 if (checkForEndLineMatch) {
1207 layoutState.setEndLineMatched(matchedEndLine(layoutState, resolver, cleanLineStart, cleanLineBidiStatus)); 977 layoutState.setEndLineMatched(matchedEndLine(layoutState, resolver, cleanLineStart, cleanLineBidiStatus));
1208 if (layoutState.endLineMatched()) { 978 if (layoutState.endLineMatched()) {
1209 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0); 979 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0);
1210 break; 980 break;
1211 } 981 }
1212 } 982 }
1213 983
1214 lineMidpointState.reset(); 984 lineMidpointState.reset();
1215 985
1216 layoutState.lineInfo().setEmpty(true); 986 layoutState.lineInfo().setEmpty(true);
1217 layoutState.lineInfo().resetRunsFromLeadingWhitespace(); 987 layoutState.lineInfo().resetRunsFromLeadingWhitespace();
1218 988
1219 const InlineIterator previousEndofLine = endOfLine; 989 const InlineIterator previousEndofLine = endOfLine;
1220 bool isNewUBAParagraph = layoutState.lineInfo().previousLineBrokeCleanly (); 990 bool isNewUBAParagraph = layoutState.lineInfo().previousLineBrokeCleanly ();
1221 FloatingObject* lastFloatFromPreviousLine = (containsFloats()) ? m_float ingObjects->set().last() : 0; 991 FloatingObject* lastFloatFromPreviousLine = (containsFloats()) ? m_float ingObjects->set().last() : 0;
1222 992
1223 updateShapeAndSegmentsForCurrentLine(shapeInsideInfo, logicalOffsetFromS hapeContainer, layoutState);
1224
1225 WordMeasurements wordMeasurements; 993 WordMeasurements wordMeasurements;
1226 endOfLine = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasu rements); 994 endOfLine = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasu rements);
1227 renderTextInfo.m_lineBreakIterator.resetPriorContext(); 995 renderTextInfo.m_lineBreakIterator.resetPriorContext();
1228 if (resolver.position().atEnd()) { 996 if (resolver.position().atEnd()) {
1229 // FIXME: We shouldn't be creating any runs in nextLineBreak to begi n with! 997 // FIXME: We shouldn't be creating any runs in nextLineBreak to begi n with!
1230 // Once BidiRunList is separated from BidiResolver this will not be needed. 998 // Once BidiRunList is separated from BidiResolver this will not be needed.
1231 resolver.runs().deleteRuns(); 999 resolver.runs().deleteRuns();
1232 resolver.markCurrentRunEmpty(); // FIXME: This can probably be repla ced by an ASSERT (or just removed). 1000 resolver.markCurrentRunEmpty(); // FIXME: This can probably be repla ced by an ASSERT (or just removed).
1233 layoutState.setCheckForFloatsFromLastLine(true); 1001 layoutState.setCheckForFloatsFromLastLine(true);
1234 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0 ), 0); 1002 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0 ), 0);
1235 break; 1003 break;
1236 } 1004 }
1237 1005
1238 if (adjustLogicalLineTopAndLogicalHeightIfNeeded(shapeInsideInfo, logica lOffsetFromShapeContainer.height(), layoutState, resolver, lastFloatFromPrevious Line, endOfLine, wordMeasurements))
1239 continue;
1240
1241 ASSERT(endOfLine != resolver.position()); 1006 ASSERT(endOfLine != resolver.position());
1242 1007
1243 // This is a short-cut for empty lines. 1008 // This is a short-cut for empty lines.
1244 if (layoutState.lineInfo().isEmpty()) { 1009 if (layoutState.lineInfo().isEmpty()) {
1245 if (lastRootBox()) 1010 if (lastRootBox())
1246 lastRootBox()->setLineBreakInfo(endOfLine.object(), endOfLine.of fset(), resolver.status()); 1011 lastRootBox()->setLineBreakInfo(endOfLine.object(), endOfLine.of fset(), resolver.status());
1247 } else { 1012 } else {
1248 VisualDirectionOverride override = (styleToUse->rtlOrdering() == Vis ualOrder ? (styleToUse->direction() == LTR ? VisualLeftToRightOverride : VisualR ightToLeftOverride) : NoVisualOverride); 1013 VisualDirectionOverride override = (styleToUse->rtlOrdering() == Vis ualOrder ? (styleToUse->direction() == LTR ? VisualLeftToRightOverride : VisualR ightToLeftOverride) : NoVisualOverride);
1249 if (isNewUBAParagraph && styleToUse->unicodeBidi() == Plaintext && ! resolver.context()->parent()) { 1014 if (isNewUBAParagraph && styleToUse->unicodeBidi() == Plaintext && ! resolver.context()->parent()) {
1250 TextDirection direction = determinePlaintextDirectionality(resol ver.position().root(), resolver.position().object(), resolver.position().offset( )); 1015 TextDirection direction = determinePlaintextDirectionality(resol ver.position().root(), resolver.position().object(), resolver.position().offset( ));
(...skipping 1199 matching lines...) Expand 10 before | Expand all | Expand 10 after
2450 float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false).toFloat (); 2215 float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false).toFloat ();
2451 float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), fal se) - logicalLeft; 2216 float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), fal se) - logicalLeft;
2452 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid th, availableLogicalWidth, 0); 2217 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid th, availableLogicalWidth, 0);
2453 2218
2454 if (!style()->isLeftToRightDirection()) 2219 if (!style()->isLeftToRightDirection())
2455 return logicalWidth() - logicalLeft; 2220 return logicalWidth() - logicalLeft;
2456 return logicalLeft; 2221 return logicalLeft;
2457 } 2222 }
2458 2223
2459 } 2224 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698