From bdc3efa0cc9e7a84c4ec9dadcfbc282d48b59a9b Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Tue, 17 Jan 2017 13:55:43 -0500 Subject: [PATCH] Add support for a maxLines property on Paragraph. (flutter/engine#3338) Also fix 'ellipsis' overflow handling to work for multiline text. Fixes https://github.com/flutter/flutter/issues/7271 --- engine/src/flutter/lib/ui/text.dart | 21 ++++++++++++++----- .../flutter/lib/ui/text/paragraph_builder.cc | 20 +++++++++++------- .../flutter/lib/ui/text/paragraph_builder.h | 2 ++ 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/engine/src/flutter/lib/ui/text.dart b/engine/src/flutter/lib/ui/text.dart index 19270c7ec7..66761bf23f 100644 --- a/engine/src/flutter/lib/ui/text.dart +++ b/engine/src/flutter/lib/ui/text.dart @@ -384,6 +384,7 @@ Int32List _encodeParagraphStyle(TextAlign textAlign, String fontFamily, double fontSize, double lineHeight, + int maxLines, String ellipsis) { Int32List result = new Int32List(5); if (textAlign != null) { @@ -414,10 +415,14 @@ Int32List _encodeParagraphStyle(TextAlign textAlign, result[0] |= 1 << 7; // Passed separately to native. } - if (ellipsis != null) { + if (maxLines != null) { result[0] |= 1 << 8; // Passed separately to native. } + if (ellipsis != null) { + result[0] |= 1 << 9; + // Passed separately to native. + } return result; } @@ -441,6 +446,7 @@ class ParagraphStyle { String fontFamily, double fontSize, double lineHeight, + int maxLines, String ellipsis }) : _encoded = _encodeParagraphStyle(textAlign, fontWeight, @@ -449,10 +455,12 @@ class ParagraphStyle { fontFamily, fontSize, lineHeight, + maxLines, ellipsis), _fontFamily = fontFamily, _fontSize = fontSize, _lineHeight = lineHeight, + _maxLines = maxLines, _ellipsis = ellipsis { assert(lineCount == null); } @@ -461,6 +469,7 @@ class ParagraphStyle { final String _fontFamily; final double _fontSize; final double _lineHeight; + final int _maxLines; final String _ellipsis; bool operator ==(dynamic other) { @@ -472,6 +481,7 @@ class ParagraphStyle { if ( _fontFamily != typedOther._fontFamily || _fontSize != typedOther._fontSize || _lineHeight != typedOther._lineHeight || + _maxLines != typedOther._maxLines || _ellipsis != typedOther._ellipsis) return false; for (int index = 0; index < _encoded.length; index += 1) { @@ -481,7 +491,7 @@ class ParagraphStyle { return true; } - int get hashCode => hashValues(hashList(_encoded), _lineHeight); + int get hashCode => hashValues(hashList(_encoded), _lineHeight, _maxLines, _ellipsis); String toString() { return 'ParagraphStyle(' @@ -492,7 +502,8 @@ class ParagraphStyle { 'fontFamily: ${ _encoded[0] & 0x20 == 0x20 ? _fontFamily : "unspecified"}, ' 'fontSize: ${ _encoded[0] & 0x40 == 0x40 ? _fontSize : "unspecified"}, ' 'lineHeight: ${ _encoded[0] & 0x80 == 0x80 ? "${_lineHeight}x" : "unspecified"}, ' - 'ellipsis: ${ _encoded[0] & 0x100 == 0x100 ? "\"$_ellipsis\"" : "unspecified"}' + 'maxLines: ${ _encoded[0] & 0x100 == 0x100 ? _maxLines : "unspecified"}, ' + 'ellipsis: ${ _encoded[0] & 0x200 == 0x200 ? "\"$_ellipsis\"" : "unspecified"}' ')'; } } @@ -716,8 +727,8 @@ abstract class Paragraph extends NativeFieldWrapperClass2 { class ParagraphBuilder extends NativeFieldWrapperClass2 { /// Creates a [ParagraphBuilder] object, which is used to create a /// [Paragraph]. - ParagraphBuilder(ParagraphStyle style) { _constructor(style._encoded, style._fontFamily, style._fontSize, style._lineHeight, style._ellipsis); } - void _constructor(Int32List encoded, String fontFamily, double fontSize, double lineHeight, String ellipsis) native "ParagraphBuilder_constructor"; + ParagraphBuilder(ParagraphStyle style) { _constructor(style._encoded, style._fontFamily, style._fontSize, style._lineHeight, style._maxLines, style._ellipsis); } + void _constructor(Int32List encoded, String fontFamily, double fontSize, double lineHeight, int maxLines, String ellipsis) native "ParagraphBuilder_constructor"; /// Applies the given style to the added text until [pop] is called. /// diff --git a/engine/src/flutter/lib/ui/text/paragraph_builder.cc b/engine/src/flutter/lib/ui/text/paragraph_builder.cc index 6745698c75..f60a759590 100644 --- a/engine/src/flutter/lib/ui/text/paragraph_builder.cc +++ b/engine/src/flutter/lib/ui/text/paragraph_builder.cc @@ -57,7 +57,8 @@ const int psFontStyleIndex = 3; const int psFontFamilyIndex = 5; const int psFontSizeIndex = 6; const int psLineHeightIndex = 7; -const int psEllipsisIndex = 8; +const int psMaxLinesIndex = 8; +const int psEllipsisIndex = 9; const int psTextAlignMask = 1 << psTextAlignIndex; const int psFontWeightMask = 1 << psFontWeightIndex; @@ -65,6 +66,7 @@ const int psFontStyleMask = 1 << psFontStyleIndex; const int psFontFamilyMask = 1 << psFontFamilyIndex; const int psFontSizeMask = 1 << psFontSizeIndex; const int psLineHeightMask = 1 << psLineHeightIndex; +const int psMaxLinesMask = 1 << psMaxLinesIndex; const int psEllipsisMask = 1 << psEllipsisIndex; float getComputedSizeFromSpecifiedSize(float specifiedSize) { @@ -100,6 +102,7 @@ PassRefPtr decodeParagraphStyle( const std::string& fontFamily, double fontSize, double lineHeight, + int maxLines, const std::string& ellipsis) { FTL_DCHECK(encoded.num_elements() == 5); @@ -144,10 +147,11 @@ PassRefPtr decodeParagraphStyle( if (mask & psLineHeightMask) style->setLineHeight(Length(lineHeight * 100.0, Percent)); - if (mask & psEllipsisMask) { + if (mask & psMaxLinesMask) + style->setMaxLines(maxLines); + + if (mask & psEllipsisMask) style->setEllipsis(AtomicString::fromUTF8(ellipsis.c_str())); - style->setWordBreak(BreakAllWordBreak); - } return style.release(); } @@ -175,7 +179,7 @@ FOR_EACH_BINDING(DART_NATIVE_CALLBACK) void ParagraphBuilder::RegisterNatives(tonic::DartLibraryNatives* natives) { natives->Register( - {{"ParagraphBuilder_constructor", ParagraphBuilder_constructor, 6, true}, + {{"ParagraphBuilder_constructor", ParagraphBuilder_constructor, 7, true}, FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); } @@ -184,20 +188,22 @@ ftl::RefPtr ParagraphBuilder::create( const std::string& fontFamily, double fontSize, double lineHeight, + int maxLines, const std::string& ellipsis) { return ftl::MakeRefCounted( - encoded, fontFamily, fontSize, lineHeight, ellipsis); + encoded, fontFamily, fontSize, lineHeight, maxLines, ellipsis); } ParagraphBuilder::ParagraphBuilder(tonic::Int32List& encoded, const std::string& fontFamily, double fontSize, double lineHeight, + int maxLines, const std::string& ellipsis) { createRenderView(); RefPtr paragraphStyle = decodeParagraphStyle( - m_renderView->style(), encoded, fontFamily, fontSize, lineHeight, ellipsis); + m_renderView->style(), encoded, fontFamily, fontSize, lineHeight, maxLines, ellipsis); encoded.Release(); m_renderParagraph = new RenderParagraph(); diff --git a/engine/src/flutter/lib/ui/text/paragraph_builder.h b/engine/src/flutter/lib/ui/text/paragraph_builder.h index 7a156f23c2..17a9fb779a 100644 --- a/engine/src/flutter/lib/ui/text/paragraph_builder.h +++ b/engine/src/flutter/lib/ui/text/paragraph_builder.h @@ -25,6 +25,7 @@ class ParagraphBuilder : public ftl::RefCountedThreadSafe, const std::string& fontFamily, double fontSize, double lineHeight, + int maxLines, const std::string& ellipsis); ~ParagraphBuilder() override; @@ -48,6 +49,7 @@ class ParagraphBuilder : public ftl::RefCountedThreadSafe, const std::string& fontFamily, double fontSize, double lineHeight, + int maxLines, const std::string& ellipsis); void createRenderView();