Commit a9a959da authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

[LayoutNG] Implement visual overflow for NGPhysicalTextFragment

This patch implements all the rest of logic to compute visual
overflow for NGPhysicalTextFragment.

In doing so, this patch also refactors text-emphasis logic to
share with the pre-NG code.

Bug: 636993, 714962
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_layout_ng
Change-Id: Ib800a9b4264dfe724d59fdb220e7c0d43513685a
Reviewed-on: https://chromium-review.googlesource.com/776638Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#523386}
parent bc34071d
...@@ -98,49 +98,28 @@ inline bool InlineFlowBox::HasEmphasisMarkBefore( ...@@ -98,49 +98,28 @@ inline bool InlineFlowBox::HasEmphasisMarkBefore(
text_box->GetLineLayoutItem().StyleRef(IsFirstLineStyle()); text_box->GetLineLayoutItem().StyleRef(IsFirstLineStyle());
if (!text_box->GetEmphasisMarkPosition(style, emphasis_mark_position)) if (!text_box->GetEmphasisMarkPosition(style, emphasis_mark_position))
return false; return false;
if (IsHorizontal()) { LineLogicalSide side = style.GetTextEmphasisLineLogicalSide();
return emphasis_mark_position == TextEmphasisPosition::kOverRight || if (IsHorizontal() || !style.IsFlippedLinesWritingMode())
emphasis_mark_position == TextEmphasisPosition::kOverLeft; return side == LineLogicalSide::kOver;
} return side == LineLogicalSide::kUnder;
if (style.IsFlippedLinesWritingMode()) {
return emphasis_mark_position == TextEmphasisPosition::kOverLeft ||
emphasis_mark_position == TextEmphasisPosition::kUnderLeft;
}
if (style.IsFlippedBlocksWritingMode()) {
return emphasis_mark_position == TextEmphasisPosition::kOverRight ||
emphasis_mark_position == TextEmphasisPosition::kUnderRight;
}
return false;
} }
inline bool InlineFlowBox::HasEmphasisMarkOver( inline bool InlineFlowBox::HasEmphasisMarkOver(
const InlineTextBox* text_box) const { const InlineTextBox* text_box) const {
const auto& style =
text_box->GetLineLayoutItem().StyleRef(IsFirstLineStyle());
TextEmphasisPosition emphasis_mark_position; TextEmphasisPosition emphasis_mark_position;
if (!text_box->GetEmphasisMarkPosition( return text_box->GetEmphasisMarkPosition(style, emphasis_mark_position) &&
text_box->GetLineLayoutItem().StyleRef(IsFirstLineStyle()), style.GetTextEmphasisLineLogicalSide() == LineLogicalSide::kOver;
emphasis_mark_position))
return false;
return IsHorizontal()
? emphasis_mark_position == TextEmphasisPosition::kOverRight ||
emphasis_mark_position == TextEmphasisPosition::kOverLeft
: emphasis_mark_position == TextEmphasisPosition::kOverRight ||
emphasis_mark_position == TextEmphasisPosition::kUnderRight;
} }
inline bool InlineFlowBox::HasEmphasisMarkUnder( inline bool InlineFlowBox::HasEmphasisMarkUnder(
const InlineTextBox* text_box) const { const InlineTextBox* text_box) const {
const auto& style =
text_box->GetLineLayoutItem().StyleRef(IsFirstLineStyle());
TextEmphasisPosition emphasis_mark_position; TextEmphasisPosition emphasis_mark_position;
if (!text_box->GetEmphasisMarkPosition( return text_box->GetEmphasisMarkPosition(style, emphasis_mark_position) &&
text_box->GetLineLayoutItem().StyleRef(IsFirstLineStyle()), style.GetTextEmphasisLineLogicalSide() == LineLogicalSide::kUnder;
emphasis_mark_position))
return false;
return IsHorizontal()
? emphasis_mark_position == TextEmphasisPosition::kUnderRight ||
emphasis_mark_position == TextEmphasisPosition::kUnderLeft
: emphasis_mark_position == TextEmphasisPosition::kOverLeft ||
emphasis_mark_position == TextEmphasisPosition::kUnderLeft;
} }
void InlineFlowBox::AddToLine(InlineBox* child) { void InlineFlowBox::AddToLine(InlineBox* child) {
......
...@@ -518,12 +518,7 @@ bool InlineTextBox::GetEmphasisMarkPosition( ...@@ -518,12 +518,7 @@ bool InlineTextBox::GetEmphasisMarkPosition(
emphasis_position = style.GetTextEmphasisPosition(); emphasis_position = style.GetTextEmphasisPosition();
// Ruby text is always over, so it cannot suppress emphasis marks under. // Ruby text is always over, so it cannot suppress emphasis marks under.
if ((IsHorizontal() && if (style.GetTextEmphasisLineLogicalSide() != LineLogicalSide::kOver)
(emphasis_position == TextEmphasisPosition::kUnderRight ||
emphasis_position == TextEmphasisPosition::kUnderLeft)) ||
(!IsHorizontal() &&
(emphasis_position == TextEmphasisPosition::kOverLeft ||
emphasis_position == TextEmphasisPosition::kUnderLeft)))
return true; return true;
LineLayoutBox containing_block = GetLineLayoutItem().ContainingBlock(); LineLayoutBox containing_block = GetLineLayoutItem().ContainingBlock();
......
...@@ -14,36 +14,47 @@ NGPhysicalOffsetRect NGPhysicalTextFragment::SelfVisualRect() const { ...@@ -14,36 +14,47 @@ NGPhysicalOffsetRect NGPhysicalTextFragment::SelfVisualRect() const {
if (!shape_result_) if (!shape_result_)
return {}; return {};
// TODO(kojii): Copying InlineTextBox logic from // Glyph bounds is in logical coordinate, origin at the alphabetic baseline.
// InlineFlowBox::ComputeOverflow(). LayoutRect visual_rect = EnclosingLayoutRect(shape_result_->Bounds());
//
// InlineFlowBox::ComputeOverflow() computes GlpyhOverflow first
// (ComputeGlyphOverflow) then AddTextBoxVisualOverflow(). We probably don't
// have to keep these two steps separated.
// Glyph bounds is in logical coordinate, origin at the baseline.
FloatRect visual_float_rect = shape_result_->Bounds();
// Make the origin at the logical top of this fragment. // Make the origin at the logical top of this fragment.
// ShapeResult::Bounds() is in logical coordinate with alphabetic baseline.
const ComputedStyle& style = Style(); const ComputedStyle& style = Style();
const SimpleFontData* font_data = style.GetFont().PrimaryFont(); const Font& font = style.GetFont();
visual_float_rect.SetY( const SimpleFontData* font_data = font.PrimaryFont();
visual_float_rect.Y() + if (font_data) {
font_data->GetFontMetrics().FixedAscent(kAlphabeticBaseline)); visual_rect.SetY(visual_rect.Y() + font_data->GetFontMetrics().FixedAscent(
kAlphabeticBaseline));
}
// TODO(kojii): Copying from AddTextBoxVisualOverflow()
if (float stroke_width = style.TextStrokeWidth()) { if (float stroke_width = style.TextStrokeWidth()) {
visual_float_rect.Inflate(stroke_width / 2.0f); visual_rect.Inflate(LayoutUnit::FromFloatCeil(stroke_width / 2.0f));
} }
// TODO(kojii): Implement emphasis marks. if (style.GetTextEmphasisMark() != TextEmphasisMark::kNone) {
LayoutUnit emphasis_mark_height =
LayoutUnit(font.EmphasisMarkHeight(style.TextEmphasisMarkString()));
DCHECK_GT(emphasis_mark_height, LayoutUnit());
if (style.GetTextEmphasisLineLogicalSide() == LineLogicalSide::kOver) {
visual_rect.ShiftYEdgeTo(
std::min(visual_rect.Y(), -emphasis_mark_height));
} else {
LayoutUnit logical_height =
style.IsHorizontalWritingMode() ? Size().height : Size().width;
visual_rect.ShiftMaxYEdgeTo(
std::max(visual_rect.MaxY(), logical_height + emphasis_mark_height));
}
}
if (ShadowList* text_shadow = style.TextShadow()) { if (ShadowList* text_shadow = style.TextShadow()) {
// TODO(kojii): Implement text shadow. LayoutRectOutsets text_shadow_logical_outsets =
LayoutRectOutsets(text_shadow->RectOutsetsIncludingOriginal())
.LineOrientationOutsets(style.GetWritingMode());
text_shadow_logical_outsets.ClampNegativeToZero();
visual_rect.Expand(text_shadow_logical_outsets);
} }
LayoutRect visual_rect = EnclosingLayoutRect(visual_float_rect); visual_rect = LayoutRect(EnclosingIntRect(visual_rect));
switch (LineOrientation()) { switch (LineOrientation()) {
case NGLineOrientation::kHorizontal: case NGLineOrientation::kHorizontal:
return NGPhysicalOffsetRect(visual_rect); return NGPhysicalOffsetRect(visual_rect);
......
...@@ -1359,6 +1359,26 @@ const AtomicString& ComputedStyle::TextEmphasisMarkString() const { ...@@ -1359,6 +1359,26 @@ const AtomicString& ComputedStyle::TextEmphasisMarkString() const {
return g_null_atom; return g_null_atom;
} }
LineLogicalSide ComputedStyle::GetTextEmphasisLineLogicalSide() const {
TextEmphasisPosition position = GetTextEmphasisPosition();
if (IsHorizontalWritingMode()) {
return position == TextEmphasisPosition::kOverRight ||
position == TextEmphasisPosition::kOverLeft
? LineLogicalSide::kOver
: LineLogicalSide::kUnder;
}
if (GetWritingMode() != WritingMode::kSidewaysLr) {
return position == TextEmphasisPosition::kOverRight ||
position == TextEmphasisPosition::kUnderRight
? LineLogicalSide::kOver
: LineLogicalSide::kUnder;
}
return position == TextEmphasisPosition::kOverLeft ||
position == TextEmphasisPosition::kUnderLeft
? LineLogicalSide::kOver
: LineLogicalSide::kUnder;
}
CSSAnimationData& ComputedStyle::AccessAnimations() { CSSAnimationData& ComputedStyle::AccessAnimations() {
if (!AnimationsInternal()) if (!AnimationsInternal())
SetAnimationsInternal(CSSAnimationData::Create()); SetAnimationsInternal(CSSAnimationData::Create());
......
...@@ -878,6 +878,7 @@ class ComputedStyle : public ComputedStyleBase, ...@@ -878,6 +878,7 @@ class ComputedStyle : public ComputedStyleBase,
SetTextEmphasisMarkInternal(mark); SetTextEmphasisMarkInternal(mark);
} }
const AtomicString& TextEmphasisMarkString() const; const AtomicString& TextEmphasisMarkString() const;
LineLogicalSide GetTextEmphasisLineLogicalSide() const;
// -webkit-text-emphasis-color (aka -epub-text-emphasis-color) // -webkit-text-emphasis-color (aka -epub-text-emphasis-color)
void SetTextEmphasisColor(const StyleColor& color) { void SetTextEmphasisColor(const StyleColor& color) {
......
...@@ -248,6 +248,11 @@ enum TextEmphasisPosition { ...@@ -248,6 +248,11 @@ enum TextEmphasisPosition {
kUnderLeft, kUnderLeft,
}; };
enum class LineLogicalSide {
kOver,
kUnder,
};
} // namespace blink } // namespace blink
#endif // ComputedStyleConstants_h #endif // ComputedStyleConstants_h
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment