Commit 18f0d3ae authored by gspencergoog's avatar gspencergoog Committed by GitHub

Add framework support for system text scale factor. (#12180)

* Add framework-side support for system text scale factor.

* Rolling engine to e3404b81a53ba3180c7623a6f2190ebb28518f30
  Additional changes rolled in with engine change:
    libtxt: implementation of GetRectsForRange that processes a line at a time - e3404b8
    Provide an entropy source to the Dart engine (#4161) - e1aa867
    libtxt: search for fallback fonts that can match emoji and CJK characters - 8061df1
    Roll skia to e4679fa06a. (#4157) - 267e7a8
    Update buildroot to 53fea9aebbcc39c6522731471a1a45960ee0685e (#4160) - 02ea7ae
    Revert engine Dart roll. (#4158) - 14aab33
    Add support for system text scale factor. (#4124) - b2a7f4b
    Include _http into sky_engine libraries for analyzer (#4154) - b930f10
    libtxt: Remove postprocess_line and improve tracking of X offsets - 86f95f0
    libtxt: remove redundant line_widths (#4152) - 14bf515
    Roll dart to ade37f931e90b0fdb8fe16d6bf6f089545da55b6 (#4151) - 6f1264f
parent 7d75c29b
bdfedcc26f78ea332cdac0ed67590157c82c954e e3404b81a53ba3180c7623a6f2190ebb28518f30
\ No newline at end of file
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
<activity android:name="io.flutter.app.FlutterActivity" <activity android:name="io.flutter.app.FlutterActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@android:style/Theme.Black.NoTitleBar" android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
<activity android:name="io.flutter.app.FlutterActivity" <activity android:name="io.flutter.app.FlutterActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@android:style/Theme.Black.NoTitleBar" android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
<activity android:name=".MainActivity" <activity android:name=".MainActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@android:style/Theme.Black.NoTitleBar" android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
<activity android:name="com.yourcompany.platforminteraction.MainActivity" <activity android:name="com.yourcompany.platforminteraction.MainActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@android:style/Theme.Black.NoTitleBar" android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
<activity android:name=".MainActivity" <activity android:name=".MainActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@android:style/Theme.Black.NoTitleBar" android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
<activity android:name=".MainActivity" <activity android:name=".MainActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@android:style/Theme.Black.NoTitleBar" android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
<activity android:name=".MainActivity" <activity android:name=".MainActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@android:style/Theme.Black.NoTitleBar" android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
<activity android:name=".MainActivity" <activity android:name=".MainActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@android:style/Theme.Light.NoTitleBar" android:theme="@android:style/Theme.Light.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
<activity android:name=".MainActivity" <activity android:name=".MainActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@style/Theme.AppCompat" android:theme="@style/Theme.AppCompat"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
<activity android:name=".MainActivity" <activity android:name=".MainActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@android:style/Theme.Black.NoTitleBar" android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
<activity android:name=".MainActivity" <activity android:name=".MainActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@android:style/Theme.Black.NoTitleBar" android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<activity android:name=".MainActivity" <activity android:name=".MainActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@android:style/Theme.Black.NoTitleBar" android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
android:name="io.flutter.examples.platform_view.MainActivity" android:name="io.flutter.examples.platform_view.MainActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@android:style/Theme.Black.NoTitleBar" android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
...@@ -32,6 +32,6 @@ ...@@ -32,6 +32,6 @@
android:name="io.flutter.examples.platform_view.CountActivity" android:name="io.flutter.examples.platform_view.CountActivity"
android:parentActivityName="io.flutter.examples.platform_view.MainActivity" android:parentActivityName="io.flutter.examples.platform_view.MainActivity"
android:theme="@style/Theme.AppCompat.NoActionBar" android:theme="@style/Theme.AppCompat.NoActionBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"></activity> android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"></activity>
</application> </application>
</manifest> </manifest>
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
<activity android:name=".MainActivity" <activity android:name=".MainActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@android:style/Theme.Black.NoTitleBar" android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
......
...@@ -245,8 +245,14 @@ class TextStyle extends Diagnosticable { ...@@ -245,8 +245,14 @@ class TextStyle extends Diagnosticable {
/// During painting, the [fontSize] is multiplied by the current /// During painting, the [fontSize] is multiplied by the current
/// `textScaleFactor` to let users make it easier to read text by increasing /// `textScaleFactor` to let users make it easier to read text by increasing
/// its size. /// its size.
///
/// [getParagraphStyle] will default to 14 logical pixels if the font size
/// isn't specified here.
final double fontSize; final double fontSize;
// The default font size if none is specified.
static const double _defaultFontSize = 14.0;
/// The typeface thickness to use when painting the text (e.g., bold). /// The typeface thickness to use when painting the text (e.g., bold).
final FontWeight fontWeight; final FontWeight fontWeight;
...@@ -444,6 +450,9 @@ class TextStyle extends Diagnosticable { ...@@ -444,6 +450,9 @@ class TextStyle extends Diagnosticable {
/// The `textScaleFactor` argument must not be null. If omitted, it defaults /// The `textScaleFactor` argument must not be null. If omitted, it defaults
/// to 1.0. The other arguments may be null. The `maxLines` argument, if /// to 1.0. The other arguments may be null. The `maxLines` argument, if
/// specified and non-null, must be greater than zero. /// specified and non-null, must be greater than zero.
///
/// If the font size on this style isn't set, it will default to 14 logical
/// pixels.
ui.ParagraphStyle getParagraphStyle({ ui.ParagraphStyle getParagraphStyle({
TextAlign textAlign, TextAlign textAlign,
TextDirection textDirection, TextDirection textDirection,
...@@ -459,7 +468,7 @@ class TextStyle extends Diagnosticable { ...@@ -459,7 +468,7 @@ class TextStyle extends Diagnosticable {
fontWeight: fontWeight, fontWeight: fontWeight,
fontStyle: fontStyle, fontStyle: fontStyle,
fontFamily: fontFamily, fontFamily: fontFamily,
fontSize: fontSize == null ? null : fontSize * textScaleFactor, fontSize: (fontSize ?? _defaultFontSize) * textScaleFactor,
lineHeight: height, lineHeight: height,
maxLines: maxLines, maxLines: maxLines,
ellipsis: ellipsis, ellipsis: ellipsis,
......
...@@ -36,6 +36,7 @@ abstract class RendererBinding extends BindingBase with SchedulerBinding, Servic ...@@ -36,6 +36,7 @@ abstract class RendererBinding extends BindingBase with SchedulerBinding, Servic
); );
ui.window ui.window
..onMetricsChanged = handleMetricsChanged ..onMetricsChanged = handleMetricsChanged
..onTextScaleFactorChanged = handleTextScaleFactorChanged
..onSemanticsEnabledChanged = _handleSemanticsEnabledChanged ..onSemanticsEnabledChanged = _handleSemanticsEnabledChanged
..onSemanticsAction = _handleSemanticsAction; ..onSemanticsAction = _handleSemanticsAction;
initRenderView(); initRenderView();
...@@ -143,6 +144,11 @@ abstract class RendererBinding extends BindingBase with SchedulerBinding, Servic ...@@ -143,6 +144,11 @@ abstract class RendererBinding extends BindingBase with SchedulerBinding, Servic
renderView.configuration = createViewConfiguration(); renderView.configuration = createViewConfiguration();
} }
/// Called when the platform text scale factor changes.
///
/// See [Window.onTextScaleFactorChanged].
void handleTextScaleFactorChanged() { }
/// Returns a [ViewConfiguration] configured for the [RenderView] based on the /// Returns a [ViewConfiguration] configured for the [RenderView] based on the
/// current environment. /// current environment.
/// ///
......
...@@ -398,6 +398,15 @@ class _WidgetsAppState extends State<WidgetsApp> implements WidgetsBindingObserv ...@@ -398,6 +398,15 @@ class _WidgetsAppState extends State<WidgetsApp> implements WidgetsBindingObserv
}); });
} }
@override
void didChangeTextScaleFactor() {
setState(() {
// The textScaleFactor property of ui.window has changed. We reference
// ui.window in our build function, so we need to call setState(), but
// we don't need to cache anything locally.
});
}
@override @override
void didChangeLocale(Locale locale) { void didChangeLocale(Locale locale) {
if (locale == _locale) if (locale == _locale)
......
...@@ -90,7 +90,7 @@ abstract class WidgetsBindingObserver { ...@@ -90,7 +90,7 @@ abstract class WidgetsBindingObserver {
/// navigator. /// navigator.
/// ///
/// Observers are expected to return true if they were able to /// Observers are expected to return true if they were able to
/// handle the notification. Observers are notified in registration /// handle the notification. Observers are notified in registration
/// order until one returns true. /// order until one returns true.
Future<bool> didPushRoute(String route) => new Future<bool>.value(false); Future<bool> didPushRoute(String route) => new Future<bool>.value(false);
...@@ -133,7 +133,7 @@ abstract class WidgetsBindingObserver { ...@@ -133,7 +133,7 @@ abstract class WidgetsBindingObserver {
/// ///
/// @override /// @override
/// Widget build(BuildContext context) { /// Widget build(BuildContext context) {
/// return new Text('Last size: $_lastSize'); /// return new Text('Current size: $_lastSize');
/// } /// }
/// } /// }
/// ``` /// ```
...@@ -148,6 +148,55 @@ abstract class WidgetsBindingObserver { ...@@ -148,6 +148,55 @@ abstract class WidgetsBindingObserver {
/// boilerplate. /// boilerplate.
void didChangeMetrics() { } void didChangeMetrics() { }
/// Called when the platform's text scale factor changes.
///
/// This typically happens as the result of the user changing system
/// preferences, and it should affect all of the text sizes in the
/// application.
///
/// ## Sample code
///
/// ```dart
/// class TextScaleFactorReactor extends StatefulWidget {
/// const TextScaleFactorReactor({ Key key }) : super(key: key);
///
/// @override
/// _TextScaleFactorReactorState createState() => new _TextScaleFactorReactorState();
/// }
///
/// class _TextScaleFactorReactorState extends State<TextScaleFactorReactor> with WidgetsBindingObserver {
/// @override
/// void initState() {
/// super.initState();
/// WidgetsBinding.instance.addObserver(this);
/// }
///
/// @override
/// void dispose() {
/// WidgetsBinding.instance.removeObserver(this);
/// super.dispose();
/// }
///
/// double _lastTextScaleFactor;
///
/// @override
/// void didChangeTextScaleFactor() {
/// setState(() { _lastTextScaleFactor = ui.window.textScaleFactor; });
/// }
///
/// @override
/// Widget build(BuildContext context) {
/// return new Text('Current scale factor: $_lastTextScaleFactor');
/// }
/// }
/// ```
///
/// See also:
///
/// * [MediaQuery.of], which provides a similar service with less
/// boilerplate.
void didChangeTextScaleFactor() { }
/// Called when the system tells the app that the user's locale has /// Called when the system tells the app that the user's locale has
/// changed. For example, if the user changes the system language /// changed. For example, if the user changes the system language
/// settings. /// settings.
...@@ -284,12 +333,6 @@ abstract class WidgetsBinding extends BindingBase with GestureBinding, RendererB ...@@ -284,12 +333,6 @@ abstract class WidgetsBinding extends BindingBase with GestureBinding, RendererB
/// * [WidgetsBindingObserver], which has an example of using this method. /// * [WidgetsBindingObserver], which has an example of using this method.
bool removeObserver(WidgetsBindingObserver observer) => _observers.remove(observer); bool removeObserver(WidgetsBindingObserver observer) => _observers.remove(observer);
/// Called when the system metrics change.
///
/// Notifies all the observers using
/// [WidgetsBindingObserver.didChangeMetrics].
///
/// See [Window.onMetricsChanged].
@override @override
void handleMetricsChanged() { void handleMetricsChanged() {
super.handleMetricsChanged(); super.handleMetricsChanged();
...@@ -297,6 +340,13 @@ abstract class WidgetsBinding extends BindingBase with GestureBinding, RendererB ...@@ -297,6 +340,13 @@ abstract class WidgetsBinding extends BindingBase with GestureBinding, RendererB
observer.didChangeMetrics(); observer.didChangeMetrics();
} }
@override
void handleTextScaleFactorChanged() {
super.handleTextScaleFactorChanged();
for (WidgetsBindingObserver observer in _observers)
observer.didChangeTextScaleFactor();
}
/// Called when the system locale changes. /// Called when the system locale changes.
/// ///
/// Calls [dispatchLocaleChanged] to notify the binding observers. /// Calls [dispatchLocaleChanged] to notify the binding observers.
......
...@@ -52,7 +52,7 @@ class MediaQueryData { ...@@ -52,7 +52,7 @@ class MediaQueryData {
MediaQueryData.fromWindow(ui.Window window) MediaQueryData.fromWindow(ui.Window window)
: size = window.physicalSize / window.devicePixelRatio, : size = window.physicalSize / window.devicePixelRatio,
devicePixelRatio = window.devicePixelRatio, devicePixelRatio = window.devicePixelRatio,
textScaleFactor = 1.0, // TODO(abarth): Read this value from window. textScaleFactor = window.textScaleFactor,
padding = new EdgeInsets.fromWindowPadding(window.padding, window.devicePixelRatio); padding = new EdgeInsets.fromWindowPadding(window.padding, window.devicePixelRatio);
/// The size of the media in logical pixel (e.g, the size of the screen). /// The size of the media in logical pixel (e.g, the size of the screen).
...@@ -147,7 +147,10 @@ class MediaQueryData { ...@@ -147,7 +147,10 @@ class MediaQueryData {
int get hashCode => hashValues(size, devicePixelRatio, textScaleFactor, padding); int get hashCode => hashValues(size, devicePixelRatio, textScaleFactor, padding);
@override @override
String toString() => '$runtimeType(size: $size, devicePixelRatio: $devicePixelRatio, textScaleFactor: $textScaleFactor, padding: $padding)'; String toString() {
return '$runtimeType(size: $size, devicePixelRatio: $devicePixelRatio, '
'textScaleFactor: $textScaleFactor, padding: $padding)';
}
} }
/// Establishes a subtree in which media queries resolve to the given data. /// Establishes a subtree in which media queries resolve to the given data.
......
...@@ -249,7 +249,8 @@ class Text extends StatelessWidget { ...@@ -249,7 +249,8 @@ class Text extends StatelessWidget {
/// For example, if the text scale factor is 1.5, text will be 50% larger than /// For example, if the text scale factor is 1.5, text will be 50% larger than
/// the specified font size. /// the specified font size.
/// ///
/// Defaults to the [MediaQueryData.textScaleFactor] obtained from the ambient /// The value given to the constructor as textScaleFactor. If null, will
/// use the [MediaQueryData.textScaleFactor] obtained from the ambient
/// [MediaQuery], or 1.0 if there is no [MediaQuery] in scope. /// [MediaQuery], or 1.0 if there is no [MediaQuery] in scope.
final double textScaleFactor; final double textScaleFactor;
......
...@@ -305,4 +305,16 @@ void main() { ...@@ -305,4 +305,16 @@ void main() {
expect(tester.takeException(), isFlutterError); expect(tester.takeException(), isFlutterError);
expect(log, <String>['onGenerateRoute /', 'onUnknownRoute /']); expect(log, <String>['onGenerateRoute /', 'onUnknownRoute /']);
}); });
testWidgets('Can get text scale from media query', (WidgetTester tester) async {
double textScaleFactor;
await tester.pumpWidget(new MaterialApp(
home: new Builder(builder:(BuildContext context) {
textScaleFactor = MediaQuery.of(context).textScaleFactor;
return new Container();
}),
));
expect(textScaleFactor, isNotNull);
expect(textScaleFactor, equals(1.0));
});
} }
...@@ -44,6 +44,46 @@ void main() { ...@@ -44,6 +44,46 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Does FlatButton scale with font scale changes', (WidgetTester tester) async {
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new Material(
child: new MediaQuery(
data: const MediaQueryData(textScaleFactor: 1.0),
child: new Center(
child: new FlatButton(
onPressed: () { },
child: const Text('ABC'),
),
),
),
),
),
);
expect(tester.getSize(find.byType(FlatButton)), equals(const Size(88.0, 36.0)));
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new Material(
child: new MediaQuery(
data: const MediaQueryData(textScaleFactor: 1.3),
child: new Center(
child: new FlatButton(
onPressed: () { },
child: const Text('ABC'),
),
),
),
),
),
);
expect(tester.getSize(find.byType(FlatButton)), equals(const Size(88.0, 36.0)));
});
// This test is very similar to the '...explicit splashColor and highlightColor' test // This test is very similar to the '...explicit splashColor and highlightColor' test
// in icon_button_test.dart. If you change this one, you may want to also change that one. // in icon_button_test.dart. If you change this one, you may want to also change that one.
testWidgets('MaterialButton with explicit splashColor and highlightColor', (WidgetTester tester) async { testWidgets('MaterialButton with explicit splashColor and highlightColor', (WidgetTester tester) async {
......
...@@ -57,6 +57,23 @@ void main() { ...@@ -57,6 +57,23 @@ void main() {
expect(painter.size, const Size(123.0, 123.0)); expect(painter.size, const Size(123.0, 123.0));
}); });
test('TextPainter textScaleFactor test', () {
final TextPainter painter = new TextPainter(
text: const TextSpan(
text: 'X',
style: const TextStyle(
inherit: false,
fontFamily: 'Ahem',
fontSize: 10.0,
),
),
textDirection: TextDirection.ltr,
textScaleFactor: 2.0,
);
painter.layout();
expect(painter.size, const Size(20.0, 20.0));
});
test('TextPainter default text height is 14 pixels', () { test('TextPainter default text height is 14 pixels', () {
final TextPainter painter = new TextPainter( final TextPainter painter = new TextPainter(
text: const TextSpan(text: 'x'), text: const TextSpan(text: 'x'),
......
...@@ -125,12 +125,12 @@ void main() { ...@@ -125,12 +125,12 @@ void main() {
test('TextStyle with text direction', () { test('TextStyle with text direction', () {
final ui.ParagraphStyle ps6 = const TextStyle().getParagraphStyle(textDirection: TextDirection.ltr); final ui.ParagraphStyle ps6 = const TextStyle().getParagraphStyle(textDirection: TextDirection.ltr);
expect(ps6, equals(new ui.ParagraphStyle(textDirection: TextDirection.ltr))); expect(ps6, equals(new ui.ParagraphStyle(textDirection: TextDirection.ltr, fontSize: 14.0)));
expect(ps6.toString(), 'ParagraphStyle(textAlign: unspecified, textDirection: TextDirection.ltr, fontWeight: unspecified, fontStyle: unspecified, maxLines: unspecified, fontFamily: unspecified, fontSize: unspecified, lineHeight: unspecified, ellipsis: unspecified)'); expect(ps6.toString(), 'ParagraphStyle(textAlign: unspecified, textDirection: TextDirection.ltr, fontWeight: unspecified, fontStyle: unspecified, maxLines: unspecified, fontFamily: unspecified, fontSize: 14.0, lineHeight: unspecified, ellipsis: unspecified)');
final ui.ParagraphStyle ps7 = const TextStyle().getParagraphStyle(textDirection: TextDirection.rtl); final ui.ParagraphStyle ps7 = const TextStyle().getParagraphStyle(textDirection: TextDirection.rtl);
expect(ps7, equals(new ui.ParagraphStyle(textDirection: TextDirection.rtl))); expect(ps7, equals(new ui.ParagraphStyle(textDirection: TextDirection.rtl, fontSize: 14.0)));
expect(ps7.toString(), 'ParagraphStyle(textAlign: unspecified, textDirection: TextDirection.rtl, fontWeight: unspecified, fontStyle: unspecified, maxLines: unspecified, fontFamily: unspecified, fontSize: unspecified, lineHeight: unspecified, ellipsis: unspecified)'); expect(ps7.toString(), 'ParagraphStyle(textAlign: unspecified, textDirection: TextDirection.rtl, fontWeight: unspecified, fontStyle: unspecified, maxLines: unspecified, fontFamily: unspecified, fontSize: 14.0, lineHeight: unspecified, ellipsis: unspecified)');
}); });
test('TextStyle using package font', () { test('TextStyle using package font', () {
......
...@@ -222,6 +222,64 @@ void main() { ...@@ -222,6 +222,64 @@ void main() {
expect(paragraph.debugNeedsPaint, isFalse); expect(paragraph.debugNeedsPaint, isFalse);
}); });
test('nested TextSpans in paragraph handle textScaleFactor correctly.', () {
final TextSpan testSpan = const TextSpan(
text: 'a',
style: const TextStyle(
fontSize: 10.0,
),
children: const <TextSpan>[
const TextSpan(
text: 'b',
children: const <TextSpan>[
const TextSpan(text: 'c'),
],
style: const TextStyle(
fontSize: 20.0,
),
),
const TextSpan(
text: 'd',
),
],
);
final RenderParagraph paragraph = new RenderParagraph(
testSpan,
textDirection: TextDirection.ltr,
textScaleFactor: 1.3
);
paragraph.layout(const BoxConstraints());
// anyOf is needed here because Linux and Mac have different text
// rendering widths in tests.
// TODO(#12357): Figure out why this is, and fix it (if needed) once Blink
// text rendering is replaced.
expect(paragraph.size.width, anyOf(79.0, 78.0));
expect(paragraph.size.height, 26.0);
// Test the sizes of nested spans.
final List<ui.TextBox> boxes = <ui.TextBox>[];
final String text = testSpan.toStringDeep();
for (int i = 0; i < text.length; ++i) {
boxes.addAll(paragraph.getBoxesForSelection(
new TextSelection(baseOffset: i, extentOffset: i + 1)
));
}
expect(boxes.length, equals(4));
// anyOf is needed here and below because Linux and Mac have different text
// rendering widths in tests.
// TODO(#12357): Figure out why this is, and fix it (if needed) once Blink
// text rendering is replaced.
expect(boxes[0].toRect().width, anyOf(14.0, 13.0));
expect(boxes[0].toRect().height, 13.0);
expect(boxes[1].toRect().width, anyOf(27.0, 26.0));
expect(boxes[1].toRect().height, 26.0);
expect(boxes[2].toRect().width, anyOf(27.0, 26.0));
expect(boxes[2].toRect().height, 26.0);
expect(boxes[3].toRect().width, anyOf(14.0, 13.0));
expect(boxes[3].toRect().height, 13.0);
});
test('toStringDeep', () { test('toStringDeep', () {
final RenderParagraph paragraph = new RenderParagraph( final RenderParagraph paragraph = new RenderParagraph(
const TextSpan(text: _kText), const TextSpan(text: _kText),
......
...@@ -8,7 +8,7 @@ import 'package:flutter/widgets.dart'; ...@@ -8,7 +8,7 @@ import 'package:flutter/widgets.dart';
void main() { void main() {
testWidgets('Text respects media query', (WidgetTester tester) async { testWidgets('Text respects media query', (WidgetTester tester) async {
await tester.pumpWidget(const MediaQuery( await tester.pumpWidget(const MediaQuery(
data: const MediaQueryData(textScaleFactor: 1.5), data: const MediaQueryData(textScaleFactor: 1.3),
child: const Center( child: const Center(
child: const Text('Hello', textDirection: TextDirection.ltr) child: const Text('Hello', textDirection: TextDirection.ltr)
) )
...@@ -16,7 +16,7 @@ void main() { ...@@ -16,7 +16,7 @@ void main() {
RichText text = tester.firstWidget(find.byType(RichText)); RichText text = tester.firstWidget(find.byType(RichText));
expect(text, isNotNull); expect(text, isNotNull);
expect(text.textScaleFactor, 1.5); expect(text.textScaleFactor, 1.3);
await tester.pumpWidget(const Center( await tester.pumpWidget(const Center(
child: const Text('Hello', textDirection: TextDirection.ltr) child: const Text('Hello', textDirection: TextDirection.ltr)
...@@ -25,14 +25,58 @@ void main() { ...@@ -25,14 +25,58 @@ void main() {
text = tester.firstWidget(find.byType(RichText)); text = tester.firstWidget(find.byType(RichText));
expect(text, isNotNull); expect(text, isNotNull);
expect(text.textScaleFactor, 1.0); expect(text.textScaleFactor, 1.0);
});
testWidgets('Text respects textScaleFactor with default font size', (WidgetTester tester) async {
await tester.pumpWidget(
const Center(child: const Text('Hello', textDirection: TextDirection.ltr))
);
RichText text = tester.firstWidget(find.byType(RichText));
expect(text, isNotNull);
expect(text.textScaleFactor, 1.0);
final Size baseSize = tester.getSize(find.byType(RichText));
expect(baseSize.width, equals(70.0));
expect(baseSize.height, equals(14.0));
await tester.pumpWidget(const Center(
child: const Text('Hello', textScaleFactor: 1.5, textDirection: TextDirection.ltr)
));
text = tester.firstWidget(find.byType(RichText));
expect(text, isNotNull);
expect(text.textScaleFactor, 1.5);
final Size largeSize = tester.getSize(find.byType(RichText));
expect(largeSize.width, 105.0);
expect(largeSize.height, equals(21.0));
});
testWidgets('Text respects textScaleFactor with explicit font size', (WidgetTester tester) async {
await tester.pumpWidget(const Center(
child: const Text('Hello',
style: const TextStyle(fontSize: 20.0), textDirection: TextDirection.ltr)
));
RichText text = tester.firstWidget(find.byType(RichText));
expect(text, isNotNull);
expect(text.textScaleFactor, 1.0);
final Size baseSize = tester.getSize(find.byType(RichText));
expect(baseSize.width, equals(100.0));
expect(baseSize.height, equals(20.0));
await tester.pumpWidget(const Center( await tester.pumpWidget(const Center(
child: const Text('Hello', textScaleFactor: 3.0, textDirection: TextDirection.ltr) child: const Text('Hello',
style: const TextStyle(fontSize: 20.0),
textScaleFactor: 1.3,
textDirection: TextDirection.ltr)
)); ));
text = tester.firstWidget(find.byType(RichText)); text = tester.firstWidget(find.byType(RichText));
expect(text, isNotNull); expect(text, isNotNull);
expect(text.textScaleFactor, 3.0); expect(text.textScaleFactor, 1.3);
final Size largeSize = tester.getSize(find.byType(RichText));
expect(largeSize.width, anyOf(131.0, 130.0));
expect(largeSize.height, equals(26.0));
}); });
testWidgets('Text throws a nice error message if there\'s no Directionality', (WidgetTester tester) async { testWidgets('Text throws a nice error message if there\'s no Directionality', (WidgetTester tester) async {
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
android:name=".MainActivity" android:name=".MainActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@style/LaunchTheme" android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<!-- This keeps the window background of the activity showing <!-- This keeps the window background of the activity showing
......
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