mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Tight Paragraph Width (#8530)
Calculate and expose paragraph tightWidth to the framework to allow drawing Text based on this.
This commit is contained in:
parent
06fea14e58
commit
a144f17aee
@ -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;
|
||||
|
||||
6
third_party/txt/src/txt/paragraph.cc
vendored
6
third_party/txt/src/txt/paragraph.cc
vendored
@ -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;
|
||||
|
||||
7
third_party/txt/src/txt/paragraph.h
vendored
7
third_party/txt/src/txt/paragraph.h
vendored
@ -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;
|
||||
|
||||
24
third_party/txt/tests/paragraph_unittests.cc
vendored
24
third_party/txt/tests/paragraph_unittests.cc
vendored
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user