@shotstack/shotstack-canvas 2.1.6 → 2.1.8

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.
@@ -503,6 +503,7 @@ var canvasStyleSchema = import_zod2.richTextStyleSchema.extend({
503
503
  textDecoration: import_zod.z.enum(["none", "underline", "line-through"]).default("none"),
504
504
  gradient: canvasGradientSchema.optional()
505
505
  });
506
+ var captionStyleSchema = canvasStyleSchema.omit({ wordSpacing: true });
506
507
  var canvasStrokeSchema = import_zod2.richTextStrokeSchema.extend({
507
508
  width: import_zod.z.number().min(0).default(0),
508
509
  color: import_zod.z.string().regex(HEX6).default("#000000"),
@@ -590,8 +591,7 @@ var richCaptionFontSchema = import_zod.z.object({
590
591
  weight: import_zod.z.union([import_zod.z.string(), import_zod.z.number()]).default("400"),
591
592
  color: import_zod.z.string().regex(HEX6).default("#ffffff"),
592
593
  opacity: import_zod.z.number().min(0).max(1).default(1),
593
- background: import_zod.z.string().regex(HEX6).optional(),
594
- textDecoration: import_zod.z.enum(["none", "underline", "line-through"]).default("none")
594
+ background: import_zod.z.string().regex(HEX6).optional()
595
595
  });
596
596
  var richCaptionActiveSchema = import_zod2.richCaptionActiveSchema.extend({
597
597
  font: import_zod.z.object({
@@ -629,7 +629,7 @@ var richCaptionAssetSchema = import_zod.z.object({
629
629
  src: import_zod.z.string().min(1).optional(),
630
630
  words: import_zod.z.array(wordTimingSchema).max(1e5).optional(),
631
631
  font: richCaptionFontSchema.optional(),
632
- style: canvasStyleSchema.optional(),
632
+ style: captionStyleSchema.optional(),
633
633
  stroke: canvasStrokeSchema.optional(),
634
634
  shadow: canvasShadowSchema.optional(),
635
635
  background: canvasBackgroundSchema.optional(),
@@ -1539,7 +1539,7 @@ var LayoutEngine = class {
1539
1539
  }
1540
1540
  async layout(params) {
1541
1541
  try {
1542
- const { textTransform, desc, fontSize, letterSpacing, width, emojiFallback } = params;
1542
+ const { textTransform, desc, fontSize, letterSpacing, wordSpacing = 0, width, emojiFallback } = params;
1543
1543
  const input = this.transformText(params.text, textTransform);
1544
1544
  if (!input || input.length === 0) {
1545
1545
  return [];
@@ -1569,9 +1569,10 @@ var LayoutEngine = class {
1569
1569
  char = String.fromCodePoint(codePoint);
1570
1570
  }
1571
1571
  }
1572
+ const isSpace = char === " ";
1572
1573
  return {
1573
1574
  id: g.g,
1574
- xAdvance: g.ax * scale + letterSpacing,
1575
+ xAdvance: g.ax * scale + letterSpacing + (isSpace ? wordSpacing : 0),
1575
1576
  xOffset: g.dx * scale,
1576
1577
  yOffset: -g.dy * scale,
1577
1578
  cluster: g.cl,
@@ -2848,10 +2849,10 @@ var CaptionLayoutEngine = class {
2848
2849
  let spaceWidth;
2849
2850
  if (config.measureTextWidth) {
2850
2851
  const fontString = `${config.fontWeight} ${config.fontSize}px "${config.fontFamily}"`;
2851
- spaceWidth = config.measureTextWidth(" ", fontString) + config.wordSpacing;
2852
+ spaceWidth = config.measureTextWidth(" ", fontString);
2852
2853
  } else {
2853
2854
  const spaceWord = await this.measureWord(" ", measurementConfig);
2854
- spaceWidth = spaceWord.width + config.wordSpacing;
2855
+ spaceWidth = spaceWord.width;
2855
2856
  }
2856
2857
  const groups = wordGroups.flatMap((indices) => {
2857
2858
  const groupWidths = indices.map((i) => store.widths[i]);
@@ -3423,7 +3424,7 @@ function extractCaptionBorder(asset) {
3423
3424
  };
3424
3425
  }
3425
3426
  function extractTextDecoration(asset, isActive) {
3426
- const baseDecoration = asset.font?.textDecoration;
3427
+ const baseDecoration = asset.style?.textDecoration;
3427
3428
  const activeDecoration = asset.active?.font?.textDecoration;
3428
3429
  if (isActive && activeDecoration !== void 0) {
3429
3430
  return activeDecoration === "none" ? void 0 : activeDecoration;
@@ -5486,11 +5487,14 @@ function extractSvgDimensions(svgString) {
5486
5487
  }
5487
5488
 
5488
5489
  // src/core/canvas-text-measurer.ts
5489
- async function createCanvasTextMeasurer() {
5490
+ async function createCanvasTextMeasurer(letterSpacing) {
5490
5491
  const canvasMod = await import("canvas");
5491
5492
  const canvas = canvasMod.createCanvas(1, 1);
5492
5493
  const ctx = canvas.getContext("2d");
5493
5494
  ctx.textBaseline = "alphabetic";
5495
+ if (letterSpacing) {
5496
+ ctx.letterSpacing = `${letterSpacing}px`;
5497
+ }
5494
5498
  let lastFont = "";
5495
5499
  return (text, font) => {
5496
5500
  if (font !== lastFont) {
@@ -6269,7 +6273,7 @@ var RichCaptionRenderer = class {
6269
6273
  }
6270
6274
  const font = asset.font;
6271
6275
  const style = asset.style;
6272
- const measureTextWidth = await createCanvasTextMeasurer();
6276
+ const measureTextWidth = await createCanvasTextMeasurer(style?.letterSpacing ?? 0);
6273
6277
  const fontSize = font?.size ?? 24;
6274
6278
  const lineHeight = style?.lineHeight ?? 1.2;
6275
6279
  const padding = extractCaptionPadding(asset);
@@ -6290,7 +6294,6 @@ var RichCaptionRenderer = class {
6290
6294
  fontFamily: font?.family ?? "Roboto",
6291
6295
  fontWeight: String(font?.weight ?? "400"),
6292
6296
  letterSpacing: style?.letterSpacing ?? 0,
6293
- wordSpacing: typeof style?.wordSpacing === "number" ? style.wordSpacing : 0,
6294
6297
  lineHeight,
6295
6298
  textTransform: style?.textTransform ?? "none",
6296
6299
  pauseThreshold: this.currentAsset?.pauseThreshold ?? 500,
@@ -6844,6 +6847,7 @@ async function createTextEngine(opts = {}) {
6844
6847
  text: asset.text,
6845
6848
  width: (asset.width ?? width) - padding2.left - padding2.right,
6846
6849
  letterSpacing: asset.style?.letterSpacing ?? 0,
6850
+ wordSpacing: typeof asset.style?.wordSpacing === "number" ? asset.style.wordSpacing : 0,
6847
6851
  fontSize: main.size,
6848
6852
  lineHeight: asset.style?.lineHeight ?? 1.2,
6849
6853
  desc,
@@ -271,14 +271,8 @@ declare const richCaptionAssetSchema: z.ZodObject<{
271
271
  color: z.ZodDefault<z.ZodString>;
272
272
  opacity: z.ZodDefault<z.ZodNumber>;
273
273
  background: z.ZodOptional<z.ZodString>;
274
- textDecoration: z.ZodDefault<z.ZodEnum<{
275
- none: "none";
276
- underline: "underline";
277
- "line-through": "line-through";
278
- }>>;
279
274
  }, z.core.$strip>>;
280
275
  style: z.ZodOptional<z.ZodObject<{
281
- wordSpacing: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodNumber>, z.ZodString]>>>;
282
276
  letterSpacing: z.ZodDefault<z.ZodNumber>;
283
277
  lineHeight: z.ZodDefault<z.ZodNumber>;
284
278
  textTransform: z.ZodDefault<z.ZodEnum<{
@@ -413,14 +407,8 @@ declare const CanvasRichCaptionAssetSchema: z.ZodObject<{
413
407
  color: z.ZodDefault<z.ZodString>;
414
408
  opacity: z.ZodDefault<z.ZodNumber>;
415
409
  background: z.ZodOptional<z.ZodString>;
416
- textDecoration: z.ZodDefault<z.ZodEnum<{
417
- none: "none";
418
- underline: "underline";
419
- "line-through": "line-through";
420
- }>>;
421
410
  }, z.core.$strip>>;
422
411
  style: z.ZodOptional<z.ZodObject<{
423
- wordSpacing: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodNumber>, z.ZodString]>>>;
424
412
  letterSpacing: z.ZodDefault<z.ZodNumber>;
425
413
  lineHeight: z.ZodDefault<z.ZodNumber>;
426
414
  textTransform: z.ZodDefault<z.ZodEnum<{
@@ -661,7 +649,6 @@ interface CaptionLayoutConfig {
661
649
  fontFamily: string;
662
650
  fontWeight: string | number;
663
651
  letterSpacing: number;
664
- wordSpacing: number;
665
652
  lineHeight: number;
666
653
  textTransform: "none" | "uppercase" | "lowercase" | "capitalize";
667
654
  pauseThreshold: number;
@@ -271,14 +271,8 @@ declare const richCaptionAssetSchema: z.ZodObject<{
271
271
  color: z.ZodDefault<z.ZodString>;
272
272
  opacity: z.ZodDefault<z.ZodNumber>;
273
273
  background: z.ZodOptional<z.ZodString>;
274
- textDecoration: z.ZodDefault<z.ZodEnum<{
275
- none: "none";
276
- underline: "underline";
277
- "line-through": "line-through";
278
- }>>;
279
274
  }, z.core.$strip>>;
280
275
  style: z.ZodOptional<z.ZodObject<{
281
- wordSpacing: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodNumber>, z.ZodString]>>>;
282
276
  letterSpacing: z.ZodDefault<z.ZodNumber>;
283
277
  lineHeight: z.ZodDefault<z.ZodNumber>;
284
278
  textTransform: z.ZodDefault<z.ZodEnum<{
@@ -413,14 +407,8 @@ declare const CanvasRichCaptionAssetSchema: z.ZodObject<{
413
407
  color: z.ZodDefault<z.ZodString>;
414
408
  opacity: z.ZodDefault<z.ZodNumber>;
415
409
  background: z.ZodOptional<z.ZodString>;
416
- textDecoration: z.ZodDefault<z.ZodEnum<{
417
- none: "none";
418
- underline: "underline";
419
- "line-through": "line-through";
420
- }>>;
421
410
  }, z.core.$strip>>;
422
411
  style: z.ZodOptional<z.ZodObject<{
423
- wordSpacing: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodNumber>, z.ZodString]>>>;
424
412
  letterSpacing: z.ZodDefault<z.ZodNumber>;
425
413
  lineHeight: z.ZodDefault<z.ZodNumber>;
426
414
  textTransform: z.ZodDefault<z.ZodEnum<{
@@ -661,7 +649,6 @@ interface CaptionLayoutConfig {
661
649
  fontFamily: string;
662
650
  fontWeight: string | number;
663
651
  letterSpacing: number;
664
- wordSpacing: number;
665
652
  lineHeight: number;
666
653
  textTransform: "none" | "uppercase" | "lowercase" | "capitalize";
667
654
  pauseThreshold: number;
@@ -100,6 +100,7 @@ var canvasStyleSchema = richTextStyleSchema.extend({
100
100
  textDecoration: z.enum(["none", "underline", "line-through"]).default("none"),
101
101
  gradient: canvasGradientSchema.optional()
102
102
  });
103
+ var captionStyleSchema = canvasStyleSchema.omit({ wordSpacing: true });
103
104
  var canvasStrokeSchema = richTextStrokeSchema.extend({
104
105
  width: z.number().min(0).default(0),
105
106
  color: z.string().regex(HEX6).default("#000000"),
@@ -187,8 +188,7 @@ var richCaptionFontSchema = z.object({
187
188
  weight: z.union([z.string(), z.number()]).default("400"),
188
189
  color: z.string().regex(HEX6).default("#ffffff"),
189
190
  opacity: z.number().min(0).max(1).default(1),
190
- background: z.string().regex(HEX6).optional(),
191
- textDecoration: z.enum(["none", "underline", "line-through"]).default("none")
191
+ background: z.string().regex(HEX6).optional()
192
192
  });
193
193
  var richCaptionActiveSchema = baseCaptionActiveSchema.extend({
194
194
  font: z.object({
@@ -226,7 +226,7 @@ var richCaptionAssetSchema = z.object({
226
226
  src: z.string().min(1).optional(),
227
227
  words: z.array(wordTimingSchema).max(1e5).optional(),
228
228
  font: richCaptionFontSchema.optional(),
229
- style: canvasStyleSchema.optional(),
229
+ style: captionStyleSchema.optional(),
230
230
  stroke: canvasStrokeSchema.optional(),
231
231
  shadow: canvasShadowSchema.optional(),
232
232
  background: canvasBackgroundSchema.optional(),
@@ -1135,7 +1135,7 @@ var LayoutEngine = class {
1135
1135
  }
1136
1136
  async layout(params) {
1137
1137
  try {
1138
- const { textTransform, desc, fontSize, letterSpacing, width, emojiFallback } = params;
1138
+ const { textTransform, desc, fontSize, letterSpacing, wordSpacing = 0, width, emojiFallback } = params;
1139
1139
  const input = this.transformText(params.text, textTransform);
1140
1140
  if (!input || input.length === 0) {
1141
1141
  return [];
@@ -1165,9 +1165,10 @@ var LayoutEngine = class {
1165
1165
  char = String.fromCodePoint(codePoint);
1166
1166
  }
1167
1167
  }
1168
+ const isSpace = char === " ";
1168
1169
  return {
1169
1170
  id: g.g,
1170
- xAdvance: g.ax * scale + letterSpacing,
1171
+ xAdvance: g.ax * scale + letterSpacing + (isSpace ? wordSpacing : 0),
1171
1172
  xOffset: g.dx * scale,
1172
1173
  yOffset: -g.dy * scale,
1173
1174
  cluster: g.cl,
@@ -2444,10 +2445,10 @@ var CaptionLayoutEngine = class {
2444
2445
  let spaceWidth;
2445
2446
  if (config.measureTextWidth) {
2446
2447
  const fontString = `${config.fontWeight} ${config.fontSize}px "${config.fontFamily}"`;
2447
- spaceWidth = config.measureTextWidth(" ", fontString) + config.wordSpacing;
2448
+ spaceWidth = config.measureTextWidth(" ", fontString);
2448
2449
  } else {
2449
2450
  const spaceWord = await this.measureWord(" ", measurementConfig);
2450
- spaceWidth = spaceWord.width + config.wordSpacing;
2451
+ spaceWidth = spaceWord.width;
2451
2452
  }
2452
2453
  const groups = wordGroups.flatMap((indices) => {
2453
2454
  const groupWidths = indices.map((i) => store.widths[i]);
@@ -3019,7 +3020,7 @@ function extractCaptionBorder(asset) {
3019
3020
  };
3020
3021
  }
3021
3022
  function extractTextDecoration(asset, isActive) {
3022
- const baseDecoration = asset.font?.textDecoration;
3023
+ const baseDecoration = asset.style?.textDecoration;
3023
3024
  const activeDecoration = asset.active?.font?.textDecoration;
3024
3025
  if (isActive && activeDecoration !== void 0) {
3025
3026
  return activeDecoration === "none" ? void 0 : activeDecoration;
@@ -5082,11 +5083,14 @@ function extractSvgDimensions(svgString) {
5082
5083
  }
5083
5084
 
5084
5085
  // src/core/canvas-text-measurer.ts
5085
- async function createCanvasTextMeasurer() {
5086
+ async function createCanvasTextMeasurer(letterSpacing) {
5086
5087
  const canvasMod = await import("canvas");
5087
5088
  const canvas = canvasMod.createCanvas(1, 1);
5088
5089
  const ctx = canvas.getContext("2d");
5089
5090
  ctx.textBaseline = "alphabetic";
5091
+ if (letterSpacing) {
5092
+ ctx.letterSpacing = `${letterSpacing}px`;
5093
+ }
5090
5094
  let lastFont = "";
5091
5095
  return (text, font) => {
5092
5096
  if (font !== lastFont) {
@@ -5865,7 +5869,7 @@ var RichCaptionRenderer = class {
5865
5869
  }
5866
5870
  const font = asset.font;
5867
5871
  const style = asset.style;
5868
- const measureTextWidth = await createCanvasTextMeasurer();
5872
+ const measureTextWidth = await createCanvasTextMeasurer(style?.letterSpacing ?? 0);
5869
5873
  const fontSize = font?.size ?? 24;
5870
5874
  const lineHeight = style?.lineHeight ?? 1.2;
5871
5875
  const padding = extractCaptionPadding(asset);
@@ -5886,7 +5890,6 @@ var RichCaptionRenderer = class {
5886
5890
  fontFamily: font?.family ?? "Roboto",
5887
5891
  fontWeight: String(font?.weight ?? "400"),
5888
5892
  letterSpacing: style?.letterSpacing ?? 0,
5889
- wordSpacing: typeof style?.wordSpacing === "number" ? style.wordSpacing : 0,
5890
5893
  lineHeight,
5891
5894
  textTransform: style?.textTransform ?? "none",
5892
5895
  pauseThreshold: this.currentAsset?.pauseThreshold ?? 500,
@@ -6440,6 +6443,7 @@ async function createTextEngine(opts = {}) {
6440
6443
  text: asset.text,
6441
6444
  width: (asset.width ?? width) - padding2.left - padding2.right,
6442
6445
  letterSpacing: asset.style?.letterSpacing ?? 0,
6446
+ wordSpacing: typeof asset.style?.wordSpacing === "number" ? asset.style.wordSpacing : 0,
6443
6447
  fontSize: main.size,
6444
6448
  lineHeight: asset.style?.lineHeight ?? 1.2,
6445
6449
  desc,
@@ -271,14 +271,8 @@ declare const richCaptionAssetSchema: z.ZodObject<{
271
271
  color: z.ZodDefault<z.ZodString>;
272
272
  opacity: z.ZodDefault<z.ZodNumber>;
273
273
  background: z.ZodOptional<z.ZodString>;
274
- textDecoration: z.ZodDefault<z.ZodEnum<{
275
- none: "none";
276
- underline: "underline";
277
- "line-through": "line-through";
278
- }>>;
279
274
  }, z.core.$strip>>;
280
275
  style: z.ZodOptional<z.ZodObject<{
281
- wordSpacing: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodNumber>, z.ZodString]>>>;
282
276
  letterSpacing: z.ZodDefault<z.ZodNumber>;
283
277
  lineHeight: z.ZodDefault<z.ZodNumber>;
284
278
  textTransform: z.ZodDefault<z.ZodEnum<{
@@ -413,14 +407,8 @@ declare const CanvasRichCaptionAssetSchema: z.ZodObject<{
413
407
  color: z.ZodDefault<z.ZodString>;
414
408
  opacity: z.ZodDefault<z.ZodNumber>;
415
409
  background: z.ZodOptional<z.ZodString>;
416
- textDecoration: z.ZodDefault<z.ZodEnum<{
417
- none: "none";
418
- underline: "underline";
419
- "line-through": "line-through";
420
- }>>;
421
410
  }, z.core.$strip>>;
422
411
  style: z.ZodOptional<z.ZodObject<{
423
- wordSpacing: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodNumber>, z.ZodString]>>>;
424
412
  letterSpacing: z.ZodDefault<z.ZodNumber>;
425
413
  lineHeight: z.ZodDefault<z.ZodNumber>;
426
414
  textTransform: z.ZodDefault<z.ZodEnum<{
@@ -661,7 +649,6 @@ interface CaptionLayoutConfig {
661
649
  fontFamily: string;
662
650
  fontWeight: string | number;
663
651
  letterSpacing: number;
664
- wordSpacing: number;
665
652
  lineHeight: number;
666
653
  textTransform: "none" | "uppercase" | "lowercase" | "capitalize";
667
654
  pauseThreshold: number;
package/dist/entry.web.js CHANGED
@@ -17978,6 +17978,7 @@ var canvasStyleSchema = richTextStyleSchema.extend({
17978
17978
  textDecoration: external_exports.enum(["none", "underline", "line-through"]).default("none"),
17979
17979
  gradient: canvasGradientSchema.optional()
17980
17980
  });
17981
+ var captionStyleSchema = canvasStyleSchema.omit({ wordSpacing: true });
17981
17982
  var canvasStrokeSchema = richTextStrokeSchema.extend({
17982
17983
  width: external_exports.number().min(0).default(0),
17983
17984
  color: external_exports.string().regex(HEX6).default("#000000"),
@@ -18065,8 +18066,7 @@ var richCaptionFontSchema = external_exports.object({
18065
18066
  weight: external_exports.union([external_exports.string(), external_exports.number()]).default("400"),
18066
18067
  color: external_exports.string().regex(HEX6).default("#ffffff"),
18067
18068
  opacity: external_exports.number().min(0).max(1).default(1),
18068
- background: external_exports.string().regex(HEX6).optional(),
18069
- textDecoration: external_exports.enum(["none", "underline", "line-through"]).default("none")
18069
+ background: external_exports.string().regex(HEX6).optional()
18070
18070
  });
18071
18071
  var richCaptionActiveSchema = baseCaptionActiveSchema.extend({
18072
18072
  font: external_exports.object({
@@ -18104,7 +18104,7 @@ var richCaptionAssetSchema = external_exports.object({
18104
18104
  src: external_exports.string().min(1).optional(),
18105
18105
  words: external_exports.array(wordTimingSchema).max(1e5).optional(),
18106
18106
  font: richCaptionFontSchema.optional(),
18107
- style: canvasStyleSchema.optional(),
18107
+ style: captionStyleSchema.optional(),
18108
18108
  stroke: canvasStrokeSchema.optional(),
18109
18109
  shadow: canvasShadowSchema.optional(),
18110
18110
  background: canvasBackgroundSchema.optional(),
@@ -33170,7 +33170,7 @@ var LayoutEngine = class {
33170
33170
  }
33171
33171
  async layout(params) {
33172
33172
  try {
33173
- const { textTransform, desc, fontSize, letterSpacing, width, emojiFallback } = params;
33173
+ const { textTransform, desc, fontSize, letterSpacing, wordSpacing = 0, width, emojiFallback } = params;
33174
33174
  const input = this.transformText(params.text, textTransform);
33175
33175
  if (!input || input.length === 0) {
33176
33176
  return [];
@@ -33200,9 +33200,10 @@ var LayoutEngine = class {
33200
33200
  char = String.fromCodePoint(codePoint);
33201
33201
  }
33202
33202
  }
33203
+ const isSpace = char === " ";
33203
33204
  return {
33204
33205
  id: g.g,
33205
- xAdvance: g.ax * scale + letterSpacing,
33206
+ xAdvance: g.ax * scale + letterSpacing + (isSpace ? wordSpacing : 0),
33206
33207
  xOffset: g.dx * scale,
33207
33208
  yOffset: -g.dy * scale,
33208
33209
  cluster: g.cl,
@@ -35037,10 +35038,10 @@ var CaptionLayoutEngine = class {
35037
35038
  let spaceWidth;
35038
35039
  if (config2.measureTextWidth) {
35039
35040
  const fontString = `${config2.fontWeight} ${config2.fontSize}px "${config2.fontFamily}"`;
35040
- spaceWidth = config2.measureTextWidth(" ", fontString) + config2.wordSpacing;
35041
+ spaceWidth = config2.measureTextWidth(" ", fontString);
35041
35042
  } else {
35042
35043
  const spaceWord = await this.measureWord(" ", measurementConfig);
35043
- spaceWidth = spaceWord.width + config2.wordSpacing;
35044
+ spaceWidth = spaceWord.width;
35044
35045
  }
35045
35046
  const groups = wordGroups.flatMap((indices) => {
35046
35047
  const groupWidths = indices.map((i) => store.widths[i]);
@@ -35612,7 +35613,7 @@ function extractCaptionBorder(asset) {
35612
35613
  };
35613
35614
  }
35614
35615
  function extractTextDecoration(asset, isActive) {
35615
- const baseDecoration = asset.font?.textDecoration;
35616
+ const baseDecoration = asset.style?.textDecoration;
35616
35617
  const activeDecoration = asset.active?.font?.textDecoration;
35617
35618
  if (isActive && activeDecoration !== void 0) {
35618
35619
  return activeDecoration === "none" ? void 0 : activeDecoration;
@@ -38115,6 +38116,7 @@ async function createTextEngine(opts = {}) {
38115
38116
  text: asset.text,
38116
38117
  width: (asset.width ?? width) - padding2.left - padding2.right,
38117
38118
  letterSpacing: asset.style?.letterSpacing ?? 0,
38119
+ wordSpacing: typeof asset.style?.wordSpacing === "number" ? asset.style.wordSpacing : 0,
38118
38120
  fontSize: main.size,
38119
38121
  lineHeight: asset.style?.lineHeight ?? 1.2,
38120
38122
  desc,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shotstack/shotstack-canvas",
3
- "version": "2.1.6",
3
+ "version": "2.1.8",
4
4
  "description": "Text layout & animation engine (HarfBuzz) for Node & Web - fully self-contained.",
5
5
  "type": "module",
6
6
  "main": "./dist/entry.node.cjs",
@@ -51,7 +51,7 @@
51
51
  "dependencies": {
52
52
  "@resvg/resvg-js": "^2.6.2",
53
53
  "@resvg/resvg-wasm": "^2.6.2",
54
- "@shotstack/schemas": "1.9.1",
54
+ "@shotstack/schemas": "1.9.2",
55
55
  "bidi-js": "^1.0.3",
56
56
  "canvas": "npm:@napi-rs/canvas@^0.1.54",
57
57
  "ffmpeg-static": "^5.2.0",