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 |