[Web] Draw tab characters as single space (flutter/engine#36107)

This commit is contained in:
Loïc Sharma 2022-09-14 11:17:49 -07:00 committed by GitHub
parent ab1baa4927
commit 960f3f347c
6 changed files with 55 additions and 9 deletions

View File

@ -24,7 +24,6 @@ SET OUT_DIR=%ENGINE_SRC_DIR%\out
SET HOST_DEBUG_UNOPT_DIR=%OUT_DIR%\host_debug_unopt
SET DART_SDK_DIR=%HOST_DEBUG_UNOPT_DIR%\dart-sdk
SET DART_BIN=%DART_SDK_DIR%\bin\dart
SET PUB_BIN=%DART_SDK_DIR%\bin\pub
SET FLUTTER_DIR=%ENGINE_SRC_DIR%\flutter
SET WEB_UI_DIR=%FLUTTER_DIR%\lib\web_ui
SET DEV_DIR=%WEB_UI_DIR%\dev
@ -56,11 +55,11 @@ IF %needsHostDebugUnoptRebuild%==1 (
cd %WEB_UI_DIR%
IF NOT EXIST "%SNAPSHOT_PATH%" (
ECHO Precompiling felt snapshot
CALL %PUB_BIN% get
CALL %DART_SDK_DIR%\bin\dart pub get
%DART_BIN% --snapshot="%SNAPSHOT_PATH%" --packages="%WEB_UI_DIR%\.dart_tool\package_config.json" %FELT_PATH%
)
IF %1==test (
IF "%1"=="test" (
%DART_SDK_DIR%\bin\dart --packages="%WEB_UI_DIR%\.dart_tool\package_config.json" "%SNAPSHOT_PATH%" %* --browser=chrome
) ELSE (
%DART_SDK_DIR%\bin\dart --packages="%WEB_UI_DIR%\.dart_tool\package_config.json" "%SNAPSHOT_PATH%" %*

View File

@ -28,7 +28,6 @@ SET DEV_DIR="%WEB_UI_DIR%dev"
SET OUT_DIR="%ENGINE_SRC_DIR%out"
SET HOST_DEBUG_UNOPT_DIR="%ENGINE_SRC_DIR%out\host_debug_unopt"
SET DART_SDK_DIR=%ENGINE_SRC_DIR%out\host_debug_unopt\dart-sdk
SET PUB_DIR="%DART_SDK_DIR%\bin\pub"
SET SCRIPT_PATH="%DEV_DIR%felt.dart"
SET STAMP_PATH="%DART_TOOL_DIR%felt.snapshot.stamp"
SET GN="%FLUTTER_DIR%tools\gn"
@ -48,18 +47,18 @@ IF %orTempValue%==0 (
CALL python %GN% --unoptimized --full-dart-sdk
CALL ninja -C %HOST_DEBUG_UNOPT_DIR%)
:: TODO(yjbanov): The batch script does not support snanphot option.
:: TODO(yjbanov): The batch script does not support snapshot option.
:: Support snapshot option.
CALL :installdeps
IF %1==test (%DART_SDK_DIR%\bin\dart "%DEV_DIR%\felt.dart" %* --browser=chrome) ELSE ( %DART_SDK_DIR%\bin\dart "%DEV_DIR%\felt.dart" %* )
IF "%1"=="test" (%DART_SDK_DIR%\bin\dart %DEV_DIR%\felt.dart %* --browser=chrome) ELSE ( %DART_SDK_DIR%\bin\dart %DEV_DIR%\felt.dart %* )
EXIT /B %ERRORLEVEL%
:installdeps
ECHO "Running \`pub get\` in 'engine/src/flutter/web_sdk/web_engine_tester'"
cd "%FLUTTER_DIR%web_sdk\web_engine_tester"
CALL %PUB_DIR% get
CALL %DART_SDK_DIR%\bin\dart pub get
ECHO "Running \`pub get\` in 'engine/src/flutter/lib/web_ui'"
cd %WEB_UI_DIR%
CALL %PUB_DIR% get
CALL %DART_SDK_DIR%\bin\dart pub get
EXIT /B 0

View File

@ -1900,6 +1900,7 @@ extension SkParagraphStylePropertiesExtension on SkParagraphStyleProperties {
external set ellipsis(String? value);
external set textStyle(SkTextStyleProperties? value);
external set strutStyle(SkStrutStyleProperties? strutStyle);
external set replaceTabCharacters(bool? bool);
}
@JS()

View File

@ -178,6 +178,7 @@ class CkParagraphStyle implements ui.ParagraphStyle {
toSkStrutStyleProperties(strutStyle, textHeightBehavior);
}
properties.replaceTabCharacters = true;
properties.textStyle = toSkTextStyleProperties(
fontFamily, fontSize, height, fontWeight, fontStyle);

View File

@ -3,6 +3,7 @@
// found in the LICENSE file.
import 'dart:async';
import 'dart:typed_data';
import 'package:test/test.dart';
@ -195,6 +196,23 @@ Future<void> matchPictureGolden(String goldenFile, CkPicture picture,
await matchGoldenFile(goldenFile, region: region);
}
Future<bool> matchImage(ui.Image left, ui.Image right) async {
if (left.width != right.width || left.height != right.height) {
return false;
}
int getPixel(ByteData data, int x, int y) => data.getUint32((x + y * left.width) * 4);
final ByteData leftData = (await left.toByteData())!;
final ByteData rightData = (await right.toByteData())!;
for (int y = 0; y < left.height; y++) {
for (int x = 0; x < left.width; x++) {
if (getPixel(leftData, x, y) != getPixel(rightData, x, y)) {
return false;
}
}
}
return true;
}
/// Sends a platform message to create a Platform View with the given id and viewType.
Future<void> createPlatformView(int id, String viewType) {
final Completer<void> completer = Completer<void>();

View File

@ -4,6 +4,7 @@
import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart' as ui;
import 'common.dart';
@ -65,5 +66,32 @@ void testMain() {
// because the directionality of the 'h' is LTR.
expect(boxes.single.direction, equals(ui.TextDirection.ltr));
});
});
test('Renders tab as space instead of tofu', () async {
// CanvasKit renders a tofu if the font does not have a glyph for a
// character. However, Flutter opts-in to a CanvasKit feature to render
// tabs as a single space.
// See: https://github.com/flutter/flutter/issues/79153
Future<ui.Image> drawText(String text) {
const ui.Rect bounds = ui.Rect.fromLTRB(0, 0, 100, 100);
final CkPictureRecorder recorder = CkPictureRecorder();
final CkCanvas canvas = recorder.beginRecording(bounds);
final CkParagraph paragraph = makeSimpleText(text);
canvas.drawParagraph(paragraph, ui.Offset.zero);
final ui.Picture picture = recorder.endRecording();
return picture.toImage(100, 100);
}
// The backspace character, \b, does not have a corresponding glyph and
// is rendered as a tofu.
final ui.Image tabImage = await drawText('>\t<');
final ui.Image spaceImage = await drawText('> <');
final ui.Image tofuImage = await drawText('>\b<');
expect(await matchImage(tabImage, spaceImage), isTrue);
expect(await matchImage(tabImage, tofuImage), isFalse);
});
// TODO(hterkelsen): https://github.com/flutter/flutter/issues/71520
}, skip: isSafari || isFirefox);
}