Skip to content

Commit 4b233f0

Browse files
authored
Support overriding font leading in TextStyle and LibTxt (flutter#6927)
1 parent 25c6c1b commit 4b233f0

File tree

9 files changed

+240
-37
lines changed

9 files changed

+240
-37
lines changed

lib/ui/text.dart

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ Int32List _encodeTextStyle(
256256
double letterSpacing,
257257
double wordSpacing,
258258
double height,
259+
double leading,
259260
Locale locale,
260261
Paint background,
261262
Paint foreground,
@@ -310,22 +311,26 @@ Int32List _encodeTextStyle(
310311
result[0] |= 1 << 12;
311312
// Passed separately to native.
312313
}
313-
if (locale != null) {
314+
if (leading != null) {
314315
result[0] |= 1 << 13;
315316
// Passed separately to native.
316317
}
317-
if (background != null) {
318+
if (locale != null) {
318319
result[0] |= 1 << 14;
319320
// Passed separately to native.
320321
}
321-
if (foreground != null) {
322+
if (background != null) {
322323
result[0] |= 1 << 15;
323324
// Passed separately to native.
324325
}
325-
if (shadows != null) {
326+
if (foreground != null) {
326327
result[0] |= 1 << 16;
327328
// Passed separately to native.
328329
}
330+
if (shadows != null) {
331+
result[0] |= 1 << 17;
332+
// Passed separately to native.
333+
}
329334
return result;
330335
}
331336

@@ -344,7 +349,8 @@ class TextStyle {
344349
/// * `letterSpacing`: The amount of space (in logical pixels) to add between each letter.
345350
/// * `wordSpacing`: The amount of space (in logical pixels) to add at each sequence of white-space (i.e. between each word).
346351
/// * `textBaseline`: The common baseline that should be aligned between this text span and its parent text span, or, for the root text spans, with the line box.
347-
/// * `height`: The height of this text span, as a multiple of the font size.
352+
/// * `height`: The height of this text span, as a multiple of the sum of font size and leading.
353+
/// * `leading`: Custom leading to use instead of the font-provided leading as a multiple of font size. When null, default font leading will be used. Leading is the additional spacing between lines.
348354
/// * `locale`: The locale used to select region-specific glyphs.
349355
/// * `background`: The paint drawn as a background for the text.
350356
/// * `foreground`: The paint used to draw the text. If this is specified, `color` must be null.
@@ -361,6 +367,7 @@ class TextStyle {
361367
double letterSpacing,
362368
double wordSpacing,
363369
double height,
370+
double leading,
364371
Locale locale,
365372
Paint background,
366373
Paint foreground,
@@ -382,6 +389,7 @@ class TextStyle {
382389
letterSpacing,
383390
wordSpacing,
384391
height,
392+
leading,
385393
locale,
386394
background,
387395
foreground,
@@ -392,6 +400,7 @@ class TextStyle {
392400
_letterSpacing = letterSpacing,
393401
_wordSpacing = wordSpacing,
394402
_height = height,
403+
_leading = leading,
395404
_locale = locale,
396405
_background = background,
397406
_foreground = foreground,
@@ -403,6 +412,7 @@ class TextStyle {
403412
final double _letterSpacing;
404413
final double _wordSpacing;
405414
final double _height;
415+
final double _leading;
406416
final Locale _locale;
407417
final Paint _background;
408418
final Paint _foreground;
@@ -420,6 +430,7 @@ class TextStyle {
420430
_letterSpacing != typedOther._letterSpacing ||
421431
_wordSpacing != typedOther._wordSpacing ||
422432
_height != typedOther._height ||
433+
_leading != typedOther._leading ||
423434
_locale != typedOther._locale ||
424435
_background != typedOther._background ||
425436
_foreground != typedOther._foreground)
@@ -434,7 +445,7 @@ class TextStyle {
434445
}
435446

436447
@override
437-
int get hashCode => hashValues(hashList(_encoded), _fontFamily, _fontSize, _letterSpacing, _wordSpacing, _height, _locale, _background, _foreground);
448+
int get hashCode => hashValues(hashList(_encoded), _fontFamily, _fontSize, _letterSpacing, _wordSpacing, _height, _leading, _locale, _background, _foreground);
438449

439450
@override
440451
String toString() {
@@ -451,10 +462,11 @@ class TextStyle {
451462
'letterSpacing: ${ _encoded[0] & 0x00400 == 0x00400 ? "${_letterSpacing}x" : "unspecified"}, '
452463
'wordSpacing: ${ _encoded[0] & 0x00800 == 0x00800 ? "${_wordSpacing}x" : "unspecified"}, '
453464
'height: ${ _encoded[0] & 0x01000 == 0x01000 ? "${_height}x" : "unspecified"}, '
454-
'locale: ${ _encoded[0] & 0x02000 == 0x02000 ? _locale : "unspecified"}, '
455-
'background: ${ _encoded[0] & 0x04000 == 0x04000 ? _background : "unspecified"}, '
456-
'foreground: ${ _encoded[0] & 0x08000 == 0x08000 ? _foreground : "unspecified"}, '
457-
'shadows: ${ _encoded[0] & 0x10000 == 0x10000 ? _shadows : "unspecified"}'
465+
'leading: ${ _encoded[0] & 0x02000 == 0x02000 ? "${_leading}x" : "unspecified"}, '
466+
'locale: ${ _encoded[0] & 0x04000 == 0x04000 ? _locale : "unspecified"}, '
467+
'background: ${ _encoded[0] & 0x08000 == 0x08000 ? _background : "unspecified"}, '
468+
'foreground: ${ _encoded[0] & 0x10000 == 0x10000 ? _foreground : "unspecified"}, '
469+
'shadows: ${ _encoded[0] & 0x20000 == 0x20000 ? _shadows : "unspecified"}'
458470
')';
459471
}
460472
}
@@ -1135,8 +1147,8 @@ class ParagraphBuilder extends NativeFieldWrapperClass2 {
11351147
/// Applies the given style to the added text until [pop] is called.
11361148
///
11371149
/// See [pop] for details.
1138-
void pushStyle(TextStyle style) => _pushStyle(style._encoded, style._fontFamily, style._fontSize, style._letterSpacing, style._wordSpacing, style._height, _encodeLocale(style._locale), style._background?._objects, style._background?._data, style._foreground?._objects, style._foreground?._data, Shadow._encodeShadows(style._shadows));
1139-
void _pushStyle(Int32List encoded, String fontFamily, double fontSize, double letterSpacing, double wordSpacing, double height, String locale, List<dynamic> backgroundObjects, ByteData backgroundData, List<dynamic> foregroundObjects, ByteData foregroundData, ByteData shadowsData) native 'ParagraphBuilder_pushStyle';
1150+
void pushStyle(TextStyle style) => _pushStyle(style._encoded, style._fontFamily, style._fontSize, style._letterSpacing, style._wordSpacing, style._height, style._leading, _encodeLocale(style._locale), style._background?._objects, style._background?._data, style._foreground?._objects, style._foreground?._data, Shadow._encodeShadows(style._shadows));
1151+
void _pushStyle(Int32List encoded, String fontFamily, double fontSize, double letterSpacing, double wordSpacing, double height, double leading, String locale, List<dynamic> backgroundObjects, ByteData backgroundData, List<dynamic> foregroundObjects, ByteData foregroundData, ByteData shadowsData) native 'ParagraphBuilder_pushStyle';
11401152

11411153
static String _encodeLocale(Locale locale) => locale?.toString() ?? '';
11421154

lib/ui/text/paragraph_builder.cc

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,11 @@ const int tsFontSizeIndex = 9;
4141
const int tsLetterSpacingIndex = 10;
4242
const int tsWordSpacingIndex = 11;
4343
const int tsHeightIndex = 12;
44-
const int tsLocaleIndex = 13;
45-
const int tsBackgroundIndex = 14;
46-
const int tsForegroundIndex = 15;
47-
const int tsTextShadowsIndex = 16;
44+
const int tsLeadingIndex = 13;
45+
const int tsLocaleIndex = 14;
46+
const int tsBackgroundIndex = 15;
47+
const int tsForegroundIndex = 16;
48+
const int tsTextShadowsIndex = 17;
4849

4950
const int tsColorMask = 1 << tsColorIndex;
5051
const int tsTextDecorationMask = 1 << tsTextDecorationIndex;
@@ -58,6 +59,7 @@ const int tsFontSizeMask = 1 << tsFontSizeIndex;
5859
const int tsLetterSpacingMask = 1 << tsLetterSpacingIndex;
5960
const int tsWordSpacingMask = 1 << tsWordSpacingIndex;
6061
const int tsHeightMask = 1 << tsHeightIndex;
62+
const int tsLeadingMask = 1 << tsLeadingIndex;
6163
const int tsLocaleMask = 1 << tsLocaleIndex;
6264
const int tsBackgroundMask = 1 << tsBackgroundIndex;
6365
const int tsForegroundMask = 1 << tsForegroundIndex;
@@ -207,6 +209,7 @@ void ParagraphBuilder::pushStyle(tonic::Int32List& encoded,
207209
double letterSpacing,
208210
double wordSpacing,
209211
double height,
212+
double leading,
210213
const std::string& locale,
211214
Dart_Handle background_objects,
212215
Dart_Handle background_data,
@@ -269,6 +272,11 @@ void ParagraphBuilder::pushStyle(tonic::Int32List& encoded,
269272
style.height = height;
270273
}
271274

275+
if (mask & tsLeadingMask) {
276+
style.use_custom_leading = true;
277+
style.leading = leading;
278+
}
279+
272280
if (mask & tsLocaleMask) {
273281
style.locale = locale;
274282
}

lib/ui/text/paragraph_builder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class ParagraphBuilder : public RefCountedDartWrappable<ParagraphBuilder> {
4040
double letterSpacing,
4141
double wordSpacing,
4242
double height,
43+
double leading,
4344
const std::string& locale,
4445
Dart_Handle background_objects,
4546
Dart_Handle background_data,

third_party/txt/src/txt/paragraph.cc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -761,10 +761,13 @@ void Paragraph::Layout(double width, bool force) {
761761
// TODO(garyq): Multipling in the style.height on the first line is
762762
// probably wrong. Figure out how paragraph and line heights are supposed
763763
// to work and fix it.
764-
double line_spacing =
765-
(line_number == 0)
766-
? -metrics.fAscent * style.height
767-
: (-metrics.fAscent + metrics.fLeading) * style.height;
764+
double leading =
765+
style.use_custom_leading
766+
? (metrics.fDescent - metrics.fAscent) * style.leading
767+
: metrics.fLeading;
768+
double line_spacing = (line_number == 0)
769+
? -metrics.fAscent * style.height
770+
: (-metrics.fAscent + leading) * style.height;
768771
if (line_spacing > max_line_spacing) {
769772
max_line_spacing = line_spacing;
770773
if (line_number == 0) {

third_party/txt/src/txt/paragraph.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,10 @@ class Paragraph {
214214
FRIEND_TEST(ParagraphTest, DecorationsParagraph);
215215
FRIEND_TEST(ParagraphTest, ItalicsParagraph);
216216
FRIEND_TEST(ParagraphTest, ChineseParagraph);
217-
FRIEND_TEST(ParagraphTest, DISABLED_ArabicParagraph);
217+
FRIEND_TEST(ParagraphTest, ArabicParagraph);
218+
FRIEND_TEST(ParagraphTest, ArabicLeadingOverrideParagraph);
219+
FRIEND_TEST(ParagraphTest, ArabicLeadingOverrideTallParagraph);
220+
FRIEND_TEST(ParagraphTest, ArabicLeadingOverrideNegativeParagraph);
218221
FRIEND_TEST(ParagraphTest, SpacingParagraph);
219222
FRIEND_TEST(ParagraphTest, LongWordParagraph);
220223
FRIEND_TEST(ParagraphTest, KernScaleParagraph);

third_party/txt/src/txt/styled_runs.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,10 @@ class StyledRuns {
7373
FRIEND_TEST(ParagraphTest, DecorationsParagraph);
7474
FRIEND_TEST(ParagraphTest, ItalicsParagraph);
7575
FRIEND_TEST(ParagraphTest, ChineseParagraph);
76-
FRIEND_TEST(ParagraphTest, DISABLED_ArabicParagraph);
76+
FRIEND_TEST(ParagraphTest, ArabicParagraph);
77+
FRIEND_TEST(ParagraphTest, ArabicLeadingOverrideParagraph);
78+
FRIEND_TEST(ParagraphTest, ArabicLeadingOverrideTallParagraph);
79+
FRIEND_TEST(ParagraphTest, ArabicLeadingOverrideNegativeParagraph);
7780
FRIEND_TEST(ParagraphTest, LongWordParagraph);
7881
FRIEND_TEST(ParagraphTest, KernParagraph);
7982
FRIEND_TEST(ParagraphTest, HyphenBreakParagraph);

third_party/txt/src/txt/text_style.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ bool TextStyle::equals(const TextStyle& other) const {
4747
return false;
4848
if (height != other.height)
4949
return false;
50+
if (use_custom_leading != other.use_custom_leading)
51+
return false;
52+
if (use_custom_leading && leading != other.leading)
53+
return false;
5054
if (locale != other.locale)
5155
return false;
5256
if (foreground != other.foreground)

third_party/txt/src/txt/text_style.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ class TextStyle {
4848
double letter_spacing = 0.0;
4949
double word_spacing = 0.0;
5050
double height = 1.0;
51+
double leading = 0;
52+
bool use_custom_leading = false;
5153
std::string locale;
5254
bool has_background = false;
5355
SkPaint background;

0 commit comments

Comments
 (0)