modern-text 0.2.4 → 0.2.6

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/dist/index.cjs CHANGED
@@ -171,9 +171,10 @@ class Character {
171
171
  this.index = index;
172
172
  this.parent = parent;
173
173
  __publicField$4(this, "boundingBox", new modernPath2d.BoundingBox());
174
- __publicField$4(this, "path", new modernPath2d.Path2D());
175
174
  __publicField$4(this, "textWidth", 0);
176
175
  __publicField$4(this, "textHeight", 0);
176
+ // glyph
177
+ __publicField$4(this, "commands", []);
177
178
  }
178
179
  get computedStyle() {
179
180
  return this.parent.computedStyle;
@@ -191,11 +192,14 @@ class Character {
191
192
  }
192
193
  return void 0;
193
194
  }
194
- _updateGlyph(font) {
195
+ updateGlyph(font = this._font()) {
196
+ if (!font) {
197
+ return this;
198
+ }
199
+ const { unitsPerEm, ascender, descender, os2, post } = font;
195
200
  const { content, computedStyle, boundingBox, isVertical } = this;
196
201
  const { left, top, height } = boundingBox;
197
202
  const { fontSize } = computedStyle;
198
- const { unitsPerEm, ascender, descender, os2, post } = font;
199
203
  const rate = unitsPerEm / fontSize;
200
204
  const glyphWidth = font.getAdvanceWidth(content, fontSize);
201
205
  const glyphHeight = (ascender + Math.abs(descender)) / rate;
@@ -216,84 +220,7 @@ class Character {
216
220
  this.centerPoint = this.glyphBox.getCenterPoint();
217
221
  return this;
218
222
  }
219
- _decoration() {
220
- const { isVertical, underlinePosition, yStrikeoutPosition } = this;
221
- const { textDecoration, fontSize } = this.computedStyle;
222
- const { left, top, width, height } = this.boundingBox;
223
- const lineWidth = 0.1 * fontSize;
224
- let start;
225
- switch (textDecoration) {
226
- case "underline":
227
- if (isVertical) {
228
- start = left;
229
- } else {
230
- start = top + underlinePosition;
231
- }
232
- break;
233
- case "line-through":
234
- if (isVertical) {
235
- start = left + width / 2;
236
- } else {
237
- start = top + yStrikeoutPosition;
238
- }
239
- break;
240
- case "none":
241
- default:
242
- return [];
243
- }
244
- if (isVertical) {
245
- return [
246
- { type: "M", x: start, y: top },
247
- { type: "L", x: start, y: top + height },
248
- { type: "L", x: start + lineWidth, y: top + height },
249
- { type: "L", x: start + lineWidth, y: top },
250
- { type: "Z" }
251
- ];
252
- } else {
253
- return [
254
- { type: "M", x: left, y: start },
255
- { type: "L", x: left + width, y: start },
256
- { type: "L", x: left + width, y: start + lineWidth },
257
- { type: "L", x: left, y: start + lineWidth },
258
- { type: "Z" }
259
- ];
260
- }
261
- }
262
- _transform(commands, cb) {
263
- return commands.map((rawCmd) => {
264
- const cmd = { ...rawCmd };
265
- switch (cmd.type) {
266
- case "L":
267
- case "M":
268
- [cmd.x, cmd.y] = cb(cmd.x, cmd.y);
269
- break;
270
- case "Q":
271
- [cmd.x1, cmd.y1] = cb(cmd.x1, cmd.y1);
272
- [cmd.x, cmd.y] = cb(cmd.x, cmd.y);
273
- break;
274
- }
275
- return cmd;
276
- });
277
- }
278
- _italic(commands, startPoint) {
279
- const { baseline, glyphWidth } = this;
280
- const { left, top } = this.boundingBox;
281
- const _startPoint = startPoint || {
282
- y: top + baseline,
283
- x: left + glyphWidth / 2
284
- };
285
- return this._transform(commands, (x, y) => {
286
- const p = getSkewPoint({ x, y }, _startPoint, -0.24, 0);
287
- return [p.x, p.y];
288
- });
289
- }
290
- _rotation90(commands, point) {
291
- return this._transform(commands, (x, y) => {
292
- const p = getPointPosition({ x, y }, point, 90);
293
- return [p.x, p.y];
294
- });
295
- }
296
- updatePath() {
223
+ updateCommands() {
297
224
  const font = this._font();
298
225
  if (!font) {
299
226
  return this;
@@ -308,7 +235,7 @@ class Character {
308
235
  baseline,
309
236
  glyphHeight,
310
237
  glyphWidth
311
- } = this._updateGlyph(font);
238
+ } = this.updateGlyph(font);
312
239
  const { os2, ascender, descender } = font;
313
240
  const usWinAscent = ascender;
314
241
  const usWinDescent = descender;
@@ -366,11 +293,120 @@ class Character {
366
293
  }
367
294
  commands.push(...this._decoration());
368
295
  this.commands = commands;
369
- this.path = new modernPath2d.Path2D(commands);
370
296
  return this;
371
297
  }
372
298
  update() {
373
- this.updatePath();
299
+ this.updateCommands();
300
+ return this;
301
+ }
302
+ _decoration() {
303
+ const { isVertical, underlinePosition, yStrikeoutPosition } = this;
304
+ const { textDecoration, fontSize } = this.computedStyle;
305
+ const { left, top, width, height } = this.boundingBox;
306
+ const lineWidth = 0.1 * fontSize;
307
+ let start;
308
+ switch (textDecoration) {
309
+ case "underline":
310
+ if (isVertical) {
311
+ start = left;
312
+ } else {
313
+ start = top + underlinePosition;
314
+ }
315
+ break;
316
+ case "line-through":
317
+ if (isVertical) {
318
+ start = left + width / 2;
319
+ } else {
320
+ start = top + yStrikeoutPosition;
321
+ }
322
+ break;
323
+ case "none":
324
+ default:
325
+ return [];
326
+ }
327
+ if (isVertical) {
328
+ return [
329
+ { type: "M", x: start, y: top },
330
+ { type: "L", x: start, y: top + height },
331
+ { type: "L", x: start + lineWidth, y: top + height },
332
+ { type: "L", x: start + lineWidth, y: top },
333
+ { type: "Z" }
334
+ ];
335
+ } else {
336
+ return [
337
+ { type: "M", x: left, y: start },
338
+ { type: "L", x: left + width, y: start },
339
+ { type: "L", x: left + width, y: start + lineWidth },
340
+ { type: "L", x: left, y: start + lineWidth },
341
+ { type: "Z" }
342
+ ];
343
+ }
344
+ }
345
+ _italic(commands, startPoint) {
346
+ const { baseline, glyphWidth } = this;
347
+ const { left, top } = this.boundingBox;
348
+ const _startPoint = startPoint || {
349
+ y: top + baseline,
350
+ x: left + glyphWidth / 2
351
+ };
352
+ return this._transform(commands, (x, y) => {
353
+ const p = getSkewPoint({ x, y }, _startPoint, -0.24, 0);
354
+ return [p.x, p.y];
355
+ });
356
+ }
357
+ _rotation90(commands, point) {
358
+ return this._transform(commands, (x, y) => {
359
+ const p = getPointPosition({ x, y }, point, 90);
360
+ return [p.x, p.y];
361
+ });
362
+ }
363
+ _transform(commands, cb) {
364
+ return commands.map((rawCmd) => {
365
+ const cmd = { ...rawCmd };
366
+ switch (cmd.type) {
367
+ case "L":
368
+ case "M":
369
+ [cmd.x, cmd.y] = cb(cmd.x, cmd.y);
370
+ break;
371
+ case "Q":
372
+ [cmd.x1, cmd.y1] = cb(cmd.x1, cmd.y1);
373
+ [cmd.x, cmd.y] = cb(cmd.x, cmd.y);
374
+ break;
375
+ }
376
+ return cmd;
377
+ });
378
+ }
379
+ forEachCommand(cb) {
380
+ const commands = this.commands;
381
+ const last = { x: 0, y: 0 };
382
+ const first = { x: 0, y: 0 };
383
+ let isFirst = true;
384
+ let doSetFirstPoint = false;
385
+ for (let i = 0, len = commands.length; i < len; i++) {
386
+ if (isFirst) {
387
+ doSetFirstPoint = true;
388
+ isFirst = false;
389
+ }
390
+ let command = commands[i];
391
+ command = cb(command, i, { last, first }) ?? command;
392
+ switch (command.type) {
393
+ case "M":
394
+ case "L":
395
+ case "Q":
396
+ last.x = command.x;
397
+ last.y = command.y;
398
+ if (doSetFirstPoint) {
399
+ first.x = last.x;
400
+ first.y = last.y;
401
+ }
402
+ break;
403
+ case "Z":
404
+ last.x = first.x;
405
+ last.y = first.y;
406
+ isFirst = true;
407
+ break;
408
+ }
409
+ }
374
410
  return this;
375
411
  }
376
412
  getMinMax(min = modernPath2d.Point2D.MAX, max = modernPath2d.Point2D.MIN) {
@@ -404,7 +440,7 @@ class Character {
404
440
  drawTo(ctx, config = {}) {
405
441
  drawPaths({
406
442
  ctx,
407
- paths: [this.path],
443
+ paths: [new modernPath2d.Path2D(this.commands)],
408
444
  fontSize: this.computedStyle.fontSize,
409
445
  color: this.computedStyle.color,
410
446
  ...config
@@ -570,7 +606,7 @@ class Highlighter extends Feature {
570
606
  this.paths = groups.filter((characters2) => characters2.length).map((characters2) => {
571
607
  return {
572
608
  url: characters2[0].parent.highlight.url,
573
- box: modernPath2d.BoundingBox.from(...characters2.map((c) => c.glyphBox)),
609
+ box: modernPath2d.BoundingBox.from(...characters2.map((c) => c.boundingBox)),
574
610
  baseline: Math.max(...characters2.map((c) => c.baseline))
575
611
  };
576
612
  }).map((group2) => this._parseGroup(group2, fontSize)).flat();
@@ -1039,14 +1075,15 @@ class Text {
1039
1075
  const { paragraphs, boundingBox } = this.measure();
1040
1076
  this.paragraphs = paragraphs;
1041
1077
  this.boundingBox = boundingBox;
1042
- this.characters.forEach((c) => c.update());
1078
+ const characters = this.characters;
1079
+ characters.forEach((c) => c.update());
1043
1080
  if (this.deformation) {
1044
1081
  this._deformer.deform();
1045
1082
  }
1046
1083
  this._highlighter.highlight();
1047
1084
  const min = modernPath2d.Point2D.MAX;
1048
1085
  const max = modernPath2d.Point2D.MIN;
1049
- this.characters.forEach((c) => c.getMinMax(min, max));
1086
+ characters.forEach((c) => c.getMinMax(min, max));
1050
1087
  this.renderBoundingBox = new modernPath2d.BoundingBox(min.x, min.y, max.x - min.x, max.y - min.y);
1051
1088
  return this;
1052
1089
  }
package/dist/index.d.cts CHANGED
@@ -12,6 +12,10 @@ type TextAlign = 'center' | 'end' | 'left' | 'right' | 'start';
12
12
  type VerticalAlign = 'baseline' | 'top' | 'middle' | 'bottom' | 'sub' | 'super' | 'text-top' | 'text-bottom';
13
13
  type TextTransform = 'uppercase' | 'lowercase' | 'none';
14
14
  type TextDecoration = 'none' | 'underline' | 'line-through';
15
+ interface PointLike {
16
+ x: number;
17
+ y: number;
18
+ }
15
19
  interface TextLayoutStyle {
16
20
  writingMode: WritingMode;
17
21
  textOrientation: TextOrientation;
@@ -97,7 +101,6 @@ declare class Character {
97
101
  index: number;
98
102
  parent: Fragment;
99
103
  boundingBox: BoundingBox;
100
- path: Path2D<any>;
101
104
  textWidth: number;
102
105
  textHeight: number;
103
106
  commands: GlyphPathCommand[];
@@ -110,28 +113,23 @@ declare class Character {
110
113
  baseline: number;
111
114
  centerDiviation: number;
112
115
  glyphBox: BoundingBox;
113
- centerPoint: {
114
- x: number;
115
- y: number;
116
- };
116
+ centerPoint: PointLike;
117
117
  get computedStyle(): TextStyle;
118
118
  get isVertical(): boolean;
119
119
  get fontSize(): number;
120
120
  constructor(content: string, index: number, parent: Fragment);
121
121
  protected _font(): Sfnt | undefined;
122
- protected _updateGlyph(font: Sfnt): this;
122
+ updateGlyph(font?: Sfnt | undefined): this;
123
+ updateCommands(): this;
124
+ update(): this;
123
125
  protected _decoration(): GlyphPathCommand[];
126
+ protected _italic(commands: GlyphPathCommand[], startPoint?: PointLike): GlyphPathCommand[];
127
+ protected _rotation90(commands: GlyphPathCommand[], point: PointLike): GlyphPathCommand[];
124
128
  protected _transform(commands: GlyphPathCommand[], cb: (x: number, y: number) => number[]): GlyphPathCommand[];
125
- protected _italic(commands: GlyphPathCommand[], startPoint?: {
126
- x: number;
127
- y: number;
128
- }): GlyphPathCommand[];
129
- protected _rotation90(commands: GlyphPathCommand[], point: {
130
- x: number;
131
- y: number;
132
- }): GlyphPathCommand[];
133
- updatePath(): this;
134
- update(): this;
129
+ forEachCommand(cb: (command: GlyphPathCommand, index: number, context: {
130
+ first: PointLike;
131
+ last: PointLike;
132
+ }) => void | GlyphPathCommand): this;
135
133
  getMinMax(min?: Point2D, max?: Point2D): {
136
134
  min: Point2D;
137
135
  max: Point2D;
@@ -346,4 +344,4 @@ declare function getPointPosition(point: {
346
344
  y: number;
347
345
  };
348
346
 
349
- export { Character, Deformer, type DrawShapePathsOptions, type EffectOptions, Effector, type FontKerning, type FontStyle, type FontWeight, Fragment, type FragmentContent, type FragmentHighlight, Highlighter, type LinearGradient, type MeasuredCharacter, type MeasuredFragment, type MeasuredParagraph, type MeasuredResult, Measurer, Paragraph, type ParagraphContent, Parser, Reflector, type Render2dOptions, Renderer2D, Text, type TextAlign, type TextContent, type TextDecoration, type TextDeformation, type TextDrawStyle, type TextEffect, type TextLayoutStyle, type TextOptions, type TextOrientation, type TextRenderOptions, type TextStyle, type TextTransform, type TextWrap, type VerticalAlign, type WritingMode, defaultTextStyles, drawPaths, filterEmpty, getPointPosition, getRotationPoint, getScalePoint, getSkewPoint, parseColor, uploadColor };
347
+ export { Character, Deformer, type DrawShapePathsOptions, type EffectOptions, Effector, type FontKerning, type FontStyle, type FontWeight, Fragment, type FragmentContent, type FragmentHighlight, Highlighter, type LinearGradient, type MeasuredCharacter, type MeasuredFragment, type MeasuredParagraph, type MeasuredResult, Measurer, Paragraph, type ParagraphContent, Parser, type PointLike, Reflector, type Render2dOptions, Renderer2D, Text, type TextAlign, type TextContent, type TextDecoration, type TextDeformation, type TextDrawStyle, type TextEffect, type TextLayoutStyle, type TextOptions, type TextOrientation, type TextRenderOptions, type TextStyle, type TextTransform, type TextWrap, type VerticalAlign, type WritingMode, defaultTextStyles, drawPaths, filterEmpty, getPointPosition, getRotationPoint, getScalePoint, getSkewPoint, parseColor, uploadColor };
package/dist/index.d.mts CHANGED
@@ -12,6 +12,10 @@ type TextAlign = 'center' | 'end' | 'left' | 'right' | 'start';
12
12
  type VerticalAlign = 'baseline' | 'top' | 'middle' | 'bottom' | 'sub' | 'super' | 'text-top' | 'text-bottom';
13
13
  type TextTransform = 'uppercase' | 'lowercase' | 'none';
14
14
  type TextDecoration = 'none' | 'underline' | 'line-through';
15
+ interface PointLike {
16
+ x: number;
17
+ y: number;
18
+ }
15
19
  interface TextLayoutStyle {
16
20
  writingMode: WritingMode;
17
21
  textOrientation: TextOrientation;
@@ -97,7 +101,6 @@ declare class Character {
97
101
  index: number;
98
102
  parent: Fragment;
99
103
  boundingBox: BoundingBox;
100
- path: Path2D<any>;
101
104
  textWidth: number;
102
105
  textHeight: number;
103
106
  commands: GlyphPathCommand[];
@@ -110,28 +113,23 @@ declare class Character {
110
113
  baseline: number;
111
114
  centerDiviation: number;
112
115
  glyphBox: BoundingBox;
113
- centerPoint: {
114
- x: number;
115
- y: number;
116
- };
116
+ centerPoint: PointLike;
117
117
  get computedStyle(): TextStyle;
118
118
  get isVertical(): boolean;
119
119
  get fontSize(): number;
120
120
  constructor(content: string, index: number, parent: Fragment);
121
121
  protected _font(): Sfnt | undefined;
122
- protected _updateGlyph(font: Sfnt): this;
122
+ updateGlyph(font?: Sfnt | undefined): this;
123
+ updateCommands(): this;
124
+ update(): this;
123
125
  protected _decoration(): GlyphPathCommand[];
126
+ protected _italic(commands: GlyphPathCommand[], startPoint?: PointLike): GlyphPathCommand[];
127
+ protected _rotation90(commands: GlyphPathCommand[], point: PointLike): GlyphPathCommand[];
124
128
  protected _transform(commands: GlyphPathCommand[], cb: (x: number, y: number) => number[]): GlyphPathCommand[];
125
- protected _italic(commands: GlyphPathCommand[], startPoint?: {
126
- x: number;
127
- y: number;
128
- }): GlyphPathCommand[];
129
- protected _rotation90(commands: GlyphPathCommand[], point: {
130
- x: number;
131
- y: number;
132
- }): GlyphPathCommand[];
133
- updatePath(): this;
134
- update(): this;
129
+ forEachCommand(cb: (command: GlyphPathCommand, index: number, context: {
130
+ first: PointLike;
131
+ last: PointLike;
132
+ }) => void | GlyphPathCommand): this;
135
133
  getMinMax(min?: Point2D, max?: Point2D): {
136
134
  min: Point2D;
137
135
  max: Point2D;
@@ -346,4 +344,4 @@ declare function getPointPosition(point: {
346
344
  y: number;
347
345
  };
348
346
 
349
- export { Character, Deformer, type DrawShapePathsOptions, type EffectOptions, Effector, type FontKerning, type FontStyle, type FontWeight, Fragment, type FragmentContent, type FragmentHighlight, Highlighter, type LinearGradient, type MeasuredCharacter, type MeasuredFragment, type MeasuredParagraph, type MeasuredResult, Measurer, Paragraph, type ParagraphContent, Parser, Reflector, type Render2dOptions, Renderer2D, Text, type TextAlign, type TextContent, type TextDecoration, type TextDeformation, type TextDrawStyle, type TextEffect, type TextLayoutStyle, type TextOptions, type TextOrientation, type TextRenderOptions, type TextStyle, type TextTransform, type TextWrap, type VerticalAlign, type WritingMode, defaultTextStyles, drawPaths, filterEmpty, getPointPosition, getRotationPoint, getScalePoint, getSkewPoint, parseColor, uploadColor };
347
+ export { Character, Deformer, type DrawShapePathsOptions, type EffectOptions, Effector, type FontKerning, type FontStyle, type FontWeight, Fragment, type FragmentContent, type FragmentHighlight, Highlighter, type LinearGradient, type MeasuredCharacter, type MeasuredFragment, type MeasuredParagraph, type MeasuredResult, Measurer, Paragraph, type ParagraphContent, Parser, type PointLike, Reflector, type Render2dOptions, Renderer2D, Text, type TextAlign, type TextContent, type TextDecoration, type TextDeformation, type TextDrawStyle, type TextEffect, type TextLayoutStyle, type TextOptions, type TextOrientation, type TextRenderOptions, type TextStyle, type TextTransform, type TextWrap, type VerticalAlign, type WritingMode, defaultTextStyles, drawPaths, filterEmpty, getPointPosition, getRotationPoint, getScalePoint, getSkewPoint, parseColor, uploadColor };
package/dist/index.d.ts CHANGED
@@ -12,6 +12,10 @@ type TextAlign = 'center' | 'end' | 'left' | 'right' | 'start';
12
12
  type VerticalAlign = 'baseline' | 'top' | 'middle' | 'bottom' | 'sub' | 'super' | 'text-top' | 'text-bottom';
13
13
  type TextTransform = 'uppercase' | 'lowercase' | 'none';
14
14
  type TextDecoration = 'none' | 'underline' | 'line-through';
15
+ interface PointLike {
16
+ x: number;
17
+ y: number;
18
+ }
15
19
  interface TextLayoutStyle {
16
20
  writingMode: WritingMode;
17
21
  textOrientation: TextOrientation;
@@ -97,7 +101,6 @@ declare class Character {
97
101
  index: number;
98
102
  parent: Fragment;
99
103
  boundingBox: BoundingBox;
100
- path: Path2D<any>;
101
104
  textWidth: number;
102
105
  textHeight: number;
103
106
  commands: GlyphPathCommand[];
@@ -110,28 +113,23 @@ declare class Character {
110
113
  baseline: number;
111
114
  centerDiviation: number;
112
115
  glyphBox: BoundingBox;
113
- centerPoint: {
114
- x: number;
115
- y: number;
116
- };
116
+ centerPoint: PointLike;
117
117
  get computedStyle(): TextStyle;
118
118
  get isVertical(): boolean;
119
119
  get fontSize(): number;
120
120
  constructor(content: string, index: number, parent: Fragment);
121
121
  protected _font(): Sfnt | undefined;
122
- protected _updateGlyph(font: Sfnt): this;
122
+ updateGlyph(font?: Sfnt | undefined): this;
123
+ updateCommands(): this;
124
+ update(): this;
123
125
  protected _decoration(): GlyphPathCommand[];
126
+ protected _italic(commands: GlyphPathCommand[], startPoint?: PointLike): GlyphPathCommand[];
127
+ protected _rotation90(commands: GlyphPathCommand[], point: PointLike): GlyphPathCommand[];
124
128
  protected _transform(commands: GlyphPathCommand[], cb: (x: number, y: number) => number[]): GlyphPathCommand[];
125
- protected _italic(commands: GlyphPathCommand[], startPoint?: {
126
- x: number;
127
- y: number;
128
- }): GlyphPathCommand[];
129
- protected _rotation90(commands: GlyphPathCommand[], point: {
130
- x: number;
131
- y: number;
132
- }): GlyphPathCommand[];
133
- updatePath(): this;
134
- update(): this;
129
+ forEachCommand(cb: (command: GlyphPathCommand, index: number, context: {
130
+ first: PointLike;
131
+ last: PointLike;
132
+ }) => void | GlyphPathCommand): this;
135
133
  getMinMax(min?: Point2D, max?: Point2D): {
136
134
  min: Point2D;
137
135
  max: Point2D;
@@ -346,4 +344,4 @@ declare function getPointPosition(point: {
346
344
  y: number;
347
345
  };
348
346
 
349
- export { Character, Deformer, type DrawShapePathsOptions, type EffectOptions, Effector, type FontKerning, type FontStyle, type FontWeight, Fragment, type FragmentContent, type FragmentHighlight, Highlighter, type LinearGradient, type MeasuredCharacter, type MeasuredFragment, type MeasuredParagraph, type MeasuredResult, Measurer, Paragraph, type ParagraphContent, Parser, Reflector, type Render2dOptions, Renderer2D, Text, type TextAlign, type TextContent, type TextDecoration, type TextDeformation, type TextDrawStyle, type TextEffect, type TextLayoutStyle, type TextOptions, type TextOrientation, type TextRenderOptions, type TextStyle, type TextTransform, type TextWrap, type VerticalAlign, type WritingMode, defaultTextStyles, drawPaths, filterEmpty, getPointPosition, getRotationPoint, getScalePoint, getSkewPoint, parseColor, uploadColor };
347
+ export { Character, Deformer, type DrawShapePathsOptions, type EffectOptions, Effector, type FontKerning, type FontStyle, type FontWeight, Fragment, type FragmentContent, type FragmentHighlight, Highlighter, type LinearGradient, type MeasuredCharacter, type MeasuredFragment, type MeasuredParagraph, type MeasuredResult, Measurer, Paragraph, type ParagraphContent, Parser, type PointLike, Reflector, type Render2dOptions, Renderer2D, Text, type TextAlign, type TextContent, type TextDecoration, type TextDeformation, type TextDrawStyle, type TextEffect, type TextLayoutStyle, type TextOptions, type TextOrientation, type TextRenderOptions, type TextStyle, type TextTransform, type TextWrap, type VerticalAlign, type WritingMode, defaultTextStyles, drawPaths, filterEmpty, getPointPosition, getRotationPoint, getScalePoint, getSkewPoint, parseColor, uploadColor };