未验证 提交 a144f17a 编写于 作者: J Justin McCandless 提交者: GitHub

Tight Paragraph Width (#8530)

Calculate and expose paragraph tightWidth to the framework to allow drawing Text based on this.
上级 06fea14e
......@@ -1315,6 +1315,12 @@ class Paragraph extends NativeFieldWrapperClass2 {
/// Valid only after [layout] has been called.
double get height native 'Paragraph_height';
/// The distance from the left edge of the leftmost glyph to the right edge of
/// the rightmost glyph in the paragraph.
///
/// Valid only after [layout] has been called.
double get tightWidth native 'Paragraph_tightWidth';
/// The minimum width that this paragraph could be without failing to paint
/// its contents within itself.
///
......
......@@ -22,6 +22,7 @@ IMPLEMENT_WRAPPERTYPEINFO(ui, Paragraph);
#define FOR_EACH_BINDING(V) \
V(Paragraph, width) \
V(Paragraph, height) \
V(Paragraph, tightWidth) \
V(Paragraph, minIntrinsicWidth) \
V(Paragraph, maxIntrinsicWidth) \
V(Paragraph, alphabeticBaseline) \
......@@ -56,6 +57,10 @@ double Paragraph::height() {
return m_paragraphImpl->height();
}
double Paragraph::tightWidth() {
return m_paragraphImpl->tightWidth();
}
double Paragraph::minIntrinsicWidth() {
return m_paragraphImpl->minIntrinsicWidth();
}
......
......@@ -33,6 +33,7 @@ class Paragraph : public RefCountedDartWrappable<Paragraph> {
double width();
double height();
double tightWidth();
double minIntrinsicWidth();
double maxIntrinsicWidth();
double alphabeticBaseline();
......
......@@ -19,6 +19,8 @@ class ParagraphImpl {
virtual double height() = 0;
virtual double tightWidth() = 0;
virtual double minIntrinsicWidth() = 0;
virtual double maxIntrinsicWidth() = 0;
......
......@@ -29,6 +29,10 @@ double ParagraphImplTxt::height() {
return m_paragraph->GetHeight();
}
double ParagraphImplTxt::tightWidth() {
return m_paragraph->GetTightWidth();
}
double ParagraphImplTxt::minIntrinsicWidth() {
return m_paragraph->GetMinIntrinsicWidth();
}
......
......@@ -19,6 +19,7 @@ class ParagraphImplTxt : public ParagraphImpl {
double width() override;
double height() override;
double tightWidth() override;
double minIntrinsicWidth() override;
double maxIntrinsicWidth() override;
double alphabeticBaseline() override;
......
......@@ -919,6 +919,8 @@ void Paragraph::Layout(double width, bool force) {
[](const CodeUnitRun& a, const CodeUnitRun& b) {
return a.code_units.start < b.code_units.start;
});
tight_width_ = max_right_ - min_left_;
}
double Paragraph::GetLineXOffset(double line_total_advance) {
......@@ -970,6 +972,10 @@ double Paragraph::GetMaxWidth() const {
return width_;
}
double Paragraph::GetTightWidth() const {
return tight_width_;
}
void Paragraph::SetParagraphStyle(const ParagraphStyle& style) {
needs_layout_ = true;
paragraph_style_ = style;
......
......@@ -155,6 +155,12 @@ class Paragraph {
// GetMaxWidth() >= GetLayoutWidth().
double GetMaxWidth() const;
// Returns the tight width found in Layout(), which is defined as the
// horizontal distance from the left edge of the leftmost glyph to the right
// edge of the rightmost glyph. We expect that GetTightWidth() <=
// GetMaxWidth().
double GetTightWidth() const;
// Distance from top of paragraph to the Alphabetic baseline of the first
// line. Used for alphabetic fonts (A-Z, a-z, greek, etc.)
double GetAlphabeticBaseline() const;
......@@ -348,6 +354,7 @@ class Paragraph {
// The max width of the paragraph as provided in the most recent Layout()
// call.
double width_ = -1.0f;
double tight_width_ = -1.0f;
double max_intrinsic_width_ = 0;
double min_intrinsic_width_ = 0;
double alphabetic_baseline_ = FLT_MAX;
......
......@@ -264,6 +264,19 @@ TEST_F(ParagraphTest, BoldParagraph) {
ASSERT_TRUE(paragraph->runs_.styles_[1].equals(text_style));
ASSERT_EQ(paragraph->records_[0].style().color, text_style.color);
ASSERT_TRUE(Snapshot());
// width_ takes the full available space, but tight_width_ is only the width
// of the text, which is less than one line.
ASSERT_DOUBLE_EQ(paragraph->width_, GetTestCanvasWidth());
ASSERT_TRUE(paragraph->tight_width_ < paragraph->width_);
Paragraph::RectHeightStyle rect_height_style =
Paragraph::RectHeightStyle::kMax;
Paragraph::RectWidthStyle rect_width_style =
Paragraph::RectWidthStyle::kTight;
std::vector<txt::Paragraph::TextBox> boxes = paragraph->GetRectsForRange(
0, strlen(text), rect_height_style, rect_width_style);
ASSERT_DOUBLE_EQ(paragraph->tight_width_,
boxes[boxes.size() - 1].rect.right() - boxes[0].rect.left());
}
TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(LeftAlignParagraph)) {
......@@ -407,7 +420,8 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(RightAlignParagraph)) {
builder.Pop();
auto paragraph = builder.Build();
paragraph->Layout(GetTestCanvasWidth() - 100);
int available_width = GetTestCanvasWidth() - 100;
paragraph->Layout(available_width);
paragraph->Paint(GetCanvas(), 0, 0);
......@@ -432,6 +446,14 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(RightAlignParagraph)) {
paragraph->breaker_.getWidths()[paragraph->records_[0].line()],
2.0);
// width_ takes the full available space, while tight_width_ wraps the glyphs
// as tightly as possible. Even though this text is more than one line long,
// no line perfectly spans the width of the full line, so tight_width_ is less
// than width_.
ASSERT_DOUBLE_EQ(paragraph->width_, available_width);
ASSERT_TRUE(paragraph->tight_width_ < available_width);
ASSERT_DOUBLE_EQ(paragraph->tight_width_, 893.19921875);
ASSERT_TRUE(paragraph->records_[2].style().equals(text_style));
ASSERT_DOUBLE_EQ(paragraph->records_[2].offset().y(), expected_y);
expected_y += 30;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册