OLD | NEW |
1 /* | 1 /* |
2 * This file is part of the layout object implementation for KHTML. | 2 * This file is part of the layout object implementation for KHTML. |
3 * | 3 * |
4 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 4 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
5 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 5 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
6 * Copyright (C) 2003 Apple Computer, Inc. | 6 * Copyright (C) 2003 Apple Computer, Inc. |
7 * | 7 * |
8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 LayoutDeprecatedFlexibleBox* m_box; | 114 LayoutDeprecatedFlexibleBox* m_box; |
115 LayoutBox* m_currentChild; | 115 LayoutBox* m_currentChild; |
116 bool m_forward; | 116 bool m_forward; |
117 unsigned m_currentOrdinal; | 117 unsigned m_currentOrdinal; |
118 unsigned m_largestOrdinal; | 118 unsigned m_largestOrdinal; |
119 HashSet<unsigned> m_ordinalValues; | 119 HashSet<unsigned> m_ordinalValues; |
120 Vector<unsigned> m_sortedOrdinalValues; | 120 Vector<unsigned> m_sortedOrdinalValues; |
121 int m_ordinalIteration; | 121 int m_ordinalIteration; |
122 }; | 122 }; |
123 | 123 |
| 124 // Helper methods for obtaining the last line, computing line counts and heights
for line counts |
| 125 // (crawling into blocks). |
| 126 static bool shouldCheckLines(LayoutBlockFlow* blockFlow) |
| 127 { |
| 128 return !blockFlow->isFloatingOrOutOfFlowPositioned() && blockFlow->style()->
height().isAuto(); |
| 129 } |
| 130 |
| 131 static int getHeightForLineCount(const LayoutBlockFlow* blockFlow, int lineCount
, bool includeBottom, int& count) |
| 132 { |
| 133 if (blockFlow->style()->visibility() != VISIBLE) |
| 134 return -1; |
| 135 if (blockFlow->childrenInline()) { |
| 136 for (RootInlineBox* box = blockFlow->firstRootBox(); box; box = box->nex
tRootBox()) { |
| 137 if (++count == lineCount) |
| 138 return box->lineBottom() + (includeBottom ? (blockFlow->borderBo
ttom() + blockFlow->paddingBottom()) : LayoutUnit()); |
| 139 } |
| 140 return -1; |
| 141 } |
| 142 |
| 143 LayoutBox* normalFlowChildWithoutLines = nullptr; |
| 144 for (LayoutBox* obj = blockFlow->firstChildBox(); obj; obj = obj->nextSiblin
gBox()) { |
| 145 if (obj->isLayoutBlockFlow() && shouldCheckLines(toLayoutBlockFlow(obj))
) { |
| 146 int result = getHeightForLineCount(toLayoutBlockFlow(obj), lineCount
, false, count); |
| 147 if (result != -1) |
| 148 return result + obj->location().y() + (includeBottom ? (blockFlo
w->borderBottom() + blockFlow->paddingBottom()) : LayoutUnit()); |
| 149 } else if (!obj->isFloatingOrOutOfFlowPositioned()) { |
| 150 normalFlowChildWithoutLines = obj; |
| 151 } |
| 152 } |
| 153 if (normalFlowChildWithoutLines && lineCount == 0) |
| 154 return normalFlowChildWithoutLines->location().y() + normalFlowChildWith
outLines->size().height(); |
| 155 |
| 156 return -1; |
| 157 } |
| 158 |
| 159 static RootInlineBox* lineAtIndex(const LayoutBlockFlow* blockFlow, int i) |
| 160 { |
| 161 ASSERT(i >= 0); |
| 162 |
| 163 if (blockFlow->style()->visibility() != VISIBLE) |
| 164 return nullptr; |
| 165 |
| 166 if (blockFlow->childrenInline()) { |
| 167 for (RootInlineBox* box = blockFlow->firstRootBox(); box; box = box->nex
tRootBox()) { |
| 168 if (!i--) |
| 169 return box; |
| 170 } |
| 171 return nullptr; |
| 172 } |
| 173 for (LayoutObject* child = blockFlow->firstChild(); child; child = child->ne
xtSibling()) { |
| 174 if (!child->isLayoutBlockFlow()) |
| 175 continue; |
| 176 LayoutBlockFlow* childBlockFlow = toLayoutBlockFlow(child); |
| 177 if (!shouldCheckLines(childBlockFlow)) |
| 178 continue; |
| 179 if (RootInlineBox* box = lineAtIndex(childBlockFlow, i)) |
| 180 return box; |
| 181 } |
| 182 |
| 183 return nullptr; |
| 184 } |
| 185 |
| 186 static int lineCount(const LayoutBlockFlow* blockFlow, const RootInlineBox* stop
RootInlineBox = nullptr, bool* found = nullptr) |
| 187 { |
| 188 if (blockFlow->style()->visibility() != VISIBLE) |
| 189 return 0; |
| 190 int count = 0; |
| 191 if (blockFlow->childrenInline()) { |
| 192 for (RootInlineBox* box = blockFlow->firstRootBox(); box; box = box->nex
tRootBox()) { |
| 193 count++; |
| 194 if (box == stopRootInlineBox) { |
| 195 if (found) |
| 196 *found = true; |
| 197 break; |
| 198 } |
| 199 } |
| 200 return count; |
| 201 } |
| 202 for (LayoutObject* obj = blockFlow->firstChild(); obj; obj = obj->nextSiblin
g()) { |
| 203 if (!obj->isLayoutBlockFlow()) |
| 204 continue; |
| 205 LayoutBlockFlow* childBlockFlow = toLayoutBlockFlow(obj); |
| 206 if (!shouldCheckLines(childBlockFlow)) |
| 207 continue; |
| 208 bool recursiveFound = false; |
| 209 count += lineCount(childBlockFlow, stopRootInlineBox, &recursiveFound); |
| 210 if (recursiveFound) { |
| 211 if (found) |
| 212 *found = true; |
| 213 break; |
| 214 } |
| 215 } |
| 216 return count; |
| 217 } |
| 218 |
| 219 static void clearTruncation(LayoutBlockFlow* blockFlow) |
| 220 { |
| 221 if (blockFlow->style()->visibility() != VISIBLE) |
| 222 return; |
| 223 if (blockFlow->childrenInline() && blockFlow->hasMarkupTruncation()) { |
| 224 blockFlow->setHasMarkupTruncation(false); |
| 225 for (RootInlineBox* box = blockFlow->firstRootBox(); box; box = box->nex
tRootBox()) |
| 226 box->clearTruncation(); |
| 227 return; |
| 228 } |
| 229 for (LayoutObject* obj = blockFlow->firstChild(); obj; obj = obj->nextSiblin
g()) { |
| 230 if (!obj->isLayoutBlockFlow()) |
| 231 continue; |
| 232 LayoutBlockFlow* childBlockFlow = toLayoutBlockFlow(obj); |
| 233 if (shouldCheckLines(childBlockFlow)) |
| 234 clearTruncation(childBlockFlow); |
| 235 } |
| 236 } |
| 237 |
124 LayoutDeprecatedFlexibleBox::LayoutDeprecatedFlexibleBox(Element& element) | 238 LayoutDeprecatedFlexibleBox::LayoutDeprecatedFlexibleBox(Element& element) |
125 : LayoutBlock(&element) | 239 : LayoutBlock(&element) |
126 { | 240 { |
127 ASSERT(!childrenInline()); | 241 ASSERT(!childrenInline()); |
128 m_stretchingChildren = false; | 242 m_stretchingChildren = false; |
129 if (!isAnonymous()) { | 243 if (!isAnonymous()) { |
130 const KURL& url = document().url(); | 244 const KURL& url = document().url(); |
131 if (url.protocolIs("chrome")) | 245 if (url.protocolIs("chrome")) |
132 UseCounter::count(document(), UseCounter::DeprecatedFlexboxChrome); | 246 UseCounter::count(document(), UseCounter::DeprecatedFlexboxChrome); |
133 else if (url.protocolIs("chrome-extension")) | 247 else if (url.protocolIs("chrome-extension")) |
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
845 for (LayoutBox* child = iterator.first(); child; child = iterator.next()) { | 959 for (LayoutBox* child = iterator.first(); child; child = iterator.next()) { |
846 if (childDoesNotAffectWidthOrFlexing(child)) | 960 if (childDoesNotAffectWidthOrFlexing(child)) |
847 continue; | 961 continue; |
848 | 962 |
849 child->clearOverrideSize(); | 963 child->clearOverrideSize(); |
850 if (relayoutChildren || (child->isAtomicInlineLevel() && (child->style()
->width().hasPercent() || child->style()->height().hasPercent())) | 964 if (relayoutChildren || (child->isAtomicInlineLevel() && (child->style()
->width().hasPercent() || child->style()->height().hasPercent())) |
851 || (child->style()->height().isAuto() && child->isLayoutBlock())) { | 965 || (child->style()->height().isAuto() && child->isLayoutBlock())) { |
852 child->setChildNeedsLayout(MarkOnlyThis); | 966 child->setChildNeedsLayout(MarkOnlyThis); |
853 | 967 |
854 // Dirty all the positioned objects. | 968 // Dirty all the positioned objects. |
855 if (child->isLayoutBlock()) { | 969 if (child->isLayoutBlockFlow()) { |
856 toLayoutBlock(child)->markPositionedObjectsForLayout(); | 970 toLayoutBlockFlow(child)->markPositionedObjectsForLayout(); |
857 toLayoutBlock(child)->clearTruncation(); | 971 clearTruncation(toLayoutBlockFlow(child)); |
858 } | 972 } |
859 } | 973 } |
860 child->layoutIfNeeded(); | 974 child->layoutIfNeeded(); |
861 if (child->style()->height().isAuto() && child->isLayoutBlock()) | 975 if (child->style()->height().isAuto() && child->isLayoutBlockFlow()) |
862 maxLineCount = std::max(maxLineCount, toLayoutBlock(child)->lineCoun
t()); | 976 maxLineCount = std::max(maxLineCount, lineCount(toLayoutBlockFlow(ch
ild))); |
863 } | 977 } |
864 | 978 |
865 // Get the number of lines and then alter all block flow children with auto
height to use the | 979 // Get the number of lines and then alter all block flow children with auto
height to use the |
866 // specified height. We always try to leave room for at least one line. | 980 // specified height. We always try to leave room for at least one line. |
867 LineClampValue lineClamp = style()->lineClamp(); | 981 LineClampValue lineClamp = style()->lineClamp(); |
868 int numVisibleLines = lineClamp.isPercentage() ? std::max(1, (maxLineCount +
1) * lineClamp.value() / 100) : lineClamp.value(); | 982 int numVisibleLines = lineClamp.isPercentage() ? std::max(1, (maxLineCount +
1) * lineClamp.value() / 100) : lineClamp.value(); |
869 if (numVisibleLines >= maxLineCount) | 983 if (numVisibleLines >= maxLineCount) |
870 return; | 984 return; |
871 | 985 |
872 for (LayoutBox* child = iterator.first(); child; child = iterator.next()) { | 986 for (LayoutBox* child = iterator.first(); child; child = iterator.next()) { |
873 if (childDoesNotAffectWidthOrFlexing(child) || !child->style()->height()
.isAuto() || !child->isLayoutBlock()) | 987 if (childDoesNotAffectWidthOrFlexing(child) || !child->style()->height()
.isAuto() || !child->isLayoutBlockFlow()) |
874 continue; | 988 continue; |
875 | 989 |
876 LayoutBlock* blockChild = toLayoutBlock(child); | 990 LayoutBlockFlow* blockChild = toLayoutBlockFlow(child); |
877 int lineCount = blockChild->lineCount(); | 991 int lineCount = blink::lineCount(blockChild); |
878 if (lineCount <= numVisibleLines) | 992 if (lineCount <= numVisibleLines) |
879 continue; | 993 continue; |
880 | 994 |
881 LayoutUnit newHeight(blockChild->heightForLineCount(numVisibleLines)); | 995 int dummyCount = 0; |
| 996 LayoutUnit newHeight(getHeightForLineCount(blockChild, numVisibleLines,
true, dummyCount)); |
882 if (newHeight == child->size().height()) | 997 if (newHeight == child->size().height()) |
883 continue; | 998 continue; |
884 | 999 |
885 child->setOverrideLogicalContentHeight(newHeight - child->borderAndPaddi
ngHeight()); | 1000 child->setOverrideLogicalContentHeight(newHeight - child->borderAndPaddi
ngHeight()); |
886 child->forceChildLayout(); | 1001 child->forceChildLayout(); |
887 | 1002 |
888 // FIXME: For now don't support RTL. | 1003 // FIXME: For now don't support RTL. |
889 if (style()->direction() != LTR) | 1004 if (style()->direction() != LTR) |
890 continue; | 1005 continue; |
891 | 1006 |
892 // Get the last line | 1007 // Get the last line |
893 RootInlineBox* lastLine = blockChild->lineAtIndex(lineCount - 1); | 1008 RootInlineBox* lastLine = lineAtIndex(blockChild, lineCount - 1); |
894 if (!lastLine) | 1009 if (!lastLine) |
895 continue; | 1010 continue; |
896 | 1011 |
897 RootInlineBox* lastVisibleLine = blockChild->lineAtIndex(numVisibleLines
- 1); | 1012 RootInlineBox* lastVisibleLine = lineAtIndex(blockChild, numVisibleLines
- 1); |
898 if (!lastVisibleLine) | 1013 if (!lastVisibleLine) |
899 continue; | 1014 continue; |
900 | 1015 |
901 DEFINE_STATIC_LOCAL(AtomicString, ellipsisStr, (&horizontalEllipsisChara
cter, 1)); | 1016 DEFINE_STATIC_LOCAL(AtomicString, ellipsisStr, (&horizontalEllipsisChara
cter, 1)); |
902 const Font& font = style(numVisibleLines == 1)->font(); | 1017 const Font& font = style(numVisibleLines == 1)->font(); |
903 float totalWidth = font.width(constructTextRun(font, &horizontalEllipsis
Character, 1, styleRef(), style()->direction())); | 1018 float totalWidth = font.width(constructTextRun(font, &horizontalEllipsis
Character, 1, styleRef(), style()->direction())); |
904 | 1019 |
905 // See if this width can be accommodated on the last visible line | 1020 // See if this width can be accommodated on the last visible line |
906 LineLayoutBlockFlow destBlock = lastVisibleLine->block(); | 1021 LineLayoutBlockFlow destBlock = lastVisibleLine->block(); |
907 LineLayoutBlockFlow srcBlock = lastLine->block(); | 1022 LineLayoutBlockFlow srcBlock = lastLine->block(); |
(...skipping 23 matching lines...) Expand all Loading... |
931 FlexBoxIterator iterator(this); | 1046 FlexBoxIterator iterator(this); |
932 for (LayoutBox* child = iterator.first(); child; child = iterator.next()) { | 1047 for (LayoutBox* child = iterator.first(); child; child = iterator.next()) { |
933 if (childDoesNotAffectWidthOrFlexing(child)) | 1048 if (childDoesNotAffectWidthOrFlexing(child)) |
934 continue; | 1049 continue; |
935 | 1050 |
936 child->clearOverrideSize(); | 1051 child->clearOverrideSize(); |
937 if ((child->isAtomicInlineLevel() && (child->style()->width().hasPercent
() || child->style()->height().hasPercent())) | 1052 if ((child->isAtomicInlineLevel() && (child->style()->width().hasPercent
() || child->style()->height().hasPercent())) |
938 || (child->style()->height().isAuto() && child->isLayoutBlock())) { | 1053 || (child->style()->height().isAuto() && child->isLayoutBlock())) { |
939 child->setChildNeedsLayout(); | 1054 child->setChildNeedsLayout(); |
940 | 1055 |
941 if (child->isLayoutBlock()) { | 1056 if (child->isLayoutBlockFlow()) { |
942 toLayoutBlock(child)->markPositionedObjectsForLayout(); | 1057 toLayoutBlockFlow(child)->markPositionedObjectsForLayout(); |
943 toLayoutBlock(child)->clearTruncation(); | 1058 clearTruncation(toLayoutBlockFlow(child)); |
944 } | 1059 } |
945 } | 1060 } |
946 } | 1061 } |
947 } | 1062 } |
948 | 1063 |
949 void LayoutDeprecatedFlexibleBox::placeChild(LayoutBox* child, const LayoutPoint
& location) | 1064 void LayoutDeprecatedFlexibleBox::placeChild(LayoutBox* child, const LayoutPoint
& location) |
950 { | 1065 { |
951 // FIXME Investigate if this can be removed based on other flags. crbug.com/
370010 | 1066 // FIXME Investigate if this can be removed based on other flags. crbug.com/
370010 |
952 child->setMayNeedPaintInvalidation(); | 1067 child->setMayNeedPaintInvalidation(); |
953 | 1068 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
997 if (minHeight.isFixed() || minHeight.isAuto()) { | 1112 if (minHeight.isFixed() || minHeight.isAuto()) { |
998 LayoutUnit minHeight(child->style()->minHeight().value()); | 1113 LayoutUnit minHeight(child->style()->minHeight().value()); |
999 LayoutUnit height = contentHeightForChild(child); | 1114 LayoutUnit height = contentHeightForChild(child); |
1000 LayoutUnit allowedShrinkage = (minHeight - height).clampPositiveToZero()
; | 1115 LayoutUnit allowedShrinkage = (minHeight - height).clampPositiveToZero()
; |
1001 return allowedShrinkage; | 1116 return allowedShrinkage; |
1002 } | 1117 } |
1003 return LayoutUnit(); | 1118 return LayoutUnit(); |
1004 } | 1119 } |
1005 | 1120 |
1006 } // namespace blink | 1121 } // namespace blink |
OLD | NEW |