modern-text 0.2.41 → 0.2.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,32 +21,19 @@
21
21
  ## Usage
22
22
 
23
23
  ```ts
24
- import { Text } from 'modern-text'
24
+ import { renderText } from 'modern-text'
25
25
 
26
- const text = new Text({
26
+ const view = document.createElement('canvas')
27
+ document.body.append(view)
28
+
29
+ renderText({
30
+ view,
27
31
  style: {
28
32
  width: 100,
29
33
  height: 200,
30
34
  fontSize: 22,
31
35
  textDecoration: 'underline',
32
36
  },
33
- // content: 'paragraph'
34
- // content: [
35
- // 'paragraph1',
36
- // ['paragraph1', 'paragraph2'],
37
- // { content: 'paragraph2', fontSize: 20 },
38
- // [
39
- // { content: 'fragment1', fontSize: 12 },
40
- // { content: 'fragment2', fontSize: 30 },
41
- // ],
42
- // {
43
- // backgroundColor: 'blue',
44
- // fragments: [
45
- // { content: 'fragment3', color: 'red', fontSize: 12 },
46
- // { content: 'fragment4', color: 'black' },
47
- // ],
48
- // },
49
- // ]
50
37
  content: [
51
38
  {
52
39
  letterSpacing: 3,
@@ -59,10 +46,4 @@ const text = new Text({
59
46
  { content: 'World!', color: 'black' },
60
47
  ],
61
48
  })
62
-
63
- const view = document.createElement('canvas')
64
- text.render({ view })
65
- document.body.append(view) // canvas 2d
66
-
67
- console.log(text.measure()) // boundingBox with computed paragraphs
68
49
  ```
package/dist/index.cjs CHANGED
@@ -122,6 +122,14 @@ const set2 = /* @__PURE__ */ new Set([
122
122
  "\u2019",
123
123
  "\u02DC"
124
124
  ]);
125
+ const fsSelectionMap = {
126
+ 1: "italic",
127
+ 32: "bold"
128
+ };
129
+ const macStyleMap = {
130
+ 1: "italic",
131
+ 2: "bold"
132
+ };
125
133
  const fontWeightMap = {
126
134
  100: -0.2,
127
135
  200: -0.1,
@@ -201,17 +209,19 @@ class Character {
201
209
  if (!font) {
202
210
  return this;
203
211
  }
212
+ this.updateGlyph(font);
204
213
  const {
205
214
  isVertical,
206
215
  content,
207
- computedStyle,
216
+ computedStyle: style,
208
217
  baseline,
209
218
  inlineBox
210
- } = this.updateGlyph(font);
211
- const { os2, ascender, descender } = font;
219
+ } = this;
220
+ const { os2, head, ascender, descender } = font;
212
221
  const typoAscender = os2.sTypoAscender;
222
+ const fontStyle = fsSelectionMap[os2.fsSelection] ?? macStyleMap[head.macStyle];
213
223
  const { left, top } = inlineBox;
214
- const { fontSize, fontStyle } = computedStyle;
224
+ const needsItalic = style.fontStyle === "italic" && fontStyle !== "italic";
215
225
  let x = left;
216
226
  let y = top + baseline;
217
227
  let glyphIndex;
@@ -225,13 +235,13 @@ class Character {
225
235
  }
226
236
  if (isVertical && !set1.has(content) && (content.codePointAt(0) <= 256 || set2.has(content))) {
227
237
  path.addCommands(
228
- font.getPathCommands(content, x, top + baseline - (inlineBox.height - inlineBox.width) / 2, fontSize) ?? []
238
+ font.getPathCommands(content, x, top + baseline - (inlineBox.height - inlineBox.width) / 2, style.fontSize) ?? []
229
239
  );
230
240
  const point = {
231
241
  y: top - (inlineBox.height - inlineBox.width) / 2 + inlineBox.height / 2,
232
242
  x: x + inlineBox.width / 2
233
243
  };
234
- if (fontStyle === "italic") {
244
+ if (needsItalic) {
235
245
  this._italic(
236
246
  path,
237
247
  isVertical ? {
@@ -244,9 +254,9 @@ class Character {
244
254
  } else {
245
255
  if (glyphIndex !== void 0) {
246
256
  path.addCommands(
247
- font.glyphs.get(glyphIndex).getPathCommands(x, y, fontSize)
257
+ font.glyphs.get(glyphIndex).getPathCommands(x, y, style.fontSize)
248
258
  );
249
- if (fontStyle === "italic") {
259
+ if (needsItalic) {
250
260
  this._italic(
251
261
  path,
252
262
  isVertical ? {
@@ -257,9 +267,9 @@ class Character {
257
267
  }
258
268
  } else {
259
269
  path.addCommands(
260
- font.getPathCommands(content, x, y, fontSize) ?? []
270
+ font.getPathCommands(content, x, y, style.fontSize) ?? []
261
271
  );
262
- if (fontStyle === "italic") {
272
+ if (needsItalic) {
263
273
  this._italic(
264
274
  path,
265
275
  isVertical ? { x: x + inlineBox.height / 2, y } : void 0
@@ -268,14 +278,14 @@ class Character {
268
278
  }
269
279
  }
270
280
  path.addCommands(this._decoration());
271
- const fontWeight = computedStyle.fontWeight ?? 400;
272
- if (fontWeight in fontWeightMap) {
273
- path.bold(fontWeightMap[fontWeight] * fontSize * 0.05);
281
+ const fontWeight = style.fontWeight ?? 400;
282
+ if (fontWeight in fontWeightMap && ((fontWeight === 700 || fontWeight === "bold") && fontStyle !== "bold")) {
283
+ path.bold(fontWeightMap[fontWeight] * style.fontSize * 0.05);
274
284
  }
275
285
  path.style = {
276
- fill: computedStyle.color,
277
- stroke: computedStyle.textStrokeWidth ? computedStyle.textStrokeColor : "none",
278
- strokeWidth: computedStyle.textStrokeWidth ? computedStyle.textStrokeWidth * fontSize * 0.03 : 0
286
+ fill: style.color,
287
+ stroke: style.textStrokeWidth ? style.textStrokeColor : "none",
288
+ strokeWidth: style.textStrokeWidth ? style.textStrokeWidth * style.fontSize * 0.03 : 0
279
289
  };
280
290
  this.path = path;
281
291
  this.glyphBox = this.getGlyphBoundingBox();
@@ -453,6 +463,7 @@ class Measurer {
453
463
  "fontSize",
454
464
  "letterSpacing",
455
465
  "textStrokeWidth",
466
+ "textIndent",
456
467
  "shadowOffsetX",
457
468
  "shadowOffsetY",
458
469
  "shadowBlur"
@@ -880,56 +891,50 @@ function listStyle() {
880
891
  paths,
881
892
  update: (text) => {
882
893
  paths.length = 0;
883
- const { paragraphs, computedStyle: style, isVertical } = text;
884
- let fontSize = text.fontSize;
885
- paragraphs.forEach((p) => {
886
- p.fragments.forEach((f) => {
887
- f.characters.forEach((c) => {
888
- fontSize = Math.max(fontSize, c.computedStyle.fontSize);
889
- });
890
- });
891
- });
892
- let listStyleSize = style.listStyleSize;
893
- let image;
894
- if (!isNone(style.listStyleImage)) {
895
- image = style.listStyleImage;
896
- } else if (!isNone(style.listStyleType)) {
897
- const r = fontSize * 0.38 / 2;
898
- listStyleSize = listStyleSize === "cover" ? r * 2 : listStyleSize;
899
- switch (style.listStyleType) {
900
- case "disc":
901
- image = `<svg width="${r * 2}" height="${r * 2}" xmlns="http://www.w3.org/2000/svg">
894
+ const { paragraphs, isVertical, fontSize } = text;
895
+ const padding = fontSize * 0.45;
896
+ paragraphs.forEach((paragraph) => {
897
+ const { computedStyle: style } = paragraph;
898
+ let listStyleSize = style.listStyleSize;
899
+ let image;
900
+ if (!isNone(style.listStyleImage)) {
901
+ image = style.listStyleImage;
902
+ } else if (!isNone(style.listStyleType)) {
903
+ const r = fontSize * 0.38 / 2;
904
+ listStyleSize = listStyleSize === "cover" ? r * 2 : listStyleSize;
905
+ switch (style.listStyleType) {
906
+ case "disc":
907
+ image = `<svg width="${r * 2}" height="${r * 2}" xmlns="http://www.w3.org/2000/svg">
902
908
  <circle cx="${r}" cy="${r}" r="${r}" fill="${style.color}" />
903
909
  </svg>`;
904
- break;
910
+ break;
911
+ }
905
912
  }
906
- }
907
- if (!image) {
908
- return;
909
- }
910
- const padding = fontSize * 0.45;
911
- const imagePaths = modernPath2d.parseSvg(image);
912
- const imageBox = modernPath2d.getPathsBoundingBox(imagePaths);
913
- paragraphs.forEach((paragraph) => {
913
+ if (!image) {
914
+ return;
915
+ }
916
+ const imagePaths = modernPath2d.parseSvg(image);
917
+ const imageBox = modernPath2d.getPathsBoundingBox(imagePaths);
914
918
  const box = paragraph.lineBox;
915
- if (box) {
919
+ const fBox = paragraph.fragments[0].inlineBox;
920
+ if (fBox) {
916
921
  const m = new modernPath2d.Matrix3();
917
922
  if (isVertical) {
918
- const scale = parseScale(listStyleSize, style.fontSize, fontSize);
923
+ const scale = parseScale(listStyleSize, fontSize, fontSize);
919
924
  const reScale = fontSize / imageBox.height * scale;
920
925
  m.translate(-imageBox.left, -imageBox.top);
921
926
  m.rotate(Math.PI / 2);
922
927
  m.scale(reScale, reScale);
923
928
  m.translate(fontSize / 2 - imageBox.height * reScale / 2, 0);
924
- m.translate(box.left + (box.width - fontSize) / 2, box.top - padding);
929
+ m.translate(box.left + (box.width - fontSize) / 2, fBox.top - padding);
925
930
  } else {
926
- const scale = parseScale(listStyleSize, style.fontSize, fontSize);
931
+ const scale = parseScale(listStyleSize, fontSize, fontSize);
927
932
  const reScale = fontSize / imageBox.height * scale;
928
933
  m.translate(-imageBox.left, -imageBox.top);
929
934
  m.translate(-imageBox.width, 0);
930
935
  m.scale(reScale, reScale);
931
936
  m.translate(0, fontSize / 2 - imageBox.height * reScale / 2);
932
- m.translate(box.left - padding, box.top + (box.height - fontSize) / 2);
937
+ m.translate(fBox.left - padding, box.top + (box.height - fontSize) / 2);
933
938
  }
934
939
  paths.push(...imagePaths.map((p) => p.clone().matrix(m)));
935
940
  }
@@ -1019,8 +1024,8 @@ function render() {
1019
1024
  }
1020
1025
  function getTransform2D(text, style) {
1021
1026
  const { fontSize, renderBoundingBox } = text;
1022
- const offsetX = (style.offsetX ?? 0) * fontSize;
1023
- const offsetY = (style.offsetY ?? 0) * fontSize;
1027
+ const translateX = (style.translateX ?? 0) * fontSize;
1028
+ const translateY = (style.translateY ?? 0) * fontSize;
1024
1029
  const PI_2 = Math.PI * 2;
1025
1030
  const skewX = (style.skewX ?? 0) / 360 * PI_2;
1026
1031
  const skewY = (style.skewY ?? 0) / 360 * PI_2;
@@ -1028,7 +1033,7 @@ function getTransform2D(text, style) {
1028
1033
  const centerX = left + width / 2;
1029
1034
  const centerY = top + height / 2;
1030
1035
  tempM1.identity();
1031
- tempM2.makeTranslation(offsetX, offsetY);
1036
+ tempM2.makeTranslation(translateX, translateY);
1032
1037
  tempM1.multiply(tempM2);
1033
1038
  tempM2.makeTranslation(centerX, centerY);
1034
1039
  tempM1.multiply(tempM2);
@@ -1048,7 +1053,7 @@ var __publicField = (obj, key, value) => {
1048
1053
  const defaultTextStyles = {
1049
1054
  writingMode: "horizontal-tb",
1050
1055
  verticalAlign: "baseline",
1051
- lineHeight: 1,
1056
+ lineHeight: 1.2,
1052
1057
  letterSpacing: 0,
1053
1058
  // font
1054
1059
  fontSize: 14,
@@ -1059,21 +1064,16 @@ const defaultTextStyles = {
1059
1064
  // text
1060
1065
  textWrap: "wrap",
1061
1066
  textAlign: "start",
1067
+ textIndent: 0,
1062
1068
  textTransform: "none",
1063
1069
  textOrientation: "mixed",
1064
- // color
1065
- color: "#000",
1066
- backgroundColor: "rgba(0, 0, 0, 0)",
1067
- // text
1068
1070
  textDecoration: "none",
1069
1071
  // textStroke
1070
1072
  textStrokeWidth: 0,
1071
1073
  textStrokeColor: "#000",
1072
- // shadow
1073
- shadowColor: "rgba(0, 0, 0, 0)",
1074
- shadowOffsetX: 0,
1075
- shadowOffsetY: 0,
1076
- shadowBlur: 0,
1074
+ // color
1075
+ color: "#000",
1076
+ backgroundColor: "rgba(0, 0, 0, 0)",
1077
1077
  // listStyle
1078
1078
  listStyleType: "none",
1079
1079
  listStyleImage: "none",
@@ -1084,7 +1084,16 @@ const defaultTextStyles = {
1084
1084
  highlightImage: "none",
1085
1085
  highlightSize: "cover",
1086
1086
  highlightStrokeWidth: "100%",
1087
- highlightOverflow: "none"
1087
+ highlightOverflow: "none",
1088
+ // shadow
1089
+ shadowColor: "rgba(0, 0, 0, 0)",
1090
+ shadowOffsetX: 0,
1091
+ shadowOffsetY: 0,
1092
+ shadowBlur: 0,
1093
+ translateX: 0,
1094
+ translateY: 0,
1095
+ skewX: 0,
1096
+ skewY: 0
1088
1097
  };
1089
1098
  class Text {
1090
1099
  constructor(options = {}) {
@@ -1122,20 +1131,10 @@ class Text {
1122
1131
  }
1123
1132
  measure(dom = this.measureDom) {
1124
1133
  this.computedStyle = { ...defaultTextStyles, ...this.style };
1125
- const old = this.paragraphs;
1134
+ const oldParagraphs = this.paragraphs;
1135
+ const oldRenderBoundingBox = this.renderBoundingBox;
1126
1136
  this.paragraphs = this.parser.parse();
1127
1137
  const result = this.measurer.measure(dom);
1128
- this.paragraphs = old;
1129
- return result;
1130
- }
1131
- requestUpdate() {
1132
- this.needsUpdate = true;
1133
- return this;
1134
- }
1135
- update() {
1136
- const { paragraphs, boundingBox } = this.measure();
1137
- this.paragraphs = paragraphs;
1138
- this.boundingBox = boundingBox;
1139
1138
  const characters = this.characters;
1140
1139
  characters.forEach((c) => c.update());
1141
1140
  const plugins = [...this.plugins.values()];
@@ -1163,6 +1162,20 @@ class Text {
1163
1162
  return modernPath2d.getPathsBoundingBox(plugin.paths ?? []);
1164
1163
  }).filter(Boolean)
1165
1164
  );
1165
+ result.renderBoundingBox = this.renderBoundingBox;
1166
+ this.paragraphs = oldParagraphs;
1167
+ this.renderBoundingBox = oldRenderBoundingBox;
1168
+ return result;
1169
+ }
1170
+ requestUpdate() {
1171
+ this.needsUpdate = true;
1172
+ return this;
1173
+ }
1174
+ update() {
1175
+ const { paragraphs, boundingBox, renderBoundingBox } = this.measure();
1176
+ this.paragraphs = paragraphs;
1177
+ this.boundingBox = boundingBox;
1178
+ this.renderBoundingBox = renderBoundingBox;
1166
1179
  return this;
1167
1180
  }
1168
1181
  render(options) {
@@ -1194,6 +1207,14 @@ class Text {
1194
1207
  }
1195
1208
  }
1196
1209
 
1210
+ function measureText(options) {
1211
+ return new Text(options).measure();
1212
+ }
1213
+
1214
+ function renderText(options) {
1215
+ return new Text(options).render(options);
1216
+ }
1217
+
1197
1218
  exports.Character = Character;
1198
1219
  exports.Fragment = Fragment;
1199
1220
  exports.Measurer = Measurer;
@@ -1208,8 +1229,10 @@ exports.getTransform2D = getTransform2D;
1208
1229
  exports.highlight = highlight;
1209
1230
  exports.isNone = isNone;
1210
1231
  exports.listStyle = listStyle;
1232
+ exports.measureText = measureText;
1211
1233
  exports.parseColor = parseColor;
1212
1234
  exports.render = render;
1235
+ exports.renderText = renderText;
1213
1236
  exports.setupView = setupView;
1214
1237
  exports.uploadColor = uploadColor;
1215
1238
  exports.uploadColors = uploadColors;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { BoundingBox, Vector2, Path2D, VectorLike, Matrix3 } from 'modern-path2d';
1
+ import { BoundingBox, Path2D, Vector2, VectorLike, Matrix3 } from 'modern-path2d';
2
2
  export * from 'modern-path2d';
3
3
  import { Sfnt, GlyphPathCommand } from 'modern-font';
4
4
  export * from 'modern-font';
@@ -22,46 +22,49 @@ type HighlightImage = 'none' | string;
22
22
  type HighlightSize = 'cover' | Sizeable;
23
23
  type HighlightStrokeWidth = Sizeable;
24
24
  type HighlightOverflow = 'none' | 'visible' | 'hidden';
25
- interface TextLayoutStyle {
25
+ interface TextLineStyle {
26
26
  writingMode: WritingMode;
27
- verticalAlign: VerticalAlign;
27
+ textWrap: TextWrap;
28
+ textAlign: TextAlign;
29
+ textIndent: number;
28
30
  lineHeight: number;
31
+ listStyleType: ListStyleType;
32
+ listStyleImage: ListStyleImage;
33
+ listStyleSize: ListStyleSize;
34
+ listStylePosition: ListStylePosition;
35
+ }
36
+ interface TextInlineStyle {
37
+ verticalAlign: VerticalAlign;
29
38
  letterSpacing: number;
30
39
  fontSize: number;
31
40
  fontWeight: FontWeight;
32
41
  fontFamily: string;
33
42
  fontStyle: FontStyle;
34
43
  fontKerning?: FontKerning;
35
- textWrap: TextWrap;
36
- textAlign: TextAlign;
37
44
  textTransform: TextTransform;
38
45
  textOrientation: TextOrientation;
46
+ textDecoration: TextDecoration;
47
+ highlightReferImage: HighlightImage;
48
+ highlightImage: HighlightImage;
49
+ highlightSize: HighlightSize;
50
+ highlightStrokeWidth: HighlightStrokeWidth;
51
+ highlightOverflow: HighlightOverflow;
39
52
  }
40
53
  interface TextDrawStyle {
41
54
  color: string | CanvasGradient | CanvasPattern;
42
55
  backgroundColor: string | CanvasGradient | CanvasPattern;
43
- textDecoration: TextDecoration;
44
56
  textStrokeWidth: number;
45
57
  textStrokeColor: string | CanvasGradient | CanvasPattern;
46
58
  shadowColor: string;
47
59
  shadowOffsetX: number;
48
60
  shadowOffsetY: number;
49
61
  shadowBlur: number;
62
+ translateX: number;
63
+ translateY: number;
64
+ skewX: number;
65
+ skewY: number;
50
66
  }
51
- interface TextListStyle {
52
- listStyleType: ListStyleType;
53
- listStyleImage: ListStyleImage;
54
- listStyleSize: ListStyleSize;
55
- listStylePosition: ListStylePosition;
56
- }
57
- interface TextHighlightStyle {
58
- highlightReferImage: HighlightImage;
59
- highlightImage: HighlightImage;
60
- highlightSize: HighlightSize;
61
- highlightStrokeWidth: HighlightStrokeWidth;
62
- highlightOverflow: HighlightOverflow;
63
- }
64
- interface TextStyle extends TextLayoutStyle, TextDrawStyle, TextListStyle, TextHighlightStyle {
67
+ interface TextStyle extends TextLineStyle, TextInlineStyle, TextDrawStyle {
65
68
  }
66
69
  interface FragmentContent extends Partial<TextStyle> {
67
70
  content: string;
@@ -72,7 +75,7 @@ interface ParagraphContent extends Partial<TextStyle> {
72
75
  type TextContent = string | FragmentContent | ParagraphContent | (string | FragmentContent | ParagraphContent | (string | FragmentContent)[])[];
73
76
 
74
77
  declare function parseColor(ctx: CanvasRenderingContext2D, source: string | CanvasGradient | CanvasPattern, box: BoundingBox): string | CanvasGradient | CanvasPattern;
75
- declare function uploadColor(style: Partial<TextDrawStyle>, box: BoundingBox, ctx: CanvasRenderingContext2D): void;
78
+ declare function uploadColor(style: Partial<TextStyle>, box: BoundingBox, ctx: CanvasRenderingContext2D): void;
76
79
  interface LinearGradient {
77
80
  x0: number;
78
81
  y0: number;
@@ -84,6 +87,16 @@ interface LinearGradient {
84
87
  }[];
85
88
  }
86
89
 
90
+ interface DrawShapePathsOptions extends Partial<TextStyle> {
91
+ ctx: CanvasRenderingContext2D;
92
+ path: Path2D;
93
+ fontSize: number;
94
+ clipRect?: BoundingBox;
95
+ }
96
+ declare function drawPath(options: DrawShapePathsOptions): void;
97
+
98
+ declare function setupView(ctx: CanvasRenderingContext2D, pixelRatio: number, boundingBox: BoundingBox): void;
99
+
87
100
  declare class Fragment {
88
101
  content: string;
89
102
  style: Partial<TextStyle>;
@@ -128,7 +141,7 @@ declare class Character {
128
141
  max: Vector2;
129
142
  } | undefined;
130
143
  getGlyphBoundingBox(withStyle?: boolean): BoundingBox | undefined;
131
- drawTo(ctx: CanvasRenderingContext2D, config?: Partial<TextEffect>): void;
144
+ drawTo(ctx: CanvasRenderingContext2D, config?: Partial<TextStyle>): void;
132
145
  }
133
146
 
134
147
  declare class Paragraph {
@@ -170,7 +183,7 @@ interface MeasuredCharacter {
170
183
  textHeight: number;
171
184
  textWidth: number;
172
185
  }
173
- interface MeasuredResult {
186
+ interface MeasureDomResult {
174
187
  paragraphs: Paragraph[];
175
188
  boundingBox: BoundingBox;
176
189
  }
@@ -197,10 +210,22 @@ declare class Measurer {
197
210
  fragments: MeasuredFragment[];
198
211
  characters: MeasuredCharacter[];
199
212
  };
200
- measureDom(dom: HTMLElement): MeasuredResult;
201
- measure(dom?: HTMLElement): MeasuredResult;
213
+ measureDom(dom: HTMLElement): MeasureDomResult;
214
+ measure(dom?: HTMLElement): MeasureDomResult;
202
215
  }
203
216
 
217
+ type PromiseLike<T> = T | Promise<T>;
218
+ interface Plugin {
219
+ name: string;
220
+ paths?: Path2D[];
221
+ getBoundingBox?: (text: Text) => BoundingBox | undefined;
222
+ updateOrder?: number;
223
+ update?: (text: Text) => PromiseLike<void>;
224
+ renderOrder?: number;
225
+ render?: (ctx: CanvasRenderingContext2D, text: Text) => PromiseLike<void>;
226
+ }
227
+ declare function definePlugin(options: Plugin): Plugin;
228
+
204
229
  declare class Parser {
205
230
  protected _text: Text;
206
231
  constructor(_text: Text);
@@ -215,48 +240,19 @@ interface TextOptions {
215
240
  content?: TextContent;
216
241
  style?: Partial<TextStyle>;
217
242
  measureDom?: HTMLElement;
218
- effects?: TextEffect[];
243
+ effects?: Partial<TextStyle>[];
219
244
  }
245
+ type MeasureResult = MeasureDomResult & {
246
+ renderBoundingBox: BoundingBox;
247
+ };
220
248
  declare const defaultTextStyles: TextStyle;
221
249
  declare class Text {
222
250
  content: TextContent;
223
251
  style: Partial<TextStyle>;
224
- effects?: TextEffect[];
252
+ effects?: Partial<TextStyle>[];
225
253
  measureDom?: HTMLElement;
226
254
  needsUpdate: boolean;
227
- computedStyle: {
228
- writingMode: WritingMode;
229
- verticalAlign: VerticalAlign;
230
- lineHeight: number;
231
- letterSpacing: number;
232
- fontSize: number;
233
- fontWeight: FontWeight;
234
- fontFamily: string;
235
- fontStyle: FontStyle;
236
- fontKerning?: FontKerning;
237
- textWrap: TextWrap;
238
- textAlign: TextAlign;
239
- textTransform: TextTransform;
240
- textOrientation: TextOrientation;
241
- color: string | CanvasGradient | CanvasPattern;
242
- backgroundColor: string | CanvasGradient | CanvasPattern;
243
- textDecoration: TextDecoration;
244
- textStrokeWidth: number;
245
- textStrokeColor: string | CanvasGradient | CanvasPattern;
246
- shadowColor: string;
247
- shadowOffsetX: number;
248
- shadowOffsetY: number;
249
- shadowBlur: number;
250
- listStyleType: ListStyleType;
251
- listStyleImage: ListStyleImage;
252
- listStyleSize: ListStyleSize;
253
- listStylePosition: ListStylePosition;
254
- highlightReferImage: HighlightImage;
255
- highlightImage: HighlightImage;
256
- highlightSize: HighlightSize;
257
- highlightStrokeWidth: HighlightStrokeWidth;
258
- highlightOverflow: HighlightOverflow;
259
- };
255
+ computedStyle: TextStyle;
260
256
  paragraphs: Paragraph[];
261
257
  boundingBox: BoundingBox;
262
258
  renderBoundingBox: BoundingBox;
@@ -268,50 +264,26 @@ declare class Text {
268
264
  get characters(): Character[];
269
265
  constructor(options?: TextOptions);
270
266
  use(plugin: Plugin): this;
271
- measure(dom?: HTMLElement | undefined): MeasuredResult;
267
+ measure(dom?: HTMLElement | undefined): MeasureResult;
272
268
  requestUpdate(): this;
273
269
  update(): this;
274
270
  render(options: TextRenderOptions): this;
275
271
  }
276
272
 
277
- type PromiseLike<T> = T | Promise<T>;
278
- interface Plugin {
279
- name: string;
280
- paths?: Path2D[];
281
- getBoundingBox?: (text: Text) => BoundingBox | undefined;
282
- updateOrder?: number;
283
- update?: (text: Text) => PromiseLike<void>;
284
- renderOrder?: number;
285
- render?: (ctx: CanvasRenderingContext2D, text: Text) => PromiseLike<void>;
286
- }
287
- declare function definePlugin(options: Plugin): Plugin;
273
+ declare function uploadColors(ctx: CanvasRenderingContext2D, text: Text): void;
274
+
275
+ declare function measureText(options: TextOptions): MeasureResult;
288
276
 
289
277
  declare function highlight(): Plugin;
290
278
 
291
279
  declare function listStyle(): Plugin;
292
280
 
293
- type TextEffect = Partial<TextDrawStyle & {
294
- offsetX: number;
295
- offsetY: number;
296
- skewX: number;
297
- skewY: number;
298
- }>;
299
281
  declare function render(): Plugin;
300
- declare function getTransform2D(text: Text, style: TextEffect): Matrix3;
282
+ declare function getTransform2D(text: Text, style: Partial<TextStyle>): Matrix3;
301
283
 
302
- interface DrawShapePathsOptions extends Partial<TextEffect> {
303
- ctx: CanvasRenderingContext2D;
304
- path: Path2D;
305
- fontSize: number;
306
- clipRect?: BoundingBox;
307
- }
308
- declare function drawPath(options: DrawShapePathsOptions): void;
309
-
310
- declare function setupView(ctx: CanvasRenderingContext2D, pixelRatio: number, boundingBox: BoundingBox): void;
311
-
312
- declare function uploadColors(ctx: CanvasRenderingContext2D, text: Text): void;
284
+ declare function renderText(options: TextOptions & TextRenderOptions): Text;
313
285
 
314
286
  declare function isNone(val: string | undefined): boolean;
315
287
  declare function filterEmpty(val: Record<string, any> | undefined): Record<string, any> | undefined;
316
288
 
317
- export { Character, type DrawShapePathsOptions, type FontKerning, type FontStyle, type FontWeight, Fragment, type FragmentContent, type HighlightImage, type HighlightOverflow, type HighlightSize, type HighlightStrokeWidth, type LinearGradient, type ListStyleImage, type ListStylePosition, type ListStyleSize, type ListStyleType, type MeasuredCharacter, type MeasuredFragment, type MeasuredParagraph, type MeasuredResult, Measurer, Paragraph, type ParagraphContent, Parser, type Plugin, type Sizeable, Text, type TextAlign, type TextContent, type TextDecoration, type TextDrawStyle, type TextEffect, type TextHighlightStyle, type TextLayoutStyle, type TextListStyle, type TextOptions, type TextOrientation, type TextRenderOptions, type TextStyle, type TextTransform, type TextWrap, type VerticalAlign, type WritingMode, defaultTextStyles, definePlugin, drawPath, filterEmpty, getTransform2D, highlight, isNone, listStyle, parseColor, render, setupView, uploadColor, uploadColors };
289
+ export { Character, type DrawShapePathsOptions, type FontKerning, type FontStyle, type FontWeight, Fragment, type FragmentContent, type HighlightImage, type HighlightOverflow, type HighlightSize, type HighlightStrokeWidth, type LinearGradient, type ListStyleImage, type ListStylePosition, type ListStyleSize, type ListStyleType, type MeasureDomResult, type MeasureResult, type MeasuredCharacter, type MeasuredFragment, type MeasuredParagraph, Measurer, Paragraph, type ParagraphContent, Parser, type Plugin, type Sizeable, Text, type TextAlign, type TextContent, type TextDecoration, type TextDrawStyle, type TextInlineStyle, type TextLineStyle, type TextOptions, type TextOrientation, type TextRenderOptions, type TextStyle, type TextTransform, type TextWrap, type VerticalAlign, type WritingMode, defaultTextStyles, definePlugin, drawPath, filterEmpty, getTransform2D, highlight, isNone, listStyle, measureText, parseColor, render, renderText, setupView, uploadColor, uploadColors };