Skip to content

Commit

Permalink
[canvaskit] fix addPlaceholder JS bindings; add paragraph test (flutt…
Browse files Browse the repository at this point in the history
  • Loading branch information
yjbanov authored Jan 20, 2021
1 parent 0c79393 commit 688578e
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 23 deletions.
18 changes: 7 additions & 11 deletions lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1470,7 +1470,13 @@ class SkParagraphBuilder {
external void pushPaintStyle(
SkTextStyle textStyle, SkPaint foreground, SkPaint background);
external void pop();
external void addPlaceholder(SkPlaceholderStyleProperties placeholderStyle);
external void addPlaceholder(
double width,
double height,
SkPlaceholderAlignment alignment,
SkTextBaseline baseline,
double offset,
);
external SkParagraph build();
external void delete();
}
Expand Down Expand Up @@ -1606,16 +1612,6 @@ class SkStrutStyleProperties {
external set forceStrutHeight(bool? value);
}

@JS()
@anonymous
class SkPlaceholderStyleProperties {
external set width(double? value);
external set height(double? value);
external set alignment(SkPlaceholderAlignment? value);
external set offset(double? value);
external set baseline(SkTextBaseline? value);
}

@JS()
@anonymous
class SkFontStyle {
Expand Down
47 changes: 35 additions & 12 deletions lib/web_ui/lib/src/engine/canvaskit/text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ class CkParagraphBuilder implements ui.ParagraphBuilder {

_placeholderCount++;
_placeholderScales.add(scale);
SkPlaceholderStyleProperties placeholderStyle = toSkPlaceholderStyle(
final _CkParagraphPlaceholder placeholderStyle = toSkPlaceholderStyle(
width * scale,
height * scale,
alignment,
Expand All @@ -639,24 +639,31 @@ class CkParagraphBuilder implements ui.ParagraphBuilder {
_addPlaceholder(placeholderStyle);
}

void _addPlaceholder(SkPlaceholderStyleProperties placeholderStyle) {
void _addPlaceholder(_CkParagraphPlaceholder placeholderStyle) {
_commands.add(_ParagraphCommand.addPlaceholder(placeholderStyle));
_paragraphBuilder.addPlaceholder(placeholderStyle);
_paragraphBuilder.addPlaceholder(
placeholderStyle.width,
placeholderStyle.height,
placeholderStyle.alignment,
placeholderStyle.baseline,
placeholderStyle.offset,
);
}

static SkPlaceholderStyleProperties toSkPlaceholderStyle(
static _CkParagraphPlaceholder toSkPlaceholderStyle(
double width,
double height,
ui.PlaceholderAlignment alignment,
double baselineOffset,
ui.TextBaseline baseline,
) {
final properties = SkPlaceholderStyleProperties();
properties.width = width;
properties.height = height;
properties.alignment = toSkPlaceholderAlignment(alignment);
properties.offset = baselineOffset;
properties.baseline = toSkTextBaseline(baseline);
final properties = _CkParagraphPlaceholder(
width: width,
height: height,
alignment: toSkPlaceholderAlignment(alignment),
offset: baselineOffset,
baseline: toSkTextBaseline(baseline),
);
return properties;
}

Expand Down Expand Up @@ -722,11 +729,27 @@ class CkParagraphBuilder implements ui.ParagraphBuilder {
}
}

class _CkParagraphPlaceholder {
_CkParagraphPlaceholder({
required this.width,
required this.height,
required this.alignment,
required this.baseline,
required this.offset,
});

final double width;
final double height;
final SkPlaceholderAlignment alignment;
final SkTextBaseline baseline;
final double offset;
}

class _ParagraphCommand {
final _ParagraphCommandType type;
final String? text;
final CkTextStyle? style;
final SkPlaceholderStyleProperties? placeholderStyle;
final _CkParagraphPlaceholder? placeholderStyle;

const _ParagraphCommand._(
this.type,
Expand All @@ -745,7 +768,7 @@ class _ParagraphCommand {
: this._(_ParagraphCommandType.pushStyle, null, style, null);

const _ParagraphCommand.addPlaceholder(
SkPlaceholderStyleProperties placeholderStyle)
_CkParagraphPlaceholder placeholderStyle)
: this._(
_ParagraphCommandType.addPlaceholder, null, null, placeholderStyle);
}
Expand Down
109 changes: 109 additions & 0 deletions lib/web_ui/test/canvaskit/canvaskit_api_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:test/test.dart';
import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart' as ui;

import '../matchers.dart';
import 'common.dart';
import 'test_data.dart';

Expand Down Expand Up @@ -47,6 +48,7 @@ void testMain() {
_toSkMatrixFromFloat32Tests();
_toSkRectTests();
_skVerticesTests();
_paragraphTests();
group('SkPath', () {
_pathTests();
});
Expand Down Expand Up @@ -1229,3 +1231,110 @@ void _textStyleTests() {
}
});
}

void _paragraphTests() {
// This test is just a kitchen sink that blasts CanvasKit with all paragraph
// properties all at once, making sure CanvasKit doesn't choke on anything.
// In particular, this tests that our JS bindings are correct, such as that
// arguments are of acceptable types and passed in the correct order.
test('SkParagraph API kitchensink', () {
final SkParagraphStyleProperties props = SkParagraphStyleProperties();
props.textAlign = canvasKit.TextAlign.Center;
props.textDirection = canvasKit.TextDirection.RTL;
props.heightMultiplier = 3;
props.textHeightBehavior = ui.TextHeightBehavior().encode();
props.maxLines = 4;
props.ellipsis = '___';
props.textStyle = SkTextStyleProperties()
..backgroundColor = Float32List.fromList(<double>[1, 2, 3, 4])
..color = Float32List.fromList(<double>[5, 6, 7, 8])
..foregroundColor = Float32List.fromList(<double>[9, 10, 11, 12])
..decoration = 0x2
..decorationThickness = 2.0
..decorationColor = Float32List.fromList(<double>[13, 14, 15, 16])
..decorationStyle = canvasKit.DecorationStyle.Dotted
..textBaseline = canvasKit.TextBaseline.Ideographic
..fontSize = 24
..letterSpacing = 5
..wordSpacing = 10
..heightMultiplier = 2.5
..locale = 'en_CA'
..fontFamilies = <String>['Roboto', 'serif']
..fontStyle = (SkFontStyle()
..slant = canvasKit.FontSlant.Upright
..weight = canvasKit.FontWeight.Normal)
..shadows = <SkTextShadow>[]
..fontFeatures = <SkFontFeature>[
SkFontFeature()
..name = 'pnum'
..value = 1,
SkFontFeature()
..name = 'tnum'
..value = 1,
];
props.strutStyle = SkStrutStyleProperties()
..fontFamilies = <String>['Roboto', 'Noto']
..fontStyle = (SkFontStyle()
..slant = canvasKit.FontSlant.Italic
..weight = canvasKit.FontWeight.Bold)
..fontSize = 23
..heightMultiplier = 5
..leading = 6
..strutEnabled = true
..forceStrutHeight = false;

final SkParagraphStyle paragraphStyle = canvasKit.ParagraphStyle(props);
final SkParagraphBuilder builder = canvasKit.ParagraphBuilder.Make(
paragraphStyle,
skiaFontCollection.skFontMgr,
);

builder.addText('Hello');
builder.addPlaceholder(
50,
25,
canvasKit.PlaceholderAlignment.Middle,
canvasKit.TextBaseline.Ideographic,
4.0,
);
builder.pushStyle(canvasKit.TextStyle(SkTextStyleProperties()
..fontSize = 12));
builder.addText('World');
builder.pop();
builder.pushPaintStyle(canvasKit.TextStyle(SkTextStyleProperties()
..fontSize = 12), SkPaint(), SkPaint());
builder.addText('!');
builder.pop();
final SkParagraph paragraph = builder.build();
paragraph.layout(55);
expect(paragraph.getAlphabeticBaseline(), within<double>(distance: 0.5, from: 22));
expect(paragraph.didExceedMaxLines(), false);
expect(paragraph.getHeight(), 28);
expect(paragraph.getIdeographicBaseline(), within<double>(distance: 0.5, from: 28));
expect(paragraph.getLongestLine(), 50);
expect(paragraph.getMaxIntrinsicWidth(), 50);
expect(paragraph.getMinIntrinsicWidth(), 0);
expect(paragraph.getMaxWidth(), 55);
expect(paragraph.getRectsForRange(1, 3, canvasKit.RectHeightStyle.Tight, canvasKit.RectWidthStyle.Max), <double>[]);
expect(paragraph.getRectsForPlaceholders(), hasLength(1));
expect(paragraph.getGlyphPositionAtCoordinate(5, 5).affinity, canvasKit.Affinity.Downstream);

// "Hello"
for (int i = 0; i < 5; i++) {
expect(paragraph.getWordBoundary(i).start, 0);
expect(paragraph.getWordBoundary(i).end, 5);
}
// Placeholder
expect(paragraph.getWordBoundary(5).start, 5);
expect(paragraph.getWordBoundary(5).end, 6);
// "World"
for (int i = 6; i < 11; i++) {
expect(paragraph.getWordBoundary(i).start, 6);
expect(paragraph.getWordBoundary(i).end, 11);
}
// "!"
expect(paragraph.getWordBoundary(11).start, 11);
expect(paragraph.getWordBoundary(11).end, 12);
paragraph.delete();
});
}

0 comments on commit 688578e

Please sign in to comment.