OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserv ed. | 4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserv ed. |
5 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) | 5 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) |
6 * Copyright (C) 2010 Daniel Bates (dbates@intudata.com) | 6 * Copyright (C) 2010 Daniel Bates (dbates@intudata.com) |
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 18 matching lines...) Expand all Loading... | |
29 #include "core/layout/LayoutAnalyzer.h" | 29 #include "core/layout/LayoutAnalyzer.h" |
30 #include "core/layout/LayoutListItem.h" | 30 #include "core/layout/LayoutListItem.h" |
31 #include "core/layout/TextRunConstructor.h" | 31 #include "core/layout/TextRunConstructor.h" |
32 #include "core/paint/ListMarkerPainter.h" | 32 #include "core/paint/ListMarkerPainter.h" |
33 #include "core/paint/PaintLayer.h" | 33 #include "core/paint/PaintLayer.h" |
34 #include "platform/fonts/Font.h" | 34 #include "platform/fonts/Font.h" |
35 #include "wtf/text/StringBuilder.h" | 35 #include "wtf/text/StringBuilder.h" |
36 | 36 |
37 namespace blink { | 37 namespace blink { |
38 | 38 |
39 // TODO(wkorman): A seemingly arbitrary number tacked on following any image | |
40 // and included as part of margin for any text. Look into history, other | |
41 // browser behavior, and update or remove as appropriate. | |
39 const int cMarkerPadding = 7; | 42 const int cMarkerPadding = 7; |
eae
2015/10/12 06:02:01
cMarkerPaddingPx (assuming it is in pixels).
wkorman
2015/10/14 01:55:30
Done.
| |
40 | 43 |
41 enum SequenceType { NumericSequence, AlphabeticSequence }; | 44 enum SequenceType { NumericSequence, AlphabeticSequence }; |
42 | 45 |
43 static String toRoman(int number, bool upper) | 46 static String toRoman(int number, bool upper) |
44 { | 47 { |
45 // FIXME: CSS3 describes how to make this work for much larger numbers, | 48 // FIXME: CSS3 describes how to make this work for much larger numbers, |
46 // using overbars and special characters. It also specifies the characters | 49 // using overbars and special characters. It also specifies the characters |
47 // in the range U+2160 to U+217F instead of standard ASCII ones. | 50 // in the range U+2160 to U+217F instead of standard ASCII ones. |
48 ASSERT(number >= 1 && number <= 3999); | 51 ASSERT(number >= 1 && number <= 3999); |
49 | 52 |
(...skipping 977 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1027 { | 1030 { |
1028 return m_image && !m_image->errorOccurred(); | 1031 return m_image && !m_image->errorOccurred(); |
1029 } | 1032 } |
1030 | 1033 |
1031 LayoutRect LayoutListMarker::localSelectionRect() const | 1034 LayoutRect LayoutListMarker::localSelectionRect() const |
1032 { | 1035 { |
1033 InlineBox* box = inlineBoxWrapper(); | 1036 InlineBox* box = inlineBoxWrapper(); |
1034 if (!box) | 1037 if (!box) |
1035 return LayoutRect(LayoutPoint(), size()); | 1038 return LayoutRect(LayoutPoint(), size()); |
1036 RootInlineBox& root = inlineBoxWrapper()->root(); | 1039 RootInlineBox& root = inlineBoxWrapper()->root(); |
1037 LayoutUnit newLogicalTop = root.block().style()->isFlippedBlocksWritingMode( ) ? inlineBoxWrapper()->logicalBottom() - root.selectionBottom() : root.selectio nTop() - inlineBoxWrapper()->logicalTop(); | 1040 const ComputedStyle* blockStyle = root.block().style(); |
1038 if (root.block().style()->isHorizontalWritingMode()) | 1041 LayoutUnit newLogicalTop = blockStyle->isFlippedBlocksWritingMode() |
1042 ? inlineBoxWrapper()->logicalBottom() - root.selectionBottom() | |
1043 : root.selectionTop() - inlineBoxWrapper()->logicalTop(); | |
1044 if (blockStyle->isHorizontalWritingMode()) | |
1039 return LayoutRect(0, newLogicalTop, size().width(), root.selectionHeight ()); | 1045 return LayoutRect(0, newLogicalTop, size().width(), root.selectionHeight ()); |
1040 return LayoutRect(newLogicalTop, 0, root.selectionHeight(), size().height()) ; | 1046 return LayoutRect(newLogicalTop, 0, root.selectionHeight(), size().height()) ; |
1041 } | 1047 } |
1042 | 1048 |
1043 void LayoutListMarker::paint(const PaintInfo& paintInfo, const LayoutPoint& pain tOffset) const | 1049 void LayoutListMarker::paint(const PaintInfo& paintInfo, const LayoutPoint& pain tOffset) const |
1044 { | 1050 { |
1045 ListMarkerPainter(*this).paint(paintInfo, paintOffset); | 1051 ListMarkerPainter(*this).paint(paintInfo, paintOffset); |
1046 } | 1052 } |
1047 | 1053 |
1048 void LayoutListMarker::layout() | 1054 void LayoutListMarker::layout() |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1083 else | 1089 else |
1084 setShouldDoFullPaintInvalidation(); | 1090 setShouldDoFullPaintInvalidation(); |
1085 } | 1091 } |
1086 | 1092 |
1087 void LayoutListMarker::updateMarginsAndContent() | 1093 void LayoutListMarker::updateMarginsAndContent() |
1088 { | 1094 { |
1089 updateContent(); | 1095 updateContent(); |
1090 updateMargins(); | 1096 updateMargins(); |
1091 } | 1097 } |
1092 | 1098 |
1093 void LayoutListMarker::updateContent() | 1099 LayoutListMarker::SimplifiedListStyle LayoutListMarker::simplifiedListStyle() co nst |
1094 { | 1100 { |
1095 // FIXME: This if-statement is just a performance optimization, but it's mes sy to use the preferredLogicalWidths dirty bit for this. | 1101 switch (style()->listStyleType()) { |
1096 // It's unclear if this is a premature optimization. | |
1097 if (!preferredLogicalWidthsDirty()) | |
1098 return; | |
1099 | |
1100 m_text = ""; | |
1101 | |
1102 if (isImage()) { | |
1103 // FIXME: This is a somewhat arbitrary width. Generated images for mark ers really won't become particularly useful | |
1104 // until we support the CSS3 marker pseudoclass to allow control over th e width and height of the marker box. | |
1105 int bulletWidth = style()->fontMetrics().ascent() / 2; | |
1106 IntSize defaultBulletSize(bulletWidth, bulletWidth); | |
1107 IntSize imageSize = calculateImageIntrinsicDimensions(m_image.get(), def aultBulletSize, DoNotScaleByEffectiveZoom); | |
1108 m_image->setContainerSizeForLayoutObject(this, imageSize, style()->effec tiveZoom()); | |
1109 return; | |
1110 } | |
1111 | |
1112 EListStyleType type = style()->listStyleType(); | |
1113 switch (type) { | |
1114 case NoneListStyle: | 1102 case NoneListStyle: |
1115 break; | 1103 return NoneSimpleStyle; |
1104 case Disc: | |
1116 case Circle: | 1105 case Circle: |
1117 case Disc: | |
1118 case Square: | 1106 case Square: |
1119 m_text = listMarkerText(type, 0); // value is ignored for these types | 1107 return SymbolSimpleStyle; |
1120 break; | |
1121 case ArabicIndic: | 1108 case ArabicIndic: |
1122 case Armenian: | 1109 case Armenian: |
1123 case Bengali: | 1110 case Bengali: |
1124 case Cambodian: | 1111 case Cambodian: |
1125 case CJKIdeographic: | 1112 case CJKIdeographic: |
1126 case CjkEarthlyBranch: | 1113 case CjkEarthlyBranch: |
1127 case CjkHeavenlyStem: | 1114 case CjkHeavenlyStem: |
1128 case DecimalLeadingZero: | 1115 case DecimalLeadingZero: |
1129 case DecimalListStyle: | 1116 case DecimalListStyle: |
1130 case Devanagari: | 1117 case Devanagari: |
1131 case EthiopicHalehame: | 1118 case EthiopicHalehame: |
1132 case EthiopicHalehameAm: | 1119 case EthiopicHalehameAm: |
1133 case EthiopicHalehameTiEr: | 1120 case EthiopicHalehameTiEr: |
1134 case EthiopicHalehameTiEt: | 1121 case EthiopicHalehameTiEt: |
1135 case Georgian: | 1122 case Georgian: |
1136 case Gujarati: | 1123 case Gujarati: |
1137 case Gurmukhi: | 1124 case Gurmukhi: |
1125 case Hebrew: | |
1138 case Hangul: | 1126 case Hangul: |
1139 case HangulConsonant: | 1127 case HangulConsonant: |
1140 case KoreanHangulFormal: | 1128 case KoreanHangulFormal: |
1141 case KoreanHanjaFormal: | 1129 case KoreanHanjaFormal: |
1142 case KoreanHanjaInformal: | 1130 case KoreanHanjaInformal: |
1143 case Hebrew: | |
1144 case Hiragana: | 1131 case Hiragana: |
1145 case HiraganaIroha: | 1132 case HiraganaIroha: |
1146 case Kannada: | 1133 case Kannada: |
1147 case Katakana: | 1134 case Katakana: |
1148 case KatakanaIroha: | 1135 case KatakanaIroha: |
1149 case Khmer: | 1136 case Khmer: |
1150 case Lao: | 1137 case Lao: |
1151 case LowerAlpha: | 1138 case LowerAlpha: |
1152 case LowerArmenian: | 1139 case LowerArmenian: |
1153 case LowerGreek: | 1140 case LowerGreek: |
1154 case LowerLatin: | 1141 case LowerLatin: |
1155 case LowerRoman: | 1142 case LowerRoman: |
1156 case Malayalam: | 1143 case Malayalam: |
1157 case Mongolian: | 1144 case Mongolian: |
1158 case Myanmar: | 1145 case Myanmar: |
1159 case Oriya: | 1146 case Oriya: |
1160 case Persian: | 1147 case Persian: |
1161 case SimpChineseFormal: | 1148 case SimpChineseFormal: |
1162 case SimpChineseInformal: | 1149 case SimpChineseInformal: |
1163 case Telugu: | 1150 case Telugu: |
1164 case Thai: | 1151 case Thai: |
1165 case Tibetan: | 1152 case Tibetan: |
1166 case TradChineseFormal: | 1153 case TradChineseFormal: |
1167 case TradChineseInformal: | 1154 case TradChineseInformal: |
1168 case UpperAlpha: | 1155 case UpperAlpha: |
1169 case UpperArmenian: | 1156 case UpperArmenian: |
1170 case UpperLatin: | 1157 case UpperLatin: |
1171 case UpperRoman: | 1158 case UpperRoman: |
1172 case Urdu: | 1159 case Urdu: |
1173 m_text = listMarkerText(type, m_listItem->value()); | 1160 return LanguageSimpleStyle; |
1161 default: | |
1162 return NoneSimpleStyle; | |
1163 } | |
1164 } | |
1165 | |
1166 void LayoutListMarker::updateContent() | |
1167 { | |
1168 // FIXME: This if-statement is just a performance optimization, but it's mes sy to use the preferredLogicalWidths dirty bit for this. | |
1169 // It's unclear if this is a premature optimization. | |
1170 if (!preferredLogicalWidthsDirty()) | |
1171 return; | |
1172 | |
1173 m_text = ""; | |
1174 | |
1175 if (isImage()) { | |
1176 // FIXME: This is a somewhat arbitrary width. Generated images for mark ers really won't become particularly useful | |
1177 // until we support the CSS3 marker pseudoclass to allow control over th e width and height of the marker box. | |
1178 int bulletWidth = style()->fontMetrics().ascent() / 2; | |
eae
2015/10/12 06:02:01
Is flooring the result the tight thing to do here?
wkorman
2015/10/14 01:55:30
Likely to revise this in subsequent changes when I
| |
1179 IntSize defaultBulletSize(bulletWidth, bulletWidth); | |
1180 IntSize imageSize = calculateImageIntrinsicDimensions(m_image.get(), def aultBulletSize, DoNotScaleByEffectiveZoom); | |
1181 m_image->setContainerSizeForLayoutObject(this, imageSize, style()->effec tiveZoom()); | |
1182 return; | |
1183 } | |
1184 | |
1185 switch (simplifiedListStyle()) { | |
1186 case NoneSimpleStyle: | |
1187 break; | |
1188 case SymbolSimpleStyle: | |
1189 m_text = listMarkerText(style()->listStyleType(), 0); // value is ignore d for these types | |
1190 break; | |
1191 case LanguageSimpleStyle: | |
1192 m_text = listMarkerText(style()->listStyleType(), m_listItem->value()); | |
1174 break; | 1193 break; |
1175 } | 1194 } |
1176 } | 1195 } |
1177 | 1196 |
1197 LayoutUnit LayoutListMarker::getWidthOfTextWithSuffix(UChar* suffix, int suffixL ength) const | |
1198 { | |
1199 if (m_text.isEmpty()) | |
1200 return 0; | |
1201 | |
1202 const Font& font = style()->font(); | |
1203 LayoutUnit itemWidth = font.width(m_text); | |
1204 TextRun run = constructTextRun(font, suffix, suffixLength, styleRef(), style ()->direction()); | |
eae
2015/10/12 06:02:01
How about constructing a text run with both the te
wkorman
2015/10/14 01:55:30
Added TODO to look at this, I agree there's redund
| |
1205 LayoutUnit suffixSpaceWidth = font.width(run); | |
1206 return itemWidth + suffixSpaceWidth; | |
1207 } | |
1208 | |
1178 void LayoutListMarker::computePreferredLogicalWidths() | 1209 void LayoutListMarker::computePreferredLogicalWidths() |
1179 { | 1210 { |
1180 ASSERT(preferredLogicalWidthsDirty()); | 1211 ASSERT(preferredLogicalWidthsDirty()); |
1181 updateContent(); | 1212 updateContent(); |
1182 | 1213 |
1183 if (isImage()) { | 1214 if (isImage()) { |
1184 LayoutSize imageSize = m_image->imageSize(this, style()->effectiveZoom() ); | 1215 LayoutSize imageSize = m_image->imageSize(this, style()->effectiveZoom() ); |
1185 m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = style()->isHor izontalWritingMode() ? imageSize.width() : imageSize.height(); | 1216 m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = style()->isHor izontalWritingMode() ? imageSize.width() : imageSize.height(); |
1186 clearPreferredLogicalWidthsDirty(); | 1217 clearPreferredLogicalWidthsDirty(); |
1187 updateMargins(); | 1218 updateMargins(); |
1188 return; | 1219 return; |
1189 } | 1220 } |
1190 | 1221 |
1191 const Font& font = style()->font(); | |
1192 | |
1193 LayoutUnit logicalWidth = 0; | 1222 LayoutUnit logicalWidth = 0; |
1194 EListStyleType type = style()->listStyleType(); | 1223 switch (simplifiedListStyle()) { |
1195 switch (type) { | 1224 case NoneSimpleStyle: |
1196 case NoneListStyle: | |
1197 break; | 1225 break; |
1198 case Circle: | 1226 case SymbolSimpleStyle: { |
1199 case Disc: | 1227 // For these styles, the text of the marker will be the single character itself, |
1200 case Square: | 1228 // and so the only suffix will be a single space character to provide su fficient |
1201 logicalWidth = (font.fontMetrics().ascent() * 2 / 3 + 1) / 2 + 2; | 1229 // separation between the list marker text and the associated list item text. |
1230 UChar suffix[1] = { listMarkerSuffix(style()->listStyleType(), m_listIte m->value()) }; | |
1231 logicalWidth = getWidthOfTextWithSuffix(suffix, 1); | |
1232 } | |
1202 break; | 1233 break; |
1203 case ArabicIndic: | 1234 case LanguageSimpleStyle: { |
1204 case Armenian: | 1235 // For these styles, we have some kind of a language-specific separating |
1205 case Bengali: | 1236 // character, followed by a space character to provide sufficient |
1206 case Cambodian: | 1237 // separation between the list marker text and the associated list item text. |
1207 case CJKIdeographic: | 1238 UChar suffixSpace[2] = { listMarkerSuffix(style()->listStyleType(), m_li stItem->value()), ' ' }; |
1208 case CjkEarthlyBranch: | 1239 logicalWidth = getWidthOfTextWithSuffix(suffixSpace, 2); |
1209 case CjkHeavenlyStem: | |
1210 case DecimalLeadingZero: | |
1211 case DecimalListStyle: | |
1212 case Devanagari: | |
1213 case EthiopicHalehame: | |
1214 case EthiopicHalehameAm: | |
1215 case EthiopicHalehameTiEr: | |
1216 case EthiopicHalehameTiEt: | |
1217 case Georgian: | |
1218 case Gujarati: | |
1219 case Gurmukhi: | |
1220 case Hangul: | |
1221 case HangulConsonant: | |
1222 case KoreanHangulFormal: | |
1223 case KoreanHanjaFormal: | |
1224 case KoreanHanjaInformal: | |
1225 case Hebrew: | |
1226 case Hiragana: | |
1227 case HiraganaIroha: | |
1228 case Kannada: | |
1229 case Katakana: | |
1230 case KatakanaIroha: | |
1231 case Khmer: | |
1232 case Lao: | |
1233 case LowerAlpha: | |
1234 case LowerArmenian: | |
1235 case LowerGreek: | |
1236 case LowerLatin: | |
1237 case LowerRoman: | |
1238 case Malayalam: | |
1239 case Mongolian: | |
1240 case Myanmar: | |
1241 case Oriya: | |
1242 case Persian: | |
1243 case SimpChineseFormal: | |
1244 case SimpChineseInformal: | |
1245 case Telugu: | |
1246 case Thai: | |
1247 case Tibetan: | |
1248 case TradChineseFormal: | |
1249 case TradChineseInformal: | |
1250 case UpperAlpha: | |
1251 case UpperArmenian: | |
1252 case UpperLatin: | |
1253 case UpperRoman: | |
1254 case Urdu: | |
1255 if (m_text.isEmpty()) { | |
1256 logicalWidth = 0; | |
1257 } else { | |
1258 LayoutUnit itemWidth = font.width(m_text); | |
1259 UChar suffixSpace[2] = { listMarkerSuffix(type, m_listItem->value()) , ' ' }; | |
1260 LayoutUnit suffixSpaceWidth = font.width(constructTextRun(font, suff ixSpace, 2, styleRef(), style()->direction())); | |
1261 logicalWidth = itemWidth + suffixSpaceWidth; | |
1262 } | 1240 } |
1263 break; | 1241 break; |
1264 } | 1242 } |
1265 | 1243 |
1266 m_minPreferredLogicalWidth = logicalWidth; | 1244 m_minPreferredLogicalWidth = logicalWidth; |
1267 m_maxPreferredLogicalWidth = logicalWidth; | 1245 m_maxPreferredLogicalWidth = logicalWidth; |
1268 | 1246 |
1269 clearPreferredLogicalWidthsDirty(); | 1247 clearPreferredLogicalWidthsDirty(); |
1270 | 1248 |
1271 updateMargins(); | 1249 updateMargins(); |
1272 } | 1250 } |
1273 | 1251 |
1274 void LayoutListMarker::updateMargins() | 1252 void LayoutListMarker::updateMargins() |
1275 { | 1253 { |
1276 const FontMetrics& fontMetrics = style()->fontMetrics(); | |
1277 | |
1278 LayoutUnit marginStart = 0; | 1254 LayoutUnit marginStart = 0; |
1279 LayoutUnit marginEnd = 0; | 1255 LayoutUnit marginEnd = 0; |
1280 | 1256 |
1281 if (isInside()) { | 1257 if (isInside()) { |
1282 if (isImage()) { | 1258 if (isImage()) { |
1283 marginEnd = cMarkerPadding; | 1259 marginEnd = cMarkerPadding; |
1284 } else { | 1260 } else if (simplifiedListStyle() == SymbolSimpleStyle) { |
1285 switch (style()->listStyleType()) { | 1261 marginStart = minPreferredLogicalWidth(); |
1286 case Disc: | 1262 marginEnd = 0; |
1287 case Circle: | |
1288 case Square: | |
1289 marginStart = -1; | |
1290 marginEnd = fontMetrics.ascent() - minPreferredLogicalWidth() + 1; | |
1291 break; | |
1292 default: | |
1293 break; | |
1294 } | |
1295 } | 1263 } |
1296 } else { | 1264 } else { |
1297 if (style()->isLeftToRightDirection()) { | 1265 if (style()->isLeftToRightDirection()) { |
1298 if (isImage()) { | 1266 if (isImage()) |
1299 marginStart = -minPreferredLogicalWidth() - cMarkerPadding; | 1267 marginStart = -minPreferredLogicalWidth() - cMarkerPadding; |
1300 } else { | 1268 else if (style()->listStyleType() != NoneListStyle) |
1301 int offset = fontMetrics.ascent() * 2 / 3; | 1269 marginStart = m_text.isEmpty() ? LayoutUnit() : -minPreferredLog icalWidth(); |
1302 switch (style()->listStyleType()) { | |
1303 case Disc: | |
1304 case Circle: | |
1305 case Square: | |
1306 marginStart = -offset - cMarkerPadding - 1; | |
1307 break; | |
1308 case NoneListStyle: | |
1309 break; | |
1310 default: | |
1311 marginStart = m_text.isEmpty() ? LayoutUnit() : -minPreferre dLogicalWidth() - offset / 2; | |
1312 } | |
1313 } | |
1314 marginEnd = -marginStart - minPreferredLogicalWidth(); | 1270 marginEnd = -marginStart - minPreferredLogicalWidth(); |
1315 } else { | 1271 } else { |
1316 if (isImage()) { | 1272 if (isImage()) |
1317 marginEnd = cMarkerPadding; | 1273 marginEnd = cMarkerPadding; |
1318 } else { | 1274 else if (style()->listStyleType() != NoneListStyle) |
1319 int offset = fontMetrics.ascent() * 2 / 3; | 1275 marginEnd = 0; |
1320 switch (style()->listStyleType()) { | |
1321 case Disc: | |
1322 case Circle: | |
1323 case Square: | |
1324 marginEnd = offset + cMarkerPadding + 1 - minPreferredLogica lWidth(); | |
1325 break; | |
1326 case NoneListStyle: | |
1327 break; | |
1328 default: | |
1329 marginEnd = m_text.isEmpty() ? 0 : offset / 2; | |
1330 } | |
1331 } | |
1332 marginStart = -marginEnd - minPreferredLogicalWidth(); | 1276 marginStart = -marginEnd - minPreferredLogicalWidth(); |
1333 } | 1277 } |
1334 | |
1335 } | 1278 } |
1336 | 1279 |
1337 mutableStyleRef().setMarginStart(Length(marginStart, Fixed)); | 1280 mutableStyleRef().setMarginStart(Length(marginStart, Fixed)); |
1338 mutableStyleRef().setMarginEnd(Length(marginEnd, Fixed)); | 1281 mutableStyleRef().setMarginEnd(Length(marginEnd, Fixed)); |
1339 } | 1282 } |
1340 | 1283 |
1341 LayoutUnit LayoutListMarker::lineHeight(bool firstLine, LineDirectionMode direct ion, LinePositionMode linePositionMode) const | 1284 LayoutUnit LayoutListMarker::lineHeight(bool firstLine, LineDirectionMode direct ion, LinePositionMode linePositionMode) const |
1342 { | 1285 { |
1343 if (!isImage()) | 1286 if (!isImage()) |
1344 return m_listItem->lineHeight(firstLine, direction, PositionOfInteriorLi neBoxes); | 1287 return m_listItem->lineHeight(firstLine, direction, PositionOfInteriorLi neBoxes); |
(...skipping 12 matching lines...) Expand all Loading... | |
1357 { | 1300 { |
1358 return m_listItem->notInList() || style()->listStylePosition() == INSIDE; | 1301 return m_listItem->notInList() || style()->listStylePosition() == INSIDE; |
1359 } | 1302 } |
1360 | 1303 |
1361 IntRect LayoutListMarker::getRelativeMarkerRect() const | 1304 IntRect LayoutListMarker::getRelativeMarkerRect() const |
1362 { | 1305 { |
1363 if (isImage()) | 1306 if (isImage()) |
1364 return IntRect(0, 0, m_image->imageSize(this, style()->effectiveZoom()). width(), m_image->imageSize(this, style()->effectiveZoom()).height()); | 1307 return IntRect(0, 0, m_image->imageSize(this, style()->effectiveZoom()). width(), m_image->imageSize(this, style()->effectiveZoom()).height()); |
1365 | 1308 |
1366 IntRect relativeRect; | 1309 IntRect relativeRect; |
1367 EListStyleType type = style()->listStyleType(); | 1310 switch (simplifiedListStyle()) { |
1368 switch (type) { | 1311 case NoneSimpleStyle: |
1369 case Disc: | 1312 return IntRect(); |
1370 case Circle: | 1313 case SymbolSimpleStyle: { |
1371 case Square: { | 1314 // For these styles, the text of the marker will be the single character itself, |
1372 // FIXME: Are these particular rounding rules necessary? | 1315 // and so the only suffix will be a single space character to provide su fficient |
1373 const FontMetrics& fontMetrics = style()->fontMetrics(); | 1316 // separation between the list marker text and the associated list item text. |
1374 int ascent = fontMetrics.ascent(); | 1317 UChar suffix[1] = { listMarkerSuffix(style()->listStyleType(), m_listIte m->value()) }; |
1375 int bulletWidth = (ascent * 2 / 3 + 1) / 2; | 1318 LayoutUnit itemWidth = getWidthOfTextWithSuffix(suffix, 1); |
1376 relativeRect = IntRect(1, 3 * (ascent - ascent * 2 / 3) / 2, bulletWidth , bulletWidth); | 1319 relativeRect = IntRect(0, 0, itemWidth, style()->font().fontMetrics().he ight()); |
1320 } | |
1377 break; | 1321 break; |
1378 } | 1322 case LanguageSimpleStyle: { |
1379 case NoneListStyle: | 1323 // For these styles, we have some kind of a language-specific separating |
1380 return IntRect(); | 1324 // character, followed by a space character to provide sufficient |
1381 case ArabicIndic: | 1325 // separation between the list marker text and the associated list item text. |
1382 case Armenian: | 1326 UChar suffixSpace[2] = { listMarkerSuffix(style()->listStyleType(), m_li stItem->value()), ' ' }; |
1383 case Bengali: | 1327 LayoutUnit itemWidth = getWidthOfTextWithSuffix(suffixSpace, 2); |
1384 case Cambodian: | 1328 relativeRect = IntRect(0, 0, itemWidth, style()->font().fontMetrics().he ight()); |
1385 case CJKIdeographic: | 1329 } |
1386 case CjkEarthlyBranch: | 1330 break; |
1387 case CjkHeavenlyStem: | |
1388 case DecimalLeadingZero: | |
1389 case DecimalListStyle: | |
1390 case Devanagari: | |
1391 case EthiopicHalehame: | |
1392 case EthiopicHalehameAm: | |
1393 case EthiopicHalehameTiEr: | |
1394 case EthiopicHalehameTiEt: | |
1395 case Georgian: | |
1396 case Gujarati: | |
1397 case Gurmukhi: | |
1398 case Hangul: | |
1399 case KoreanHangulFormal: | |
1400 case KoreanHanjaFormal: | |
1401 case KoreanHanjaInformal: | |
1402 case HangulConsonant: | |
1403 case Hebrew: | |
1404 case Hiragana: | |
1405 case HiraganaIroha: | |
1406 case Kannada: | |
1407 case Katakana: | |
1408 case KatakanaIroha: | |
1409 case Khmer: | |
1410 case Lao: | |
1411 case LowerAlpha: | |
1412 case LowerArmenian: | |
1413 case LowerGreek: | |
1414 case LowerLatin: | |
1415 case LowerRoman: | |
1416 case Malayalam: | |
1417 case Mongolian: | |
1418 case Myanmar: | |
1419 case Oriya: | |
1420 case Persian: | |
1421 case SimpChineseFormal: | |
1422 case SimpChineseInformal: | |
1423 case Telugu: | |
1424 case Thai: | |
1425 case Tibetan: | |
1426 case TradChineseFormal: | |
1427 case TradChineseInformal: | |
1428 case UpperAlpha: | |
1429 case UpperArmenian: | |
1430 case UpperLatin: | |
1431 case UpperRoman: | |
1432 case Urdu: | |
1433 if (m_text.isEmpty()) | |
1434 return IntRect(); | |
1435 const Font& font = style()->font(); | |
1436 int itemWidth = font.width(m_text); | |
1437 UChar suffixSpace[2] = { listMarkerSuffix(type, m_listItem->value()), ' ' }; | |
1438 int suffixSpaceWidth = font.width(constructTextRun(font, suffixSpace, 2, styleRef(), style()->direction())); | |
1439 relativeRect = IntRect(0, 0, itemWidth + suffixSpaceWidth, font.fontMetr ics().height()); | |
1440 } | 1331 } |
1441 | 1332 |
1442 if (!style()->isHorizontalWritingMode()) { | 1333 if (!style()->isHorizontalWritingMode()) { |
1443 relativeRect = relativeRect.transposedRect(); | 1334 relativeRect = relativeRect.transposedRect(); |
1444 relativeRect.setX(size().width() - relativeRect.x() - relativeRect.width ()); | 1335 relativeRect.setX(size().width() - relativeRect.x() - relativeRect.width ()); |
1445 } | 1336 } |
1446 | 1337 |
1447 return relativeRect; | 1338 return relativeRect; |
1448 } | 1339 } |
1449 | 1340 |
1450 void LayoutListMarker::setSelectionState(SelectionState state) | 1341 void LayoutListMarker::setSelectionState(SelectionState state) |
1451 { | 1342 { |
1452 // The selection state for our containing block hierarchy is updated by the base class call. | 1343 // The selection state for our containing block hierarchy is updated by the base class call. |
1453 LayoutBox::setSelectionState(state); | 1344 LayoutBox::setSelectionState(state); |
1454 | 1345 |
1455 if (inlineBoxWrapper() && canUpdateSelectionOnRootLineBoxes()) | 1346 if (inlineBoxWrapper() && canUpdateSelectionOnRootLineBoxes()) |
1456 inlineBoxWrapper()->root().setHasSelectedChildren(state != SelectionNone ); | 1347 inlineBoxWrapper()->root().setHasSelectedChildren(state != SelectionNone ); |
1457 } | 1348 } |
1458 | 1349 |
1459 LayoutRect LayoutListMarker::selectionRectForPaintInvalidation(const LayoutBoxMo delObject* paintInvalidationContainer) const | 1350 LayoutRect LayoutListMarker::selectionRectForPaintInvalidation(const LayoutBoxMo delObject* paintInvalidationContainer) const |
1460 { | 1351 { |
1461 ASSERT(!needsLayout()); | 1352 ASSERT(!needsLayout()); |
1462 | 1353 |
1463 if (selectionState() == SelectionNone || !inlineBoxWrapper()) | 1354 if (selectionState() == SelectionNone || !inlineBoxWrapper()) |
1464 return LayoutRect(); | 1355 return LayoutRect(); |
1465 | 1356 |
1357 // TODO(wkorman): Make sure the output rect from this method matches what we expect to see. | |
1358 | |
1466 RootInlineBox& root = inlineBoxWrapper()->root(); | 1359 RootInlineBox& root = inlineBoxWrapper()->root(); |
1467 LayoutRect rect(0, root.selectionTop() - location().y(), size().width(), roo t.selectionHeight()); | 1360 LayoutRect rect(0, root.selectionTop() - location().y(), size().width(), roo t.selectionHeight()); |
1468 mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, 0); | 1361 mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, 0); |
1469 // FIXME: groupedMapping() leaks the squashing abstraction. | 1362 // FIXME: groupedMapping() leaks the squashing abstraction. |
1470 if (paintInvalidationContainer->layer()->groupedMapping()) | 1363 if (paintInvalidationContainer->layer()->groupedMapping()) |
1471 PaintLayer::mapRectToPaintBackingCoordinates(paintInvalidationContainer, rect); | 1364 PaintLayer::mapRectToPaintBackingCoordinates(paintInvalidationContainer, rect); |
1472 return rect; | 1365 return rect; |
1473 } | 1366 } |
1474 | 1367 |
1475 void LayoutListMarker::listItemStyleDidChange() | 1368 void LayoutListMarker::listItemStyleDidChange() |
1476 { | 1369 { |
1477 RefPtr<ComputedStyle> newStyle = ComputedStyle::create(); | 1370 RefPtr<ComputedStyle> newStyle = ComputedStyle::create(); |
1478 // The marker always inherits from the list item, regardless of where it mig ht end | 1371 // The marker always inherits from the list item, regardless of where it mig ht end |
1479 // up (e.g., in some deeply nested line box). See CSS3 spec. | 1372 // up (e.g., in some deeply nested line box). See CSS3 spec. |
1480 newStyle->inheritFrom(m_listItem->styleRef()); | 1373 newStyle->inheritFrom(m_listItem->styleRef()); |
1481 if (style()) { | 1374 if (style()) { |
1482 // Reuse the current margins. Otherwise resetting the margins to initial values | 1375 // Reuse the current margins. Otherwise resetting the margins to initial values |
1483 // would trigger unnecessary layout. | 1376 // would trigger unnecessary layout. |
1484 newStyle->setMarginStart(style()->marginStart()); | 1377 newStyle->setMarginStart(style()->marginStart()); |
1485 newStyle->setMarginEnd(style()->marginRight()); | 1378 newStyle->setMarginEnd(style()->marginRight()); |
1486 } | 1379 } |
1487 setStyle(newStyle.release()); | 1380 setStyle(newStyle.release()); |
1488 } | 1381 } |
1489 | 1382 |
1490 } // namespace blink | 1383 } // namespace blink |
OLD | NEW |