Commit 33794d13 authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

TextStyle.apply (#5879)

Also, fix an old TODO, and add a test of various things on TextStyle.

...requires an engine roll to pick up https://github.com/flutter/engine/pull/3025 and https://github.com/flutter/engine/pull/3027.
parent bb4a2e8b
......@@ -100,6 +100,65 @@ class TextStyle {
);
}
/// Creates a copy of this text style but with the numeric fields multiplied
/// by the given factors and then incremented by the given deltas.
///
/// For example, `style.apply(fontSizeFactor: 2.0, fontSizeDelta: 1.0)` would return
/// a [TextStyle] whose [fontSize] is `style.fontSize * 2.0 + 1.0`.
///
/// For the [fontWeight], the delta is applied to the [FontWeight] enum index
/// values, so that for instance `style.apply(fontWeightDelta: -2)` when
/// applied to a `style` whose [fontWeight] is [FontWeight.w500] will return a
/// [TextStyle] with a [FontWeight.w300].
///
/// The arguments must not be null.
///
/// If the underlying values are null, then the corresponding factors and/or
/// deltas must not be specified.
///
/// The non-numeric fields are copied verbatim.
TextStyle apply({
double fontSizeFactor: 1.0,
double fontSizeDelta: 0.0,
int fontWeightDelta: 0,
double letterSpacingFactor: 1.0,
double letterSpacingDelta: 0.0,
double wordSpacingFactor: 1.0,
double wordSpacingDelta: 0.0,
double heightFactor: 1.0,
double heightDelta: 0.0,
}) {
assert(fontSizeFactor != null);
assert(fontSizeDelta != null);
assert(fontSize != null || (fontSizeFactor == 1.0 && fontSizeDelta == 0.0));
assert(fontWeightDelta != null);
assert(fontWeight != null || fontWeightDelta == 0.0);
assert(letterSpacingFactor != null);
assert(letterSpacingDelta != null);
assert(letterSpacing != null || (letterSpacingFactor == 1.0 && letterSpacingDelta == 0.0));
assert(wordSpacingFactor != null);
assert(wordSpacingDelta != null);
assert(wordSpacing != null || (wordSpacingFactor == 1.0 && wordSpacingDelta == 0.0));
assert(heightFactor != null);
assert(heightDelta != null);
assert(heightFactor != null || (heightFactor == 1.0 && heightDelta == 0.0));
return new TextStyle(
inherit: inherit,
color: color,
fontFamily: fontFamily,
fontSize: fontSize == null ? null : fontSize * fontSizeFactor + fontSizeDelta,
fontWeight: fontWeight == null ? null : FontWeight.values[(fontWeight.index + fontWeightDelta).clamp(0, FontWeight.values.length - 1)],
fontStyle: fontStyle,
letterSpacing: letterSpacing == null ? null : letterSpacing * letterSpacingFactor + letterSpacingDelta,
wordSpacing: wordSpacing == null ? null : wordSpacing * wordSpacingFactor + wordSpacingDelta,
textBaseline: textBaseline,
height: height == null ? null : height * heightFactor + heightDelta,
decoration: decoration,
decorationColor: decorationColor,
decorationStyle: decorationStyle,
);
}
/// Returns a new text style that matches this text style but with some values
/// replaced by the non-null parameters of the given text style. If the given
/// text style is null, simply returns this text style.
......@@ -133,8 +192,7 @@ class TextStyle {
color: Color.lerp(begin.color, end.color, t),
fontFamily: t < 0.5 ? begin.fontFamily : end.fontFamily,
fontSize: ui.lerpDouble(begin.fontSize ?? end.fontSize, end.fontSize ?? begin.fontSize, t),
// TODO(ianh): Replace next line with "fontWeight: FontWeight.lerp(begin.fontWeight, end.fontWeight, t)," once engine is revved
fontWeight: FontWeight.values[ui.lerpDouble(begin?.fontWeight?.index ?? FontWeight.normal.index, end?.fontWeight?.index ?? FontWeight.normal.index, t.clamp(0.0, 1.0)).round()],
fontWeight: FontWeight.lerp(begin.fontWeight, end.fontWeight, t),
fontStyle: t < 0.5 ? begin.fontStyle : end.fontStyle,
letterSpacing: ui.lerpDouble(begin.letterSpacing ?? end.letterSpacing, end.letterSpacing ?? begin.letterSpacing, t),
wordSpacing: ui.lerpDouble(begin.wordSpacing ?? end.wordSpacing, end.wordSpacing ?? begin.wordSpacing, t),
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' as ui show TextStyle, ParagraphStyle;
import 'package:flutter/painting.dart';
import 'package:test/test.dart';
void main() {
test("TextStyle control test", () {
TextStyle s1 = const TextStyle(
fontSize: 10.0,
fontWeight: FontWeight.w800,
height: 123.0,
);
expect(() { s1.fontFamily = 'test'; }, throws); // ignore: ASSIGNMENT_TO_FINAL
expect(s1.fontFamily, isNull);
expect(s1.fontSize, 10.0);
expect(s1.fontWeight, FontWeight.w800);
expect(s1.height, 123.0);
expect(s1, equals(s1));
TextStyle s2 = s1.copyWith(color: const Color(0xFF00FF00), height: 100.0);
expect(s1.fontFamily, isNull);
expect(s1.fontSize, 10.0);
expect(s1.fontWeight, FontWeight.w800);
expect(s1.height, 123.0);
expect(s1.color, isNull);
expect(s2.fontFamily, isNull);
expect(s2.fontSize, 10.0);
expect(s2.fontWeight, FontWeight.w800);
expect(s2.height, 100.0);
expect(s2.color, const Color(0xFF00FF00));
expect(s2, isNot(equals(s1)));
TextStyle s3 = s1.apply(fontSizeFactor: 2.0, fontSizeDelta: -2.0, fontWeightDelta: -4);
expect(s1.fontFamily, isNull);
expect(s1.fontSize, 10.0);
expect(s1.fontWeight, FontWeight.w800);
expect(s1.height, 123.0);
expect(s1.color, isNull);
expect(s3.fontFamily, isNull);
expect(s3.fontSize, 18.0);
expect(s3.fontWeight, FontWeight.w400);
expect(s3.height, 123.0);
expect(s3.color, isNull);
expect(s3, isNot(equals(s1)));
expect(s1.apply(fontWeightDelta: -10).fontWeight, FontWeight.w100);
expect(s1.apply(fontWeightDelta: 2).fontWeight, FontWeight.w900);
expect(s1.merge(null), equals(s1));
TextStyle s4 = s2.merge(s1);
expect(s1.fontFamily, isNull);
expect(s1.fontSize, 10.0);
expect(s1.fontWeight, FontWeight.w800);
expect(s1.height, 123.0);
expect(s1.color, isNull);
expect(s2.fontFamily, isNull);
expect(s2.fontSize, 10.0);
expect(s2.fontWeight, FontWeight.w800);
expect(s2.height, 100.0);
expect(s2.color, const Color(0xFF00FF00));
expect(s2, isNot(equals(s1)));
expect(s2, isNot(equals(s4)));
expect(s4.fontFamily, isNull);
expect(s4.fontSize, 10.0);
expect(s4.fontWeight, FontWeight.w800);
expect(s4.height, 123.0);
expect(s4.color, const Color(0xFF00FF00));
TextStyle s5 = TextStyle.lerp(s1, s3, 0.25);
expect(s1.fontFamily, isNull);
expect(s1.fontSize, 10.0);
expect(s1.fontWeight, FontWeight.w800);
expect(s1.height, 123.0);
expect(s1.color, isNull);
expect(s3.fontFamily, isNull);
expect(s3.fontSize, 18.0);
expect(s3.fontWeight, FontWeight.w400);
expect(s3.height, 123.0);
expect(s3.color, isNull);
expect(s3, isNot(equals(s1)));
expect(s3, isNot(equals(s5)));
expect(s5.fontFamily, isNull);
expect(s5.fontSize, 12.0);
expect(s5.fontWeight, FontWeight.w700);
expect(s5.height, 123.0);
expect(s5.color, isNull);
ui.TextStyle ts5 = s5.textStyle;
expect(ts5, equals(new ui.TextStyle(fontWeight: FontWeight.w700, fontSize: 12.0, height: 123.0)));
expect(ts5.toString(), 'TextStyle(2336|color: unspecified, decoration: unspecified, decorationColor: unspecified, decorationStyle: unspecified, fontWeight: FontWeight.w700, fontStyle: unspecified, fontFamily: unspecified, fontSize: 12.0, letterSpacing: unspecified, wordSpacing: unspecified, height: 123.0x)');
ui.TextStyle ts2 = s2.textStyle;
expect(ts2, equals(new ui.TextStyle(color: const Color(0xFF00FF00), fontWeight: FontWeight.w800, fontSize: 10.0, height: 100.0)));
expect(ts2.toString(), 'TextStyle(2338|color: Color(0xff00ff00), decoration: unspecified, decorationColor: unspecified, decorationStyle: unspecified, fontWeight: FontWeight.w800, fontStyle: unspecified, fontFamily: unspecified, fontSize: 10.0, letterSpacing: unspecified, wordSpacing: unspecified, height: 100.0x)');
ui.ParagraphStyle ps2 = s2.getParagraphStyle(textAlign: TextAlign.center);
expect(ps2, equals(new ui.ParagraphStyle(textAlign: TextAlign.center, fontWeight: FontWeight.w800, fontSize: 10.0, lineHeight: 100.0)));
expect(ps2.toString(), 'ParagraphStyle(textAlign: TextAlign.center, textBaseline: unspecified, fontWeight: FontWeight.w800, fontStyle: unspecified, fontFamily: unspecified, fontSize: 10.0, lineHeight: 100.0x)');
ui.ParagraphStyle ps5 = s5.getParagraphStyle();
expect(ps5, equals(new ui.ParagraphStyle(fontWeight: FontWeight.w700, fontSize: 12.0, lineHeight: 123.0)));
expect(ps5.toString(), 'ParagraphStyle(textAlign: unspecified, textBaseline: unspecified, fontWeight: FontWeight.w700, fontStyle: unspecified, fontFamily: unspecified, fontSize: 12.0, lineHeight: 123.0x)');
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment