Chromium Code Reviews| 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 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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); |
|
Bem Jones-Bey (adobe)
2014/03/27 00:09:47
You should remove constructBidiRunsForSegment and
| |
| 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 Loading... | |
| 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.nextSegmentBreak(resolver, layoutState.lineInfo( ), renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMe asurements); |
|
Bem Jones-Bey (adobe)
2014/03/27 00:09:47
Shouldn't this be nextLineBreak? We shouldn't have
| |
| 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 Loading... | |
| 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 } |
| OLD | NEW |