[canvaskit] Add TextHeightBehavior

Bug: skia:11881
Change-Id: I220f5ad43de95324172ee5b6d3d5a975a3f8a166
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/399836
Reviewed-by: Julia Lavrova <jlavrova@google.com>
This commit is contained in:
Kevin Lubick 2021-04-22 13:53:35 -04:00
parent dd8f8ed384
commit 4755b0b525
8 changed files with 81 additions and 14 deletions

View File

@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
to `RuntimeEffect.makeShader` as floats (like all other uniforms), and will be converted to
integers internally, to match the expectations of the shader.
- Add 'halfLeading' to `TextStyle` and `StrutStyle`.
- `ParagraphStyle` now accepts textHeightBehavior.
### Removed
- `Picture.saveAsFile()`, in favor of `Picture.serialize()` where clients can control how to

View File

@ -939,6 +939,13 @@ var CanvasKit = {
RTL: {},
},
TextHeightBehavior: {
All: {},
DisableFirstAscent: {},
DisableLastDescent: {},
DisableAll: {},
},
DecorationStyle: {
Solid: {},
Double: {},

View File

@ -532,6 +532,10 @@ function paragraphBuilderTests(CK: CanvasKit, fontMgr?: FontMgr, paint?: Paint)
heightMultiplier: 1.5,
forceStrutHeight: true,
},
disableHinting: true,
heightMultiplier: 2.5,
textDirection: CK.TextDirection.LTR,
textHeightBehavior: CK.TextHeightBehavior.DisableFirstAscent
});
const blueText = new CK.TextStyle({ // $ExpectType TextStyle
backgroundColor: CK.Color(234, 208, 232), // light pink

View File

@ -503,6 +503,7 @@ export interface CanvasKit {
readonly TextAlign: TextAlignEnumValues;
readonly TextBaseline: TextBaselineEnumValues;
readonly TextDirection: TextDirectionEnumValues;
readonly TextHeightBehavior: TextHeightBehaviorEnumValues;
// Paragraph Constants
readonly NoDecoration: number;
@ -877,6 +878,7 @@ export interface ParagraphStyle {
strutStyle?: StrutStyle;
textAlign?: TextAlign;
textDirection?: TextDirection;
textHeightBehavior?: TextHeightBehavior;
textStyle?: TextStyle;
}
@ -1563,10 +1565,10 @@ export interface ContourMeasure extends EmbindObject<ContourMeasure> {
}
export interface FontMetrics {
ascent: number, // suggested space above the baseline. < 0
descent: number, // suggested space below the baseline. > 0
leading: number, // suggested spacing between descent of previous line and ascent of next line.
bounds?: Rect, // smallest rect containing all glyphs (relative to 0,0)
ascent: number; // suggested space above the baseline. < 0
descent: number; // suggested space below the baseline. > 0
leading: number; // suggested spacing between descent of previous line and ascent of next line.
bounds?: Rect; // smallest rect containing all glyphs (relative to 0,0)
}
/**
@ -3694,6 +3696,7 @@ export type RectWidthStyle = EmbindEnumEntity;
export type TextAlign = EmbindEnumEntity;
export type TextBaseline = EmbindEnumEntity;
export type TextDirection = EmbindEnumEntity;
export type TextHeightBehavior = EmbindEnumEntity;
export interface AffinityEnumValues extends EmbindEnum {
Upstream: Affinity;
@ -3936,6 +3939,13 @@ export interface TextDirectionEnumValues extends EmbindEnum {
RTL: TextDirection;
}
export interface TextHeightBehaviorEnumValues extends EmbindEnum {
All: TextHeightBehavior;
DisableFirstAscent: TextHeightBehavior;
DisableLastDescent: TextHeightBehavior;
DisableAll: TextHeightBehavior;
}
export interface TileModeEnumValues extends EmbindEnum {
Clamp: TileMode;
Decal: TileMode;

View File

@ -69,10 +69,11 @@
s['heightMultiplier'] = s['heightMultiplier'] || 0;
s['maxLines'] = s['maxLines'] || 0;
s['strutStyle'] = strutStyle(s['strutStyle']);
s['textAlign'] = s['textAlign'] || CanvasKit.TextAlign.Start;
s['textDirection'] = s['textDirection'] || CanvasKit.TextDirection.LTR;
s['textHeightBehavior'] = s['textHeightBehavior'] || CanvasKit.TextHeightBehavior.All;
s['textStyle'] = CanvasKit.TextStyle(s['textStyle']);
s['strutStyle'] = strutStyle(s['strutStyle']);
return s;
};

View File

@ -214,6 +214,7 @@ struct SimpleParagraphStyle {
size_t maxLines;
para::TextAlign textAlign;
para::TextDirection textDirection;
para::TextHeightBehavior textHeightBehavior;
SimpleTextStyle textStyle;
SimpleStrutStyle strutStyle;
};
@ -241,6 +242,7 @@ para::ParagraphStyle toParagraphStyle(const SimpleParagraphStyle& s) {
if (s.maxLines != 0) {
ps.setMaxLines(s.maxLines);
}
ps.setTextHeightBehavior(s.textHeightBehavior);
return ps;
}
@ -464,15 +466,16 @@ EMSCRIPTEN_BINDINGS(Paragraph) {
.field("width", &SimpleFontStyle::width);
value_object<SimpleParagraphStyle>("ParagraphStyle")
.field("disableHinting", &SimpleParagraphStyle::disableHinting)
.field("_ellipsisPtr", &SimpleParagraphStyle::ellipsisPtr)
.field("_ellipsisLen", &SimpleParagraphStyle::ellipsisLen)
.field("heightMultiplier", &SimpleParagraphStyle::heightMultiplier)
.field("maxLines", &SimpleParagraphStyle::maxLines)
.field("textAlign", &SimpleParagraphStyle::textAlign)
.field("textDirection", &SimpleParagraphStyle::textDirection)
.field("textStyle", &SimpleParagraphStyle::textStyle)
.field("strutStyle", &SimpleParagraphStyle::strutStyle);
.field("disableHinting", &SimpleParagraphStyle::disableHinting)
.field("_ellipsisPtr", &SimpleParagraphStyle::ellipsisPtr)
.field("_ellipsisLen", &SimpleParagraphStyle::ellipsisLen)
.field("heightMultiplier", &SimpleParagraphStyle::heightMultiplier)
.field("maxLines", &SimpleParagraphStyle::maxLines)
.field("textAlign", &SimpleParagraphStyle::textAlign)
.field("textDirection", &SimpleParagraphStyle::textDirection)
.field("textHeightBehavior", &SimpleParagraphStyle::textHeightBehavior)
.field("textStyle", &SimpleParagraphStyle::textStyle)
.field("strutStyle", &SimpleParagraphStyle::strutStyle);
value_object<SimpleStrutStyle>("StrutStyle")
.field("_fontFamiliesPtr", &SimpleStrutStyle::fontFamiliesPtr)

View File

@ -92,4 +92,10 @@ EMSCRIPTEN_BINDINGS(ParagraphGen) {
enum_<para::TextDirection>("TextDirection")
.value("LTR", para::TextDirection::kLtr)
.value("RTL", para::TextDirection::kRtl);
enum_<para::TextHeightBehavior>("TextHeightBehavior")
.value("All", para::TextHeightBehavior::kAll)
.value("DisableFirstAscent", para::TextHeightBehavior::kDisableFirstAscent)
.value("DisableLastDescent", para::TextHeightBehavior::kDisableLastDescent)
.value("DisableAll", para::TextHeightBehavior::kDisableAll);
}

View File

@ -846,6 +846,41 @@ describe('Paragraph Behavior', function() {
builder.delete();
});
gm('paragraph_mixed_text_height_behavior', (canvas) => {
const fontMgr = CanvasKit.FontMgr.FromData(notoSerifFontBuffer);
expect(fontMgr.countFamilies()).toEqual(1);
expect(fontMgr.getFamilyName(0)).toEqual('Noto Serif');
canvas.clear(CanvasKit.WHITE);
const paint = new CanvasKit.Paint();
paint.setColor(CanvasKit.RED);
paint.setStyle(CanvasKit.PaintStyle.Stroke);
const wrapTo = 220;
const behaviors = ["All", "DisableFirstAscent", "DisableLastDescent", "DisableAll"];
for (let i = 0; i < behaviors.length; i++) {
const style = new CanvasKit.ParagraphStyle({
textStyle: {
color: CanvasKit.BLACK,
fontFamilies: ['Noto Serif'],
fontSize: 20,
heightMultiplier: 3, // make the difference more obvious
},
textHeightBehavior: CanvasKit.TextHeightBehavior[behaviors[i]],
});
const builder = CanvasKit.ParagraphBuilder.Make(style, fontMgr);
builder.addText('Text height behavior\nof '+behaviors[i]);
const paragraph = builder.build();
paragraph.layout(wrapTo);
canvas.drawParagraph(paragraph, 0, 150 * i);
canvas.drawRect(CanvasKit.LTRBRect(0, 150 * i, wrapTo, 150 * i + 120), paint);
paragraph.delete();
builder.delete();
}
paint.delete();
fontMgr.delete();
});
it('should not crash if we omit font family on pushed textStyle', () => {
const surface = CanvasKit.MakeCanvasSurface('test');
expect(surface).toBeTruthy('Could not make surface');