提交 d4610712 编写于 作者: J Jason Simmons 提交者: GitHub

Revise the paragraph style API to include custom ellipsis strings (#3071)

上级 5f7b0605
......@@ -93,15 +93,6 @@ enum TextAlign {
center
}
/// How to handle text that overflows its bounds
enum TextOverflow {
/// Default
clip,
/// Render as a single line that is ellipsized if it is too wide to fit
ellipsis
}
/// A horizontal line used for aligning text
enum TextBaseline {
// The horizontal line used to align the bottom of glyphs for alphabetic characters
......@@ -371,12 +362,12 @@ class TextStyle {
// This encoding must match the C++ version ParagraphBuilder::build.
//
// The encoded array buffer has 4 elements.
// The encoded array buffer has 5 elements.
//
// - Element 0: A bit field where the ith bit indicates wheter the ith element
// has a non-null value. Bit 6 indicates whether |fontFamily| is non-null.
// Bit 7 indicates whether |fontSize| is non-null. Bit 8 indicates whether
// |lineHeight| is non-null. Bit 0 is unused.
// - Element 0: A bit mask indicating which fields are non-null.
// Bit 0 is unused. Bits 1-n are set if the corresponding index in the
// encoded array is non-null. The remaining bits represent fields that
// are passed separately from the array.
//
// - Element 1: The enum index of the |textAlign|.
//
......@@ -384,15 +375,16 @@ class TextStyle {
//
// - Element 3: The enum index of the |fontStyle|.
//
// - Element 4: The enum index of the |textOverflow|.
// - Element 4: The value of |lineCount|.
//
Int32List _encodeParagraphStyle(TextAlign textAlign,
FontWeight fontWeight,
FontStyle fontStyle,
TextOverflow textOverflow,
int lineCount,
String fontFamily,
double fontSize,
double lineHeight) {
double lineHeight,
String ellipsis) {
Int32List result = new Int32List(5);
if (textAlign != null) {
result[0] |= 1 << 1;
......@@ -406,9 +398,9 @@ Int32List _encodeParagraphStyle(TextAlign textAlign,
result[0] |= 1 << 3;
result[3] = fontStyle.index;
}
if (textOverflow != null) {
if (lineCount != null) {
result[0] |= 1 << 4;
result[4] = textOverflow.index;
result[4] = lineCount;
}
if (fontFamily != null) {
result[0] |= 1 << 5;
......@@ -422,6 +414,10 @@ Int32List _encodeParagraphStyle(TextAlign textAlign,
result[0] |= 1 << 7;
// Passed separately to native.
}
if (ellipsis != null) {
result[0] |= 1 << 8;
// Passed separately to native.
}
return result;
}
......@@ -432,32 +428,40 @@ class ParagraphStyle {
/// * `textAlign`: The alignment of the text within the lines of the paragraph.
/// * `fontWeight`: The typeface thickness to use when painting the text (e.g., bold).
/// * `fontStyle`: The typeface variant to use when drawing the letters (e.g., italics).
/// * `lineCount`: Currently not implemented.
/// * `fontFamily`: The name of the font to use when painting the text (e.g., Roboto).
/// * `fontSize`: The size of glyphs (in logical pixels) to use when painting the text.
/// * `lineHeight`: The minimum height of the line boxes, as a multiple of the font size.
/// * `ellipsis`: String used to ellipsize overflowing text.
ParagraphStyle({
TextAlign textAlign,
FontWeight fontWeight,
FontStyle fontStyle,
TextOverflow textOverflow,
int lineCount,
String fontFamily,
double fontSize,
double lineHeight
double lineHeight,
String ellipsis
}) : _encoded = _encodeParagraphStyle(textAlign,
fontWeight,
fontStyle,
textOverflow,
lineCount,
fontFamily,
fontSize,
lineHeight),
lineHeight,
ellipsis),
_fontFamily = fontFamily,
_fontSize = fontSize,
_lineHeight = lineHeight;
_lineHeight = lineHeight,
_ellipsis = ellipsis {
assert(lineCount == null);
}
final Int32List _encoded;
final String _fontFamily;
final double _fontSize;
final double _lineHeight;
final String _ellipsis;
bool operator ==(dynamic other) {
if (identical(this, other))
......@@ -467,7 +471,8 @@ class ParagraphStyle {
final ParagraphStyle typedOther = other;
if ( _fontFamily != typedOther._fontFamily ||
_fontSize != typedOther._fontSize ||
_lineHeight != typedOther._lineHeight)
_lineHeight != typedOther._lineHeight ||
_ellipsis != typedOther._ellipsis)
return false;
for (int index = 0; index < _encoded.length; index += 1) {
if (_encoded[index] != typedOther._encoded[index])
......@@ -483,10 +488,11 @@ class ParagraphStyle {
'textAlign: ${ _encoded[0] & 0x02 == 0x02 ? TextAlign.values[_encoded[1]] : "unspecified"}, '
'fontWeight: ${ _encoded[0] & 0x04 == 0x04 ? FontWeight.values[_encoded[2]] : "unspecified"}, '
'fontStyle: ${ _encoded[0] & 0x08 == 0x08 ? FontStyle.values[_encoded[3]] : "unspecified"}, '
'textOverflow: ${ _encoded[0] & 0x10 == 0x10 ? TextOverflow.values[_encoded[4]] : "unspecified"}, '
'lineCount: ${ _encoded[0] & 0x10 == 0x10 ? _encoded[4] : "unspecified"}, '
'fontFamily: ${ _encoded[0] & 0x20 == 0x20 ? _fontFamily : "unspecified"}, '
'fontSize: ${ _encoded[0] & 0x40 == 0x40 ? _fontSize : "unspecified"}, '
'lineHeight: ${ _encoded[0] & 0x80 == 0x80 ? "${_lineHeight}x" : "unspecified"}'
'lineHeight: ${ _encoded[0] & 0x80 == 0x80 ? "${_lineHeight}x" : "unspecified"},'
'ellipsis: ${ _encoded[0] & 0x100 == 0x100 ? "\"$_ellipsis\"" : "unspecified"},'
')';
}
}
......@@ -736,6 +742,6 @@ class ParagraphBuilder extends NativeFieldWrapperClass2 {
///
/// After calling this function, the paragraph builder object is invalid and
/// cannot be used further.
Paragraph build(ParagraphStyle style) => _build(style._encoded, style._fontFamily, style._fontSize, style._lineHeight);
Paragraph _build(Int32List encoded, String fontFamily, double fontSize, double lineHeight) native "ParagraphBuilder_build";
Paragraph build(ParagraphStyle style) => _build(style._encoded, style._fontFamily, style._fontSize, style._lineHeight, style._ellipsis);
Paragraph _build(Int32List encoded, String fontFamily, double fontSize, double lineHeight, String ellipsis) native "ParagraphBuilder_build";
}
......@@ -95,18 +95,19 @@ const int tsHeightMask = 1 << tsHeightIndex;
const int psTextAlignIndex = 1;
const int psFontWeightIndex = 2;
const int psFontStyleIndex = 3;
const int psTextOverflowIndex = 4;
// index 4 reserved for LineCount
const int psFontFamilyIndex = 5;
const int psFontSizeIndex = 6;
const int psLineHeightIndex = 7;
const int psEllipsisIndex = 8;
const int psTextAlignMask = 1 << psTextAlignIndex;
const int psFontWeightMask = 1 << psFontWeightIndex;
const int psFontStyleMask = 1 << psFontStyleIndex;
const int psTextOverflowMask = 1 << psTextOverflowIndex;
const int psFontFamilyMask = 1 << psFontFamilyIndex;
const int psFontSizeMask = 1 << psFontSizeIndex;
const int psLineHeightMask = 1 << psLineHeightIndex;
const int psEllipsisMask = 1 << psEllipsisIndex;
} // namespace
......@@ -242,7 +243,8 @@ void ParagraphBuilder::addText(const std::string& text) {
ftl::RefPtr<Paragraph> ParagraphBuilder::build(tonic::Int32List& encoded,
const std::string& fontFamily,
double fontSize,
double lineHeight) {
double lineHeight,
const std::string& ellipsis) {
FTL_DCHECK(encoded.num_elements() == 5);
int32_t mask = encoded[0];
......@@ -284,10 +286,8 @@ ftl::RefPtr<Paragraph> ParagraphBuilder::build(tonic::Int32List& encoded,
if (mask & psLineHeightMask)
style->setLineHeight(Length(lineHeight * 100.0, Percent));
if (mask & psTextOverflowMask) {
style->setTextOverflow(
static_cast<TextOverflow>(encoded[psTextOverflowIndex]));
}
if (mask & psEllipsisMask)
style->setEllipsis(AtomicString::fromUTF8(ellipsis.c_str()));
m_renderParagraph->setStyle(style.release());
}
......
......@@ -40,7 +40,8 @@ class ParagraphBuilder : public ftl::RefCountedThreadSafe<ParagraphBuilder>,
ftl::RefPtr<Paragraph> build(tonic::Int32List& encoded,
const std::string& fontFamily,
double fontSize,
double lineHeight);
double lineHeight,
const std::string& ellipsis);
static void RegisterNatives(tonic::DartLibraryNatives* natives);
......
......@@ -452,9 +452,10 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
StringBuilder charactersWithEllipsis;
if (hasAddedEllipsis()) {
charactersWithEllipsis.reserveCapacity(string.length() + 1);
const AtomicString& ellipsis = renderer().containingBlock()->style()->ellipsis();
charactersWithEllipsis.reserveCapacity(string.length() + ellipsis.length());
charactersWithEllipsis.append(string);
charactersWithEllipsis.append(WTF::Unicode::horizontalEllipsis);
charactersWithEllipsis.append(ellipsis);
string = charactersWithEllipsis.toString().createView();
maximumLength = string.length();
}
......
......@@ -409,11 +409,10 @@ inline float measureHyphenWidth(RenderText* renderer, const Font& font, TextDire
style->hyphenString().string(), style, style->direction()));
}
inline float measureEllipsisWidth(RenderText* renderer, const Font& font)
inline float measureEllipsisWidth(RenderText* renderer, const Font& font, const String& ellipsis)
{
RenderStyle* style = renderer->style();
return font.width(constructTextRun(renderer, font,
String(&WTF::Unicode::horizontalEllipsis, 1), style, style->direction()));
return font.width(constructTextRun(renderer, font, ellipsis, style, style->direction()));
}
ALWAYS_INLINE TextDirection textDirectionFromUnicode(WTF::Unicode::Direction direction)
......@@ -468,11 +467,11 @@ inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
float hyphenWidth = 0;
bool ellipsizeMode = m_blockStyle->textOverflow() == TextOverflowEllipsis;
bool ellipsizeMode = !m_blockStyle->ellipsis().isEmpty();
float ellipsisWidth = 0;
unsigned ellipsisBreakOffset = 0;
if (ellipsizeMode) {
ellipsisWidth = measureEllipsisWidth(renderText, font);
ellipsisWidth = measureEllipsisWidth(renderText, font, m_blockStyle->ellipsis().string());
breakAll = true;
}
......
......@@ -643,6 +643,9 @@ public:
TouchAction touchAction() const { return static_cast<TouchAction>(rareNonInheritedData->m_touchAction); }
TouchActionDelay touchActionDelay() const { return static_cast<TouchActionDelay>(rareInheritedData->m_touchActionDelay); }
// Flutter property getters
const AtomicString& ellipsis() const { return rareNonInheritedData->m_ellipsis; }
// attribute setter methods
void setDisplay(EDisplay v) { noninherited_flags.effectiveDisplay = v; }
......@@ -900,6 +903,9 @@ public:
}
ClipPathOperation* clipPath() const { return rareNonInheritedData->m_clipPath.get(); }
// Flutter property setters
void setEllipsis(const AtomicString& e) { SET_VAR(rareNonInheritedData, m_ellipsis, e); }
static ClipPathOperation* initialClipPath() { return 0; }
const CounterDirectiveMap* counterDirectives() const;
......
......@@ -87,6 +87,8 @@ public:
LengthPoint m_objectPosition;
AtomicString m_ellipsis;
unsigned m_transformStyle3D : 1; // ETransformStyle3D
unsigned m_alignContent : 3; // EAlignContent
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册