Index: third_party/WebKit/Source/core/layout/LayoutListMarker.cpp |
diff --git a/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp b/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp |
index e44011989136eb710c69f07f7d3fbbd11ed657bc..fe1550abdd90d77779d3fae9782bee4b69ef99cd 100644 |
--- a/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp |
+++ b/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp |
@@ -36,6 +36,9 @@ |
namespace blink { |
+// TODO(wkorman): A seemingly arbitrary number tacked on following any image |
+// and included as part of margin for any text. Look into history, other |
+// browser behavior, and update or remove as appropriate. |
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.
|
enum SequenceType { NumericSequence, AlphabeticSequence }; |
@@ -1034,8 +1037,11 @@ LayoutRect LayoutListMarker::localSelectionRect() const |
if (!box) |
return LayoutRect(LayoutPoint(), size()); |
RootInlineBox& root = inlineBoxWrapper()->root(); |
- LayoutUnit newLogicalTop = root.block().style()->isFlippedBlocksWritingMode() ? inlineBoxWrapper()->logicalBottom() - root.selectionBottom() : root.selectionTop() - inlineBoxWrapper()->logicalTop(); |
- if (root.block().style()->isHorizontalWritingMode()) |
+ const ComputedStyle* blockStyle = root.block().style(); |
+ LayoutUnit newLogicalTop = blockStyle->isFlippedBlocksWritingMode() |
+ ? inlineBoxWrapper()->logicalBottom() - root.selectionBottom() |
+ : root.selectionTop() - inlineBoxWrapper()->logicalTop(); |
+ if (blockStyle->isHorizontalWritingMode()) |
return LayoutRect(0, newLogicalTop, size().width(), root.selectionHeight()); |
return LayoutRect(newLogicalTop, 0, root.selectionHeight(), size().height()); |
} |
@@ -1090,34 +1096,15 @@ void LayoutListMarker::updateMarginsAndContent() |
updateMargins(); |
} |
-void LayoutListMarker::updateContent() |
+LayoutListMarker::SimplifiedListStyle LayoutListMarker::simplifiedListStyle() const |
{ |
- // FIXME: This if-statement is just a performance optimization, but it's messy to use the preferredLogicalWidths dirty bit for this. |
- // It's unclear if this is a premature optimization. |
- if (!preferredLogicalWidthsDirty()) |
- return; |
- |
- m_text = ""; |
- |
- if (isImage()) { |
- // FIXME: This is a somewhat arbitrary width. Generated images for markers really won't become particularly useful |
- // until we support the CSS3 marker pseudoclass to allow control over the width and height of the marker box. |
- int bulletWidth = style()->fontMetrics().ascent() / 2; |
- IntSize defaultBulletSize(bulletWidth, bulletWidth); |
- IntSize imageSize = calculateImageIntrinsicDimensions(m_image.get(), defaultBulletSize, DoNotScaleByEffectiveZoom); |
- m_image->setContainerSizeForLayoutObject(this, imageSize, style()->effectiveZoom()); |
- return; |
- } |
- |
- EListStyleType type = style()->listStyleType(); |
- switch (type) { |
+ switch (style()->listStyleType()) { |
case NoneListStyle: |
- break; |
- case Circle: |
+ return NoneSimpleStyle; |
case Disc: |
+ case Circle: |
case Square: |
- m_text = listMarkerText(type, 0); // value is ignored for these types |
- break; |
+ return SymbolSimpleStyle; |
case ArabicIndic: |
case Armenian: |
case Bengali: |
@@ -1135,12 +1122,12 @@ void LayoutListMarker::updateContent() |
case Georgian: |
case Gujarati: |
case Gurmukhi: |
+ case Hebrew: |
case Hangul: |
case HangulConsonant: |
case KoreanHangulFormal: |
case KoreanHanjaFormal: |
case KoreanHanjaInformal: |
- case Hebrew: |
case Hiragana: |
case HiraganaIroha: |
case Kannada: |
@@ -1170,11 +1157,55 @@ void LayoutListMarker::updateContent() |
case UpperLatin: |
case UpperRoman: |
case Urdu: |
- m_text = listMarkerText(type, m_listItem->value()); |
+ return LanguageSimpleStyle; |
+ default: |
+ return NoneSimpleStyle; |
+ } |
+} |
+ |
+void LayoutListMarker::updateContent() |
+{ |
+ // FIXME: This if-statement is just a performance optimization, but it's messy to use the preferredLogicalWidths dirty bit for this. |
+ // It's unclear if this is a premature optimization. |
+ if (!preferredLogicalWidthsDirty()) |
+ return; |
+ |
+ m_text = ""; |
+ |
+ if (isImage()) { |
+ // FIXME: This is a somewhat arbitrary width. Generated images for markers really won't become particularly useful |
+ // until we support the CSS3 marker pseudoclass to allow control over the width and height of the marker box. |
+ 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
|
+ IntSize defaultBulletSize(bulletWidth, bulletWidth); |
+ IntSize imageSize = calculateImageIntrinsicDimensions(m_image.get(), defaultBulletSize, DoNotScaleByEffectiveZoom); |
+ m_image->setContainerSizeForLayoutObject(this, imageSize, style()->effectiveZoom()); |
+ return; |
+ } |
+ |
+ switch (simplifiedListStyle()) { |
+ case NoneSimpleStyle: |
+ break; |
+ case SymbolSimpleStyle: |
+ m_text = listMarkerText(style()->listStyleType(), 0); // value is ignored for these types |
+ break; |
+ case LanguageSimpleStyle: |
+ m_text = listMarkerText(style()->listStyleType(), m_listItem->value()); |
break; |
} |
} |
+LayoutUnit LayoutListMarker::getWidthOfTextWithSuffix(UChar* suffix, int suffixLength) const |
+{ |
+ if (m_text.isEmpty()) |
+ return 0; |
+ |
+ const Font& font = style()->font(); |
+ LayoutUnit itemWidth = font.width(m_text); |
+ 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
|
+ LayoutUnit suffixSpaceWidth = font.width(run); |
+ return itemWidth + suffixSpaceWidth; |
+} |
+ |
void LayoutListMarker::computePreferredLogicalWidths() |
{ |
ASSERT(preferredLogicalWidthsDirty()); |
@@ -1188,77 +1219,24 @@ void LayoutListMarker::computePreferredLogicalWidths() |
return; |
} |
- const Font& font = style()->font(); |
- |
LayoutUnit logicalWidth = 0; |
- EListStyleType type = style()->listStyleType(); |
- switch (type) { |
- case NoneListStyle: |
+ switch (simplifiedListStyle()) { |
+ case NoneSimpleStyle: |
break; |
- case Circle: |
- case Disc: |
- case Square: |
- logicalWidth = (font.fontMetrics().ascent() * 2 / 3 + 1) / 2 + 2; |
+ case SymbolSimpleStyle: { |
+ // For these styles, the text of the marker will be the single character itself, |
+ // and so the only suffix will be a single space character to provide sufficient |
+ // separation between the list marker text and the associated list item text. |
+ UChar suffix[1] = { listMarkerSuffix(style()->listStyleType(), m_listItem->value()) }; |
+ logicalWidth = getWidthOfTextWithSuffix(suffix, 1); |
+ } |
break; |
- case ArabicIndic: |
- case Armenian: |
- case Bengali: |
- case Cambodian: |
- case CJKIdeographic: |
- case CjkEarthlyBranch: |
- case CjkHeavenlyStem: |
- case DecimalLeadingZero: |
- case DecimalListStyle: |
- case Devanagari: |
- case EthiopicHalehame: |
- case EthiopicHalehameAm: |
- case EthiopicHalehameTiEr: |
- case EthiopicHalehameTiEt: |
- case Georgian: |
- case Gujarati: |
- case Gurmukhi: |
- case Hangul: |
- case HangulConsonant: |
- case KoreanHangulFormal: |
- case KoreanHanjaFormal: |
- case KoreanHanjaInformal: |
- case Hebrew: |
- case Hiragana: |
- case HiraganaIroha: |
- case Kannada: |
- case Katakana: |
- case KatakanaIroha: |
- case Khmer: |
- case Lao: |
- case LowerAlpha: |
- case LowerArmenian: |
- case LowerGreek: |
- case LowerLatin: |
- case LowerRoman: |
- case Malayalam: |
- case Mongolian: |
- case Myanmar: |
- case Oriya: |
- case Persian: |
- case SimpChineseFormal: |
- case SimpChineseInformal: |
- case Telugu: |
- case Thai: |
- case Tibetan: |
- case TradChineseFormal: |
- case TradChineseInformal: |
- case UpperAlpha: |
- case UpperArmenian: |
- case UpperLatin: |
- case UpperRoman: |
- case Urdu: |
- if (m_text.isEmpty()) { |
- logicalWidth = 0; |
- } else { |
- LayoutUnit itemWidth = font.width(m_text); |
- UChar suffixSpace[2] = { listMarkerSuffix(type, m_listItem->value()), ' ' }; |
- LayoutUnit suffixSpaceWidth = font.width(constructTextRun(font, suffixSpace, 2, styleRef(), style()->direction())); |
- logicalWidth = itemWidth + suffixSpaceWidth; |
+ case LanguageSimpleStyle: { |
+ // For these styles, we have some kind of a language-specific separating |
+ // character, followed by a space character to provide sufficient |
+ // separation between the list marker text and the associated list item text. |
+ UChar suffixSpace[2] = { listMarkerSuffix(style()->listStyleType(), m_listItem->value()), ' ' }; |
+ logicalWidth = getWidthOfTextWithSuffix(suffixSpace, 2); |
} |
break; |
} |
@@ -1273,65 +1251,30 @@ void LayoutListMarker::computePreferredLogicalWidths() |
void LayoutListMarker::updateMargins() |
{ |
- const FontMetrics& fontMetrics = style()->fontMetrics(); |
- |
LayoutUnit marginStart = 0; |
LayoutUnit marginEnd = 0; |
if (isInside()) { |
if (isImage()) { |
marginEnd = cMarkerPadding; |
- } else { |
- switch (style()->listStyleType()) { |
- case Disc: |
- case Circle: |
- case Square: |
- marginStart = -1; |
- marginEnd = fontMetrics.ascent() - minPreferredLogicalWidth() + 1; |
- break; |
- default: |
- break; |
- } |
+ } else if (simplifiedListStyle() == SymbolSimpleStyle) { |
+ marginStart = minPreferredLogicalWidth(); |
+ marginEnd = 0; |
} |
} else { |
if (style()->isLeftToRightDirection()) { |
- if (isImage()) { |
+ if (isImage()) |
marginStart = -minPreferredLogicalWidth() - cMarkerPadding; |
- } else { |
- int offset = fontMetrics.ascent() * 2 / 3; |
- switch (style()->listStyleType()) { |
- case Disc: |
- case Circle: |
- case Square: |
- marginStart = -offset - cMarkerPadding - 1; |
- break; |
- case NoneListStyle: |
- break; |
- default: |
- marginStart = m_text.isEmpty() ? LayoutUnit() : -minPreferredLogicalWidth() - offset / 2; |
- } |
- } |
+ else if (style()->listStyleType() != NoneListStyle) |
+ marginStart = m_text.isEmpty() ? LayoutUnit() : -minPreferredLogicalWidth(); |
marginEnd = -marginStart - minPreferredLogicalWidth(); |
} else { |
- if (isImage()) { |
+ if (isImage()) |
marginEnd = cMarkerPadding; |
- } else { |
- int offset = fontMetrics.ascent() * 2 / 3; |
- switch (style()->listStyleType()) { |
- case Disc: |
- case Circle: |
- case Square: |
- marginEnd = offset + cMarkerPadding + 1 - minPreferredLogicalWidth(); |
- break; |
- case NoneListStyle: |
- break; |
- default: |
- marginEnd = m_text.isEmpty() ? 0 : offset / 2; |
- } |
- } |
+ else if (style()->listStyleType() != NoneListStyle) |
+ marginEnd = 0; |
marginStart = -marginEnd - minPreferredLogicalWidth(); |
} |
- |
} |
mutableStyleRef().setMarginStart(Length(marginStart, Fixed)); |
@@ -1364,79 +1307,27 @@ IntRect LayoutListMarker::getRelativeMarkerRect() const |
return IntRect(0, 0, m_image->imageSize(this, style()->effectiveZoom()).width(), m_image->imageSize(this, style()->effectiveZoom()).height()); |
IntRect relativeRect; |
- EListStyleType type = style()->listStyleType(); |
- switch (type) { |
- case Disc: |
- case Circle: |
- case Square: { |
- // FIXME: Are these particular rounding rules necessary? |
- const FontMetrics& fontMetrics = style()->fontMetrics(); |
- int ascent = fontMetrics.ascent(); |
- int bulletWidth = (ascent * 2 / 3 + 1) / 2; |
- relativeRect = IntRect(1, 3 * (ascent - ascent * 2 / 3) / 2, bulletWidth, bulletWidth); |
- break; |
- } |
- case NoneListStyle: |
+ switch (simplifiedListStyle()) { |
+ case NoneSimpleStyle: |
return IntRect(); |
- case ArabicIndic: |
- case Armenian: |
- case Bengali: |
- case Cambodian: |
- case CJKIdeographic: |
- case CjkEarthlyBranch: |
- case CjkHeavenlyStem: |
- case DecimalLeadingZero: |
- case DecimalListStyle: |
- case Devanagari: |
- case EthiopicHalehame: |
- case EthiopicHalehameAm: |
- case EthiopicHalehameTiEr: |
- case EthiopicHalehameTiEt: |
- case Georgian: |
- case Gujarati: |
- case Gurmukhi: |
- case Hangul: |
- case KoreanHangulFormal: |
- case KoreanHanjaFormal: |
- case KoreanHanjaInformal: |
- case HangulConsonant: |
- case Hebrew: |
- case Hiragana: |
- case HiraganaIroha: |
- case Kannada: |
- case Katakana: |
- case KatakanaIroha: |
- case Khmer: |
- case Lao: |
- case LowerAlpha: |
- case LowerArmenian: |
- case LowerGreek: |
- case LowerLatin: |
- case LowerRoman: |
- case Malayalam: |
- case Mongolian: |
- case Myanmar: |
- case Oriya: |
- case Persian: |
- case SimpChineseFormal: |
- case SimpChineseInformal: |
- case Telugu: |
- case Thai: |
- case Tibetan: |
- case TradChineseFormal: |
- case TradChineseInformal: |
- case UpperAlpha: |
- case UpperArmenian: |
- case UpperLatin: |
- case UpperRoman: |
- case Urdu: |
- if (m_text.isEmpty()) |
- return IntRect(); |
- const Font& font = style()->font(); |
- int itemWidth = font.width(m_text); |
- UChar suffixSpace[2] = { listMarkerSuffix(type, m_listItem->value()), ' ' }; |
- int suffixSpaceWidth = font.width(constructTextRun(font, suffixSpace, 2, styleRef(), style()->direction())); |
- relativeRect = IntRect(0, 0, itemWidth + suffixSpaceWidth, font.fontMetrics().height()); |
+ case SymbolSimpleStyle: { |
+ // For these styles, the text of the marker will be the single character itself, |
+ // and so the only suffix will be a single space character to provide sufficient |
+ // separation between the list marker text and the associated list item text. |
+ UChar suffix[1] = { listMarkerSuffix(style()->listStyleType(), m_listItem->value()) }; |
+ LayoutUnit itemWidth = getWidthOfTextWithSuffix(suffix, 1); |
+ relativeRect = IntRect(0, 0, itemWidth, style()->font().fontMetrics().height()); |
+ } |
+ break; |
+ case LanguageSimpleStyle: { |
+ // For these styles, we have some kind of a language-specific separating |
+ // character, followed by a space character to provide sufficient |
+ // separation between the list marker text and the associated list item text. |
+ UChar suffixSpace[2] = { listMarkerSuffix(style()->listStyleType(), m_listItem->value()), ' ' }; |
+ LayoutUnit itemWidth = getWidthOfTextWithSuffix(suffixSpace, 2); |
+ relativeRect = IntRect(0, 0, itemWidth, style()->font().fontMetrics().height()); |
+ } |
+ break; |
} |
if (!style()->isHorizontalWritingMode()) { |
@@ -1463,6 +1354,8 @@ LayoutRect LayoutListMarker::selectionRectForPaintInvalidation(const LayoutBoxMo |
if (selectionState() == SelectionNone || !inlineBoxWrapper()) |
return LayoutRect(); |
+ // TODO(wkorman): Make sure the output rect from this method matches what we expect to see. |
+ |
RootInlineBox& root = inlineBoxWrapper()->root(); |
LayoutRect rect(0, root.selectionTop() - location().y(), size().width(), root.selectionHeight()); |
mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, 0); |