From a0c47e2216a2b50b70c478001cf5652f31a783af Mon Sep 17 00:00:00 2001 From: Gary Qian Date: Wed, 3 Jul 2019 15:04:18 -0700 Subject: [PATCH] Do not use ideographic baseline for RenderPargraph baseline (#35493) --- .../flutter/lib/src/rendering/paragraph.dart | 7 +- .../flutter_localizations/test/text_test.dart | 183 ++++++++++++++++++ 2 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 packages/flutter_localizations/test/text_test.dart diff --git a/packages/flutter/lib/src/rendering/paragraph.dart b/packages/flutter/lib/src/rendering/paragraph.dart index ffd4333e60..ae0e68b9d4 100644 --- a/packages/flutter/lib/src/rendering/paragraph.dart +++ b/packages/flutter/lib/src/rendering/paragraph.dart @@ -318,7 +318,12 @@ class RenderParagraph extends RenderBox assert(constraints != null); assert(constraints.debugAssertIsValid()); _layoutTextWithConstraints(constraints); - return _textPainter.computeDistanceToActualBaseline(baseline); + // TODO(garyq): Since our metric for ideographic baseline is currently inacurrate + // and the non-alphabetic baselines are based off of the alphabetic baseline, we + // use the alphabetic for now to produce correct layouts. We should eventually change + // this back to pass the `baseline` property when the ideographic baseline is properly + // implemented (https://github.com/flutter/flutter/issues/22625). + return _textPainter.computeDistanceToActualBaseline(TextBaseline.alphabetic); } // Intrinsics cannot be calculated without a full layout for diff --git a/packages/flutter_localizations/test/text_test.dart b/packages/flutter_localizations/test/text_test.dart new file mode 100644 index 0000000000..28b395f1c5 --- /dev/null +++ b/packages/flutter_localizations/test/text_test.dart @@ -0,0 +1,183 @@ +// 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 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + testWidgets('Text baseline with CJK locale', (WidgetTester tester) async { + // This test in combination with 'Text baseline with EN locale' verify the baselines + // used to align text with ideographic baselines are reasonable. We are currently + // using the alphabetic baseline to lay out as the ideographic baseline is not yet + // properly implemented. When the ideographic baseline is better defined and implemented, + // the values of this test should change very slightly. See the issue this is based off + // of: https://github.com/flutter/flutter/issues/25782. + final Key targetKey = UniqueKey(); + await tester.pumpWidget( + MaterialApp( + routes: { + '/next': (BuildContext context) { + return const Text('Next'); + }, + }, + localizationsDelegates: const >[ + GlobalMaterialLocalizations.delegate, + ], + supportedLocales: const [ + Locale('en', 'US'), + Locale('es', 'ES'), + Locale('zh', 'CN'), + ], + locale: const Locale('zh', 'CN'), + home: Material( + child: Center( + child: Builder( + key: targetKey, + builder: (BuildContext context) { + return PopupMenuButton( + onSelected: (int value) { + Navigator.pushNamed(context, '/next'); + }, + itemBuilder: (BuildContext context) { + return >[ + PopupMenuItem( + value: 1, + child: Text( + 'hello, world', + style: TextStyle(color: Colors.blue), + ), + ), + PopupMenuItem( + value: 2, + child: Text( + '你好,世界', + style: TextStyle(color: Colors.blue), + ), + ), + ]; + }, + ); + }, + ), + ), + ), + ), + ); + + await tester.tap(find.byKey(targetKey)); + await tester.pumpAndSettle(); + + expect(find.text('hello, world'), findsOneWidget); + expect(find.text('你好,世界'), findsOneWidget); + + Offset topLeft = tester.getTopLeft(find.text('hello, world')); + Offset topRight = tester.getTopRight(find.text('hello, world')); + Offset bottomLeft = tester.getBottomLeft(find.text('hello, world')); + Offset bottomRight = tester.getBottomRight(find.text('hello, world')); + + expect(topLeft, const Offset(392.0, 298.3999996185303)); + expect(topRight, const Offset(596.0, 298.3999996185303)); + expect(bottomLeft, const Offset(392.0, 315.3999996185303)); + expect(bottomRight, const Offset(596.0, 315.3999996185303)); + + topLeft = tester.getTopLeft(find.text('你好,世界')); + topRight = tester.getTopRight(find.text('你好,世界')); + bottomLeft = tester.getBottomLeft(find.text('你好,世界')); + bottomRight = tester.getBottomRight(find.text('你好,世界')); + + expect(topLeft, const Offset(392.0, 346.3999996185303)); + expect(topRight, const Offset(477.0, 346.3999996185303)); + expect(bottomLeft, const Offset(392.0, 363.3999996185303)); + expect(bottomRight, const Offset(477.0, 363.3999996185303)); + }, skip: !isLinux); + + testWidgets('Text baseline with EN locale', (WidgetTester tester) async { + // This test in combination with 'Text baseline with CJK locale' verify the baselines + // used to align text with ideographic baselines are reasonable. We are currently + // using the alphabetic baseline to lay out as the ideographic baseline is not yet + // properly implemented. When the ideographic baseline is better defined and implemented, + // the values of this test should change very slightly. See the issue this is based off + // of: https://github.com/flutter/flutter/issues/25782. + final Key targetKey = UniqueKey(); + await tester.pumpWidget( + MaterialApp( + routes: { + '/next': (BuildContext context) { + return const Text('Next'); + }, + }, + localizationsDelegates: const >[ + GlobalMaterialLocalizations.delegate, + ], + supportedLocales: const [ + Locale('en', 'US'), + Locale('es', 'ES'), + Locale('zh', 'CN'), + ], + locale: const Locale('en', 'US'), + home: Material( + child: Center( + child: Builder( + key: targetKey, + builder: (BuildContext context) { + return PopupMenuButton( + onSelected: (int value) { + Navigator.pushNamed(context, '/next'); + }, + itemBuilder: (BuildContext context) { + return >[ + PopupMenuItem( + value: 1, + child: Text( + 'hello, world', + style: TextStyle(color: Colors.blue), + ), + ), + PopupMenuItem( + value: 2, + child: Text( + '你好,世界', + style: TextStyle(color: Colors.blue), + ), + ), + ]; + }, + ); + }, + ), + ), + ), + ), + ); + + await tester.tap(find.byKey(targetKey)); + await tester.pumpAndSettle(); + + expect(find.text('hello, world'), findsOneWidget); + expect(find.text('你好,世界'), findsOneWidget); + + Offset topLeft = tester.getTopLeft(find.text('hello, world')); + Offset topRight = tester.getTopRight(find.text('hello, world')); + Offset bottomLeft = tester.getBottomLeft(find.text('hello, world')); + Offset bottomRight = tester.getBottomRight(find.text('hello, world')); + + + expect(topLeft, const Offset(392.0, 299.19999980926514)); + expect(topRight, const Offset(584.0, 299.19999980926514)); + expect(bottomLeft, const Offset(392.0, 315.19999980926514)); + expect(bottomRight, const Offset(584.0, 315.19999980926514)); + + topLeft = tester.getTopLeft(find.text('你好,世界')); + topRight = tester.getTopRight(find.text('你好,世界')); + bottomLeft = tester.getBottomLeft(find.text('你好,世界')); + bottomRight = tester.getBottomRight(find.text('你好,世界')); + + expect(topLeft, const Offset(392.0, 347.19999980926514)); + expect(topRight, const Offset(472.0, 347.19999980926514)); + expect(bottomLeft, const Offset(392.0, 363.19999980926514)); + expect(bottomRight, const Offset(472.0, 363.19999980926514)); + }, skip: !isLinux); +}