未验证 提交 82ccba30 编写于 作者: J Jason Simmons 提交者: GitHub

libtxt: have GetRectsForRange(strut) fall back to tight bounds if layout isn't...

libtxt: have GetRectsForRange(strut) fall back to tight bounds if layout isn't forcing use of the strut (#9058)
上级 8dc3a4cd
......@@ -1235,6 +1235,8 @@ enum BoxHeightStyle {
/// entire paragraph. The top edge of each line will align with the bottom
/// edge of the previous line. It is possible for glyphs to extend outside
/// these boxes.
///
/// Will fall back to tight bounds if the strut is disabled or invalid.
strut,
}
......
......@@ -1429,6 +1429,8 @@ enum BoxHeightStyle {
/// entire paragraph. The top edge of each line will align with the bottom
/// edge of the previous line. It is possible for glyphs to extend outside
/// these boxes.
///
/// Will fall back to tight bounds if the strut is disabled or invalid.
strut,
}
......
......@@ -425,6 +425,12 @@ bool Paragraph::ComputeBidiRuns(std::vector<BidiRun>* result) {
return true;
}
bool Paragraph::IsStrutValid() const {
// Font size must be positive.
return (paragraph_style_.strut_enabled &&
paragraph_style_.strut_font_size >= 0);
}
void Paragraph::ComputeStrut(StrutMetrics* strut, SkFont& font) {
strut->ascent = 0;
strut->descent = 0;
......@@ -433,15 +439,12 @@ void Paragraph::ComputeStrut(StrutMetrics* strut, SkFont& font) {
strut->line_height = 0;
strut->force_strut = false;
// Font size must be positive.
bool valid_strut =
paragraph_style_.strut_enabled && paragraph_style_.strut_font_size >= 0;
if (!valid_strut) {
if (!IsStrutValid())
return;
}
// force_strut makes all lines have exactly the strut metrics, and ignores all
// actual metrics. We only force the strut if the strut is non-zero and valid.
strut->force_strut = paragraph_style_.force_strut_height && valid_strut;
strut->force_strut = paragraph_style_.force_strut_height;
minikin::FontStyle minikin_font_style(
0, GetWeight(paragraph_style_.strut_font_weight),
paragraph_style_.strut_font_style == FontStyle::italic);
......@@ -1458,12 +1461,18 @@ std::vector<Paragraph::TextBox> Paragraph::GetRectsForRange(
box.direction);
}
} else if (rect_height_style == RectHeightStyle::kStrut) {
for (const Paragraph::TextBox& box : kv.second.boxes) {
boxes.emplace_back(
SkRect::MakeLTRB(
box.rect.fLeft, line_baselines_[kv.first] - strut_.ascent,
box.rect.fRight, line_baselines_[kv.first] + strut_.descent),
box.direction);
if (IsStrutValid()) {
for (const Paragraph::TextBox& box : kv.second.boxes) {
boxes.emplace_back(
SkRect::MakeLTRB(
box.rect.fLeft, line_baselines_[kv.first] - strut_.ascent,
box.rect.fRight, line_baselines_[kv.first] + strut_.descent),
box.direction);
}
} else {
// Fall back to tight bounds if the strut is invalid.
boxes.insert(boxes.end(), kv.second.boxes.begin(),
kv.second.boxes.end());
}
}
}
......
......@@ -405,6 +405,8 @@ class Paragraph {
// Calculates and populates strut based on paragraph_style_ strut info.
void ComputeStrut(StrutMetrics* strut, SkFont& font);
bool IsStrutValid() const;
// Calculate the starting X offset of a line based on the line's width and
// alignment.
double GetLineXOffset(double line_total_advance);
......
......@@ -2259,6 +2259,41 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(GetRectsForRangeStrut)) {
ASSERT_TRUE(Snapshot());
}
TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(GetRectsForRangeStrutFallback)) {
const char* text = "Chinese 字典";
auto icu_text = icu::UnicodeString::fromUTF8(text);
std::u16string u16_text(icu_text.getBuffer(),
icu_text.getBuffer() + icu_text.length());
txt::ParagraphStyle paragraph_style;
paragraph_style.strut_enabled = false;
txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection());
txt::TextStyle text_style;
text_style.font_families.push_back("Noto Sans CJK JP");
text_style.font_size = 20;
builder.PushStyle(text_style);
builder.AddText(u16_text);
builder.Pop();
auto paragraph = builder.Build();
paragraph->Layout(550);
std::vector<txt::Paragraph::TextBox> strut_boxes =
paragraph->GetRectsForRange(0, 10, Paragraph::RectHeightStyle::kStrut,
Paragraph::RectWidthStyle::kMax);
std::vector<txt::Paragraph::TextBox> tight_boxes =
paragraph->GetRectsForRange(0, 10, Paragraph::RectHeightStyle::kTight,
Paragraph::RectWidthStyle::kMax);
ASSERT_EQ(strut_boxes.size(), 1ull);
ASSERT_EQ(tight_boxes.size(), 1ull);
ASSERT_EQ(strut_boxes.front().rect, tight_boxes.front().rect);
}
SkRect GetCoordinatesForGlyphPosition(const txt::Paragraph& paragraph,
size_t pos) {
std::vector<txt::Paragraph::TextBox> boxes =
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册