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(
text_box->GetLineLayoutItem().StyleRef(IsFirstLineStyle());
if (!text_box->GetEmphasisMarkPosition(style, emphasis_mark_position))
return false;
if (IsHorizontal()) {
return emphasis_mark_position == TextEmphasisPosition::kOverRight ||
emphasis_mark_position == TextEmphasisPosition::kOverLeft;
}
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;
LineLogicalSide side = style.GetTextEmphasisLineLogicalSide();
if (IsHorizontal() || !style.IsFlippedLinesWritingMode())
return side == LineLogicalSide::kOver;
return side == LineLogicalSide::kUnder;
}
inline bool InlineFlowBox::HasEmphasisMarkOver(
const InlineTextBox* text_box) const {
const auto& style =
text_box->GetLineLayoutItem().StyleRef(IsFirstLineStyle());
TextEmphasisPosition emphasis_mark_position;
if (!text_box->GetEmphasisMarkPosition(
text_box->GetLineLayoutItem().StyleRef(IsFirstLineStyle()),
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;
return text_box->GetEmphasisMarkPosition(style, emphasis_mark_position) &&
style.GetTextEmphasisLineLogicalSide() == LineLogicalSide::kOver;
}
inline bool InlineFlowBox::HasEmphasisMarkUnder(
const InlineTextBox* text_box) const {
const auto& style =
text_box->GetLineLayoutItem().StyleRef(IsFirstLineStyle());
TextEmphasisPosition emphasis_mark_position;
if (!text_box->GetEmphasisMarkPosition(
text_box->GetLineLayoutItem().StyleRef(IsFirstLineStyle()),
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;
return text_box->GetEmphasisMarkPosition(style, emphasis_mark_position) &&
style.GetTextEmphasisLineLogicalSide() == LineLogicalSide::kUnder;
}
void InlineFlowBox::AddToLine(InlineBox* child) {
......
......@@ -518,12 +518,7 @@ bool InlineTextBox::GetEmphasisMarkPosition(
emphasis_position = style.GetTextEmphasisPosition();
// Ruby text is always over, so it cannot suppress emphasis marks under.
if ((IsHorizontal() &&
(emphasis_position == TextEmphasisPosition::kUnderRight ||
emphasis_position == TextEmphasisPosition::kUnderLeft)) ||
(!IsHorizontal() &&
(emphasis_position == TextEmphasisPosition::kOverLeft ||
emphasis_position == TextEmphasisPosition::kUnderLeft)))
if (style.GetTextEmphasisLineLogicalSide() != LineLogicalSide::kOver)
return true;
LineLayoutBox containing_block = GetLineLayoutItem().ContainingBlock();
......
......@@ -14,36 +14,47 @@ NGPhysicalOffsetRect NGPhysicalTextFragment::SelfVisualRect() const {
if (!shape_result_)
return {};
// TODO(kojii): Copying InlineTextBox logic from
// InlineFlowBox::ComputeOverflow().
//
// 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();
// Glyph bounds is in logical coordinate, origin at the alphabetic baseline.
LayoutRect visual_rect = EnclosingLayoutRect(shape_result_->Bounds());
// Make the origin at the logical top of this fragment.
// ShapeResult::Bounds() is in logical coordinate with alphabetic baseline.
const ComputedStyle& style = Style();
const SimpleFontData* font_data = style.GetFont().PrimaryFont();
visual_float_rect.SetY(
visual_float_rect.Y() +
font_data->GetFontMetrics().FixedAscent(kAlphabeticBaseline));
const Font& font = style.GetFont();
const SimpleFontData* font_data = font.PrimaryFont();
if (font_data) {
visual_rect.SetY(visual_rect.Y() + font_data->GetFontMetrics().FixedAscent(
kAlphabeticBaseline));
}
// TODO(kojii): Copying from AddTextBoxVisualOverflow()
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()) {
// 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()) {
case NGLineOrientation::kHorizontal:
return NGPhysicalOffsetRect(visual_rect);
......
......@@ -1359,6 +1359,26 @@ const AtomicString& ComputedStyle::TextEmphasisMarkString() const {
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() {
if (!AnimationsInternal())
SetAnimationsInternal(CSSAnimationData::Create());
......
......@@ -878,6 +878,7 @@ class ComputedStyle : public ComputedStyleBase,
SetTextEmphasisMarkInternal(mark);
}
const AtomicString& TextEmphasisMarkString() const;
LineLogicalSide GetTextEmphasisLineLogicalSide() const;
// -webkit-text-emphasis-color (aka -epub-text-emphasis-color)
void SetTextEmphasisColor(const StyleColor& color) {
......
......@@ -248,6 +248,11 @@ enum TextEmphasisPosition {
kUnderLeft,
};
enum class LineLogicalSide {
kOver,
kUnder,
};
} // namespace blink
#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