Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(209)

Unified Diff: ui/gfx/render_text_unittest.cc

Issue 2767163003: Vertically center multi-line RenderTextHarfBuzz that uses SetMinLineHeight(). (Closed)
Patch Set: respond to comments Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/gfx/render_text_harfbuzz.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/render_text_unittest.cc
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc
index dfd2111875670aa5eab66ab8ce8a42a10630db6c..d262f5f5d790806a4c9ef9fd07d905702f08f243 100644
--- a/ui/gfx/render_text_unittest.cc
+++ b/ui/gfx/render_text_unittest.cc
@@ -116,6 +116,10 @@ class RenderTextTestApi {
return render_text_->GetAlignmentOffset(line_number);
}
+ int GetDisplayTextBaseline() {
+ return render_text_->GetDisplayTextBaseline();
+ }
+
private:
RenderText* render_text_;
@@ -4405,6 +4409,100 @@ TEST_P(RenderTextTest, InvalidFont) {
DrawVisualText();
}
+// Ensures that text is centered vertically and consistently when either the
+// display rectangle height changes, or when the minimum line height changes.
+// The difference between the two is the selection rectangle, which should match
+// the line height.
+TEST_P(RenderTextHarfBuzzTest, BaselineWithLineHeight) {
+ RenderText* render_text = GetRenderText();
+ const int font_height = render_text->font_list().GetHeight();
+ render_text->SetDisplayRect(Rect(500, font_height));
+ render_text->SetText(ASCIIToUTF16("abc"));
+
+ // Select everything so the test can use GetSelectionBoundsUnion().
+ render_text->SelectAll(false);
+
+ const int normal_baseline = test_api()->GetDisplayTextBaseline();
+ ASSERT_EQ(1u, test_api()->lines().size());
+ EXPECT_EQ(font_height, test_api()->lines()[0].size.height());
+
+ // With a matching display height, the baseline calculated using font metrics
+ // and the baseline from the layout engine should agree. This works because
+ // the text string is simple (exotic glyphs may use fonts with different
+ // metrics).
+ EXPECT_EQ(normal_baseline, render_text->GetBaseline());
+ EXPECT_EQ(0, render_text->GetLineOffset(0).y());
+
+ const gfx::Rect normal_selection_bounds = GetSelectionBoundsUnion();
+
+ // Sanity check: selection should start from (0,0).
+ EXPECT_EQ(gfx::Vector2d(), normal_selection_bounds.OffsetFromOrigin());
+
+ constexpr int kDelta = 16;
+
+ // Grow just the display rectangle.
+ render_text->SetDisplayRect(Rect(500, font_height + kDelta));
+
+ // The display text baseline does not move: GetLineOffset() moves it instead.
+ EXPECT_EQ(normal_baseline, test_api()->GetDisplayTextBaseline());
+
+ ASSERT_EQ(1u, test_api()->lines().size());
+ EXPECT_EQ(font_height, test_api()->lines()[0].size.height());
+
+ // Save the baseline calculated using the display rectangle before enabling
+ // multi-line or SetMinLineHeight().
+ const int reported_baseline = render_text->GetBaseline();
+ const int baseline_shift = reported_baseline - normal_baseline;
+
+ // When line height matches font height, this should match the line offset.
+ EXPECT_EQ(baseline_shift, render_text->GetLineOffset(0).y());
+
+ // The actual shift depends on font metrics, and the calculations done in
+ // RenderText::DetermineBaselineCenteringText(). Do a sanity check that the
+ // "centering" part is happening within some tolerance by ensuring the shift
+ // is within a pixel of (kDelta / 2). That is, 7, 8 or 9 pixels (for a delta
+ // of 16). An unusual font in future may need more leeway.
+ constexpr int kFuzz = 1; // If the next EXPECT fails, try increasing this.
+ EXPECT_LE(abs(baseline_shift - kDelta / 2), kFuzz);
+
+ // Increasing display height (but not line height) should shift the selection
+ // bounds down by |baseline_shift|, but leave a matching size.
+ gfx::Rect current_selection_bounds = GetSelectionBoundsUnion();
+ EXPECT_EQ(baseline_shift, current_selection_bounds.y());
+ EXPECT_EQ(0, current_selection_bounds.x());
+ EXPECT_EQ(normal_selection_bounds.size(), current_selection_bounds.size());
+
+ // Now increase the line height, but remain single-line. Note the line height
+ // now matches the display rect.
+ render_text->SetMinLineHeight(font_height + kDelta);
+ int display_text_baseline = test_api()->GetDisplayTextBaseline();
+ ASSERT_EQ(1u, test_api()->lines().size());
+ EXPECT_EQ(font_height + kDelta, test_api()->lines()[0].size.height());
+
+ // The line offset should go back to zero, but now the display text baseline
+ // should shift down to compensate, and the shift amount should match.
+ EXPECT_EQ(0, render_text->GetLineOffset(0).y());
+ EXPECT_EQ(normal_baseline + baseline_shift, display_text_baseline);
+
+ // Now selection bounds should grow in height, but not shift its origin.
+ current_selection_bounds = GetSelectionBoundsUnion();
+ EXPECT_EQ(font_height + kDelta, current_selection_bounds.height());
+ EXPECT_EQ(normal_selection_bounds.width(), current_selection_bounds.width());
+ EXPECT_EQ(gfx::Vector2d(), current_selection_bounds.OffsetFromOrigin());
+
+ // Flipping the multiline flag should change nothing.
+ render_text->SetMultiline(true);
+ display_text_baseline = test_api()->GetDisplayTextBaseline();
+ ASSERT_EQ(1u, test_api()->lines().size());
+ EXPECT_EQ(font_height + kDelta, test_api()->lines()[0].size.height());
+ EXPECT_EQ(0, render_text->GetLineOffset(0).y());
+ EXPECT_EQ(normal_baseline + baseline_shift, display_text_baseline);
+ current_selection_bounds = GetSelectionBoundsUnion();
+ EXPECT_EQ(font_height + kDelta, current_selection_bounds.height());
+ EXPECT_EQ(normal_selection_bounds.width(), current_selection_bounds.width());
+ EXPECT_EQ(gfx::Vector2d(), current_selection_bounds.OffsetFromOrigin());
+}
+
// Prefix for test instantiations intentionally left blank since each test
// fixture class has a single parameterization.
#if defined(OS_MACOSX)
« no previous file with comments | « ui/gfx/render_text_harfbuzz.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698