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

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: Remove now unused segmentIsEmpty 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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
779 static void restoreIsolatedMidpointStates(InlineBidiResolver& topResolver, Inlin eBidiResolver& isolatedResolver) 750 static void restoreIsolatedMidpointStates(InlineBidiResolver& topResolver, Inlin eBidiResolver& isolatedResolver)
780 { 751 {
781 while (!isolatedResolver.isolatedRuns().isEmpty()) { 752 while (!isolatedResolver.isolatedRuns().isEmpty()) {
782 BidiRun* run = isolatedResolver.isolatedRuns().last(); 753 BidiRun* run = isolatedResolver.isolatedRuns().last();
783 isolatedResolver.isolatedRuns().removeLast(); 754 isolatedResolver.isolatedRuns().removeLast();
784 topResolver.setMidpointStateForIsolatedRun(run, isolatedResolver.midpoin tStateForIsolatedRun(run)); 755 topResolver.setMidpointStateForIsolatedRun(run, isolatedResolver.midpoin tStateForIsolatedRun(run));
785 } 756 }
786 } 757 }
787 758
788 // FIXME: BidiResolver should have this logic. 759 // FIXME: BidiResolver should have this logic.
789 static inline void constructBidiRunsForSegment(InlineBidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfRuns, VisualDirection Override override, bool previousLineBrokeCleanly, bool isNewUBAParagraph) 760 static inline void constructBidiRunsForLine(const RenderBlockFlow* block, Inline BidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfLine, VisualDirectionOverride override, bool previousLineBrokeCleanly, boo l isNewUBAParagraph)
790 { 761 {
791 // FIXME: We should pass a BidiRunList into createBidiRunsForLine instead 762 // FIXME: We should pass a BidiRunList into createBidiRunsForLine instead
792 // of the resolver owning the runs. 763 // of the resolver owning the runs.
793 ASSERT(&topResolver.runs() == &bidiRuns); 764 ASSERT(&topResolver.runs() == &bidiRuns);
794 ASSERT(topResolver.position() != endOfRuns); 765 ASSERT(topResolver.position() != endOfLine);
795 RenderObject* currentRoot = topResolver.position().root(); 766 RenderObject* currentRoot = topResolver.position().root();
796 topResolver.createBidiRunsForLine(endOfRuns, override, previousLineBrokeClea nly); 767 topResolver.createBidiRunsForLine(endOfLine, override, previousLineBrokeClea nly);
797 768
798 while (!topResolver.isolatedRuns().isEmpty()) { 769 while (!topResolver.isolatedRuns().isEmpty()) {
799 // It does not matter which order we resolve the runs as long as we reso lve them all. 770 // It does not matter which order we resolve the runs as long as we reso lve them all.
800 BidiRun* isolatedRun = topResolver.isolatedRuns().last(); 771 BidiRun* isolatedRun = topResolver.isolatedRuns().last();
801 topResolver.isolatedRuns().removeLast(); 772 topResolver.isolatedRuns().removeLast();
802 773
803 RenderObject* startObj = isolatedRun->object(); 774 RenderObject* startObj = isolatedRun->object();
804 775
805 // Only inlines make sense with unicode-bidi: isolate (blocks are alread y isolated). 776 // Only inlines make sense with unicode-bidi: isolate (blocks are alread y isolated).
806 // FIXME: Because enterIsolate is not passed a RenderObject, we have to crawl up the 777 // FIXME: Because enterIsolate is not passed a RenderObject, we have to crawl up the
(...skipping 22 matching lines...) Expand all
829 setupResolverToResumeInIsolate(isolatedResolver, isolatedInline, startOb j); 800 setupResolverToResumeInIsolate(isolatedResolver, isolatedInline, startOb j);
830 801
831 // The starting position is the beginning of the first run within the is olate that was identified 802 // The starting position is the beginning of the first run within the is olate that was identified
832 // during the earlier call to createBidiRunsForLine. This can be but is not necessarily the 803 // during the earlier call to createBidiRunsForLine. This can be but is not necessarily the
833 // first run within the isolate. 804 // first run within the isolate.
834 InlineIterator iter = InlineIterator(isolatedInline, startObj, isolatedR un->m_start); 805 InlineIterator iter = InlineIterator(isolatedInline, startObj, isolatedR un->m_start);
835 isolatedResolver.setPositionIgnoringNestedIsolates(iter); 806 isolatedResolver.setPositionIgnoringNestedIsolates(iter);
836 // We stop at the next end of line; we may re-enter this isolate in the next call to constructBidiRuns(). 807 // We stop at the next end of line; we may re-enter this isolate in the next call to constructBidiRuns().
837 // FIXME: What should end and previousLineBrokeCleanly be? 808 // FIXME: What should end and previousLineBrokeCleanly be?
838 // rniwa says previousLineBrokeCleanly is just a WinIE hack and could al ways be false here? 809 // rniwa says previousLineBrokeCleanly is just a WinIE hack and could al ways be false here?
839 isolatedResolver.createBidiRunsForLine(endOfRuns, NoVisualOverride, prev iousLineBrokeCleanly); 810 isolatedResolver.createBidiRunsForLine(endOfLine, NoVisualOverride, prev iousLineBrokeCleanly);
840 811
841 ASSERT(isolatedResolver.runs().runCount()); 812 ASSERT(isolatedResolver.runs().runCount());
842 if (isolatedResolver.runs().runCount()) 813 if (isolatedResolver.runs().runCount())
843 bidiRuns.replaceRunWithRuns(isolatedRun, isolatedResolver.runs()); 814 bidiRuns.replaceRunWithRuns(isolatedRun, isolatedResolver.runs());
844 815
845 // If we encountered any nested isolate runs, just move them 816 // If we encountered any nested isolate runs, just move them
846 // to the top resolver's list for later processing. 817 // to the top resolver's list for later processing.
847 if (!isolatedResolver.isolatedRuns().isEmpty()) { 818 if (!isolatedResolver.isolatedRuns().isEmpty()) {
848 topResolver.isolatedRuns().appendVector(isolatedResolver.isolatedRun s()); 819 topResolver.isolatedRuns().appendVector(isolatedResolver.isolatedRun s());
849 currentRoot = isolatedInline; 820 currentRoot = isolatedInline;
850 restoreIsolatedMidpointStates(topResolver, isolatedResolver); 821 restoreIsolatedMidpointStates(topResolver, isolatedResolver);
851 } 822 }
852 } 823 }
853 } 824 }
854 825
855 static inline bool segmentIsEmpty(const InlineIterator& segmentStart, const Inli neIterator& segmentEnd)
856 {
857 return segmentStart == segmentEnd;
858 }
859
860 static inline void constructBidiRunsForLine(const RenderBlockFlow* block, Inline BidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfLine, VisualDirectionOverride override, bool previousLineBrokeCleanly, boo l isNewUBAParagraph)
861 {
862 ShapeInsideInfo* shapeInsideInfo = block->layoutShapeInsideInfo();
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 }
890
891 // This function constructs line boxes for all of the text runs in the resolver and computes their position. 826 // 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) 827 RootInlineBox* RenderBlockFlow::createLineBoxesFromBidiRuns(unsigned bidiLevel, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end, LineInfo& lineInfo, V erticalPositionCache& verticalPositionCache, BidiRun* trailingSpaceRun, WordMeas urements& wordMeasurements)
893 { 828 {
894 if (!bidiRuns.runCount()) 829 if (!bidiRuns.runCount())
895 return 0; 830 return 0;
896 831
897 // FIXME: Why is this only done when we had runs? 832 // FIXME: Why is this only done when we had runs?
898 lineInfo.setLastLine(!end.object()); 833 lineInfo.setLastLine(!end.object());
899 834
900 RootInlineBox* lineBox = constructLine(bidiRuns, lineInfo); 835 RootInlineBox* lineBox = constructLine(bidiRuns, lineInfo);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1005 940
1006 // Before restarting the layout loop with a new logicalHeight, remove all floats that were added and reset the resolver. 941 // 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) 942 inline const InlineIterator& RenderBlockFlow::restartLayoutRunsAndFloatsInRange( LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight, FloatingObject* lastF loatFromPreviousLine, InlineBidiResolver& resolver, const InlineIterator& oldEn d)
1008 { 943 {
1009 removeFloatingObjectsBelow(lastFloatFromPreviousLine, oldLogicalHeight); 944 removeFloatingObjectsBelow(lastFloatFromPreviousLine, oldLogicalHeight);
1010 setLogicalHeight(newLogicalHeight); 945 setLogicalHeight(newLogicalHeight);
1011 resolver.setPositionIgnoringNestedIsolates(oldEnd); 946 resolver.setPositionIgnoringNestedIsolates(oldEnd);
1012 return oldEnd; 947 return oldEnd;
1013 } 948 }
1014 949
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) 950 void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, I nlineBidiResolver& resolver, const InlineIterator& cleanLineStart, const BidiSta tus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines)
1175 { 951 {
1176 RenderStyle* styleToUse = style(); 952 RenderStyle* styleToUse = style();
1177 bool paginated = view()->layoutState() && view()->layoutState()->isPaginated (); 953 bool paginated = view()->layoutState() && view()->layoutState()->isPaginated ();
1178 LineMidpointState& lineMidpointState = resolver.midpointState(); 954 LineMidpointState& lineMidpointState = resolver.midpointState();
1179 InlineIterator endOfLine = resolver.position(); 955 InlineIterator endOfLine = resolver.position();
1180 bool checkForEndLineMatch = layoutState.endLine(); 956 bool checkForEndLineMatch = layoutState.endLine();
1181 RenderTextInfo renderTextInfo; 957 RenderTextInfo renderTextInfo;
1182 VerticalPositionCache verticalPositionCache; 958 VerticalPositionCache verticalPositionCache;
1183 959
1184 LineBreaker lineBreaker(this); 960 LineBreaker lineBreaker(this);
1185 961
1186 LayoutSize logicalOffsetFromShapeContainer; 962 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 963
1204 while (!endOfLine.atEnd()) { 964 while (!endOfLine.atEnd()) {
1205 // FIXME: Is this check necessary before the first iteration or can it b e moved to the end? 965 // FIXME: Is this check necessary before the first iteration or can it b e moved to the end?
1206 if (checkForEndLineMatch) { 966 if (checkForEndLineMatch) {
1207 layoutState.setEndLineMatched(matchedEndLine(layoutState, resolver, cleanLineStart, cleanLineBidiStatus)); 967 layoutState.setEndLineMatched(matchedEndLine(layoutState, resolver, cleanLineStart, cleanLineBidiStatus));
1208 if (layoutState.endLineMatched()) { 968 if (layoutState.endLineMatched()) {
1209 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0); 969 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0);
1210 break; 970 break;
1211 } 971 }
1212 } 972 }
1213 973
1214 lineMidpointState.reset(); 974 lineMidpointState.reset();
1215 975
1216 layoutState.lineInfo().setEmpty(true); 976 layoutState.lineInfo().setEmpty(true);
1217 layoutState.lineInfo().resetRunsFromLeadingWhitespace(); 977 layoutState.lineInfo().resetRunsFromLeadingWhitespace();
1218 978
1219 const InlineIterator previousEndofLine = endOfLine; 979 const InlineIterator previousEndofLine = endOfLine;
1220 bool isNewUBAParagraph = layoutState.lineInfo().previousLineBrokeCleanly (); 980 bool isNewUBAParagraph = layoutState.lineInfo().previousLineBrokeCleanly ();
1221 FloatingObject* lastFloatFromPreviousLine = (containsFloats()) ? m_float ingObjects->set().last() : 0; 981 FloatingObject* lastFloatFromPreviousLine = (containsFloats()) ? m_float ingObjects->set().last() : 0;
1222 982
1223 updateShapeAndSegmentsForCurrentLine(shapeInsideInfo, logicalOffsetFromS hapeContainer, layoutState);
1224
1225 WordMeasurements wordMeasurements; 983 WordMeasurements wordMeasurements;
1226 endOfLine = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasu rements); 984 endOfLine = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasu rements);
1227 renderTextInfo.m_lineBreakIterator.resetPriorContext(); 985 renderTextInfo.m_lineBreakIterator.resetPriorContext();
1228 if (resolver.position().atEnd()) { 986 if (resolver.position().atEnd()) {
1229 // FIXME: We shouldn't be creating any runs in nextLineBreak to begi n with! 987 // 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. 988 // Once BidiRunList is separated from BidiResolver this will not be needed.
1231 resolver.runs().deleteRuns(); 989 resolver.runs().deleteRuns();
1232 resolver.markCurrentRunEmpty(); // FIXME: This can probably be repla ced by an ASSERT (or just removed). 990 resolver.markCurrentRunEmpty(); // FIXME: This can probably be repla ced by an ASSERT (or just removed).
1233 layoutState.setCheckForFloatsFromLastLine(true); 991 layoutState.setCheckForFloatsFromLastLine(true);
1234 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0 ), 0); 992 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0 ), 0);
1235 break; 993 break;
1236 } 994 }
1237 995
1238 if (adjustLogicalLineTopAndLogicalHeightIfNeeded(shapeInsideInfo, logica lOffsetFromShapeContainer.height(), layoutState, resolver, lastFloatFromPrevious Line, endOfLine, wordMeasurements))
1239 continue;
1240
1241 ASSERT(endOfLine != resolver.position()); 996 ASSERT(endOfLine != resolver.position());
1242 997
1243 // This is a short-cut for empty lines. 998 // This is a short-cut for empty lines.
1244 if (layoutState.lineInfo().isEmpty()) { 999 if (layoutState.lineInfo().isEmpty()) {
1245 if (lastRootBox()) 1000 if (lastRootBox())
1246 lastRootBox()->setLineBreakInfo(endOfLine.object(), endOfLine.of fset(), resolver.status()); 1001 lastRootBox()->setLineBreakInfo(endOfLine.object(), endOfLine.of fset(), resolver.status());
1247 } else { 1002 } else {
1248 VisualDirectionOverride override = (styleToUse->rtlOrdering() == Vis ualOrder ? (styleToUse->direction() == LTR ? VisualLeftToRightOverride : VisualR ightToLeftOverride) : NoVisualOverride); 1003 VisualDirectionOverride override = (styleToUse->rtlOrdering() == Vis ualOrder ? (styleToUse->direction() == LTR ? VisualLeftToRightOverride : VisualR ightToLeftOverride) : NoVisualOverride);
1249 if (isNewUBAParagraph && styleToUse->unicodeBidi() == Plaintext && ! resolver.context()->parent()) { 1004 if (isNewUBAParagraph && styleToUse->unicodeBidi() == Plaintext && ! resolver.context()->parent()) {
1250 TextDirection direction = determinePlaintextDirectionality(resol ver.position().root(), resolver.position().object(), resolver.position().offset( )); 1005 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 (); 2205 float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false).toFloat ();
2451 float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), fal se) - logicalLeft; 2206 float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), fal se) - logicalLeft;
2452 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid th, availableLogicalWidth, 0); 2207 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid th, availableLogicalWidth, 0);
2453 2208
2454 if (!style()->isLeftToRightDirection()) 2209 if (!style()->isLeftToRightDirection())
2455 return logicalWidth() - logicalLeft; 2210 return logicalWidth() - logicalLeft;
2456 return logicalLeft; 2211 return logicalLeft;
2457 } 2212 }
2458 2213
2459 } 2214 }
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderBlockFlow.cpp ('k') | Source/core/rendering/RenderDeprecatedFlexibleBox.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698