@shotstack/shotstack-canvas 1.5.8 → 1.6.0
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/entry.node.cjs +49 -13
- package/dist/entry.node.js +49 -13
- package/dist/entry.web.js +49 -13
- package/package.json +1 -1
package/dist/entry.node.cjs
CHANGED
|
@@ -397,6 +397,37 @@ async function initHB(wasmBaseURL) {
|
|
|
397
397
|
|
|
398
398
|
// src/core/font-registry.ts
|
|
399
399
|
var fontkit = __toESM(require("fontkit"), 1);
|
|
400
|
+
function normalizeWeight(weight) {
|
|
401
|
+
if (weight === void 0 || weight === null) return "400";
|
|
402
|
+
if (typeof weight === "number") return String(weight);
|
|
403
|
+
const lowerWeight = String(weight).toLowerCase().trim();
|
|
404
|
+
const weightMap = {
|
|
405
|
+
thin: "100",
|
|
406
|
+
hairline: "100",
|
|
407
|
+
extralight: "200",
|
|
408
|
+
ultralight: "200",
|
|
409
|
+
light: "300",
|
|
410
|
+
normal: "400",
|
|
411
|
+
regular: "400",
|
|
412
|
+
medium: "500",
|
|
413
|
+
semibold: "600",
|
|
414
|
+
demibold: "600",
|
|
415
|
+
bold: "700",
|
|
416
|
+
extrabold: "800",
|
|
417
|
+
ultrabold: "800",
|
|
418
|
+
black: "900",
|
|
419
|
+
heavy: "900"
|
|
420
|
+
};
|
|
421
|
+
if (weightMap[lowerWeight]) {
|
|
422
|
+
return weightMap[lowerWeight];
|
|
423
|
+
}
|
|
424
|
+
const numWeight = parseInt(String(weight), 10);
|
|
425
|
+
if (!isNaN(numWeight) && numWeight >= 100 && numWeight <= 900) {
|
|
426
|
+
return String(numWeight);
|
|
427
|
+
}
|
|
428
|
+
console.warn(`Invalid font weight "${weight}", defaulting to 400`);
|
|
429
|
+
return "400";
|
|
430
|
+
}
|
|
400
431
|
var FontRegistry = class _FontRegistry {
|
|
401
432
|
hb;
|
|
402
433
|
faces = /* @__PURE__ */ new Map();
|
|
@@ -454,7 +485,8 @@ var FontRegistry = class _FontRegistry {
|
|
|
454
485
|
return this.hb;
|
|
455
486
|
}
|
|
456
487
|
key(desc) {
|
|
457
|
-
|
|
488
|
+
const normalizedWeight = normalizeWeight(desc.weight);
|
|
489
|
+
return `${desc.family}__${normalizedWeight}`;
|
|
458
490
|
}
|
|
459
491
|
async registerFromBytes(bytes, desc) {
|
|
460
492
|
try {
|
|
@@ -466,8 +498,8 @@ var FontRegistry = class _FontRegistry {
|
|
|
466
498
|
const font = this.hb.createFont(face);
|
|
467
499
|
const upem = face.upem || 1e3;
|
|
468
500
|
font.setScale(upem, upem);
|
|
469
|
-
const
|
|
470
|
-
const weightNum =
|
|
501
|
+
const normalizedWeight = normalizeWeight(desc.weight);
|
|
502
|
+
const weightNum = parseInt(normalizedWeight, 10);
|
|
471
503
|
if (weightNum !== 400 && typeof font.setVariations === "function") {
|
|
472
504
|
try {
|
|
473
505
|
font.setVariations(`wght=${weightNum}`);
|
|
@@ -501,14 +533,15 @@ var FontRegistry = class _FontRegistry {
|
|
|
501
533
|
const loader = _FontRegistry.fallbackLoader;
|
|
502
534
|
if (!loader) return false;
|
|
503
535
|
try {
|
|
536
|
+
const normalizedWeight = normalizeWeight(desc.weight);
|
|
504
537
|
const bytes = await loader({
|
|
505
538
|
family: desc.family,
|
|
506
|
-
weight:
|
|
539
|
+
weight: normalizedWeight
|
|
507
540
|
});
|
|
508
541
|
if (!bytes) return false;
|
|
509
542
|
await this.registerFromBytes(bytes, {
|
|
510
543
|
family: desc.family,
|
|
511
|
-
weight:
|
|
544
|
+
weight: normalizedWeight
|
|
512
545
|
});
|
|
513
546
|
return true;
|
|
514
547
|
} catch {
|
|
@@ -870,19 +903,20 @@ async function buildDrawOps(p) {
|
|
|
870
903
|
const scale = p.font.size / upem;
|
|
871
904
|
const numLines = p.lines.length;
|
|
872
905
|
const lineHeightPx = p.font.size * p.style.lineHeight;
|
|
906
|
+
const textOffsetY = borderWidth + padding.top;
|
|
873
907
|
let blockY;
|
|
874
908
|
switch (p.align.vertical) {
|
|
875
909
|
case "top":
|
|
876
|
-
blockY = p.font.size +
|
|
910
|
+
blockY = p.font.size + textOffsetY;
|
|
877
911
|
break;
|
|
878
912
|
case "bottom":
|
|
879
|
-
blockY = p.textRect.height - (numLines - 1) * lineHeightPx +
|
|
913
|
+
blockY = p.textRect.height - (numLines - 1) * lineHeightPx + textOffsetY;
|
|
880
914
|
break;
|
|
881
915
|
case "middle":
|
|
882
916
|
default:
|
|
883
917
|
const capHeightRatio = 0.35;
|
|
884
918
|
const visualOffset = p.font.size * capHeightRatio;
|
|
885
|
-
blockY = (p.textRect.height - (numLines - 1) * lineHeightPx) / 2 + visualOffset +
|
|
919
|
+
blockY = (p.textRect.height - (numLines - 1) * lineHeightPx) / 2 + visualOffset + textOffsetY;
|
|
886
920
|
break;
|
|
887
921
|
}
|
|
888
922
|
const fill = p.style.gradient ? gradientSpecFrom(p.style.gradient, 1) : { kind: "solid", color: p.font.color, opacity: p.font.opacity };
|
|
@@ -891,17 +925,18 @@ async function buildDrawOps(p) {
|
|
|
891
925
|
const highlighterOps = [];
|
|
892
926
|
let gMinX = Infinity, gMinY = Infinity, gMaxX = -Infinity, gMaxY = -Infinity;
|
|
893
927
|
for (const line of p.lines) {
|
|
928
|
+
const textOffsetX = borderWidth + padding.left;
|
|
894
929
|
let lineX;
|
|
895
930
|
switch (p.align.horizontal) {
|
|
896
931
|
case "left":
|
|
897
|
-
lineX =
|
|
932
|
+
lineX = textOffsetX;
|
|
898
933
|
break;
|
|
899
934
|
case "right":
|
|
900
|
-
lineX = p.textRect.width - line.width +
|
|
935
|
+
lineX = p.textRect.width - line.width + textOffsetX;
|
|
901
936
|
break;
|
|
902
937
|
case "center":
|
|
903
938
|
default:
|
|
904
|
-
lineX = (p.textRect.width - line.width) / 2 +
|
|
939
|
+
lineX = (p.textRect.width - line.width) / 2 + textOffsetX;
|
|
905
940
|
break;
|
|
906
941
|
}
|
|
907
942
|
let xCursor = lineX;
|
|
@@ -2481,8 +2516,9 @@ async function createTextEngine(opts = {}) {
|
|
|
2481
2516
|
width: asset.width ?? width,
|
|
2482
2517
|
height: asset.height ?? height
|
|
2483
2518
|
};
|
|
2484
|
-
const
|
|
2485
|
-
const
|
|
2519
|
+
const borderWidth = asset.border?.width ?? 0;
|
|
2520
|
+
const canvasW = (asset.width ?? width) + padding.left + padding.right + borderWidth * 2;
|
|
2521
|
+
const canvasH = (asset.height ?? height) + padding.top + padding.bottom + borderWidth * 2;
|
|
2486
2522
|
const canvasPR = pixelRatio;
|
|
2487
2523
|
let ops0;
|
|
2488
2524
|
try {
|
package/dist/entry.node.js
CHANGED
|
@@ -358,6 +358,37 @@ async function initHB(wasmBaseURL) {
|
|
|
358
358
|
|
|
359
359
|
// src/core/font-registry.ts
|
|
360
360
|
import * as fontkit from "fontkit";
|
|
361
|
+
function normalizeWeight(weight) {
|
|
362
|
+
if (weight === void 0 || weight === null) return "400";
|
|
363
|
+
if (typeof weight === "number") return String(weight);
|
|
364
|
+
const lowerWeight = String(weight).toLowerCase().trim();
|
|
365
|
+
const weightMap = {
|
|
366
|
+
thin: "100",
|
|
367
|
+
hairline: "100",
|
|
368
|
+
extralight: "200",
|
|
369
|
+
ultralight: "200",
|
|
370
|
+
light: "300",
|
|
371
|
+
normal: "400",
|
|
372
|
+
regular: "400",
|
|
373
|
+
medium: "500",
|
|
374
|
+
semibold: "600",
|
|
375
|
+
demibold: "600",
|
|
376
|
+
bold: "700",
|
|
377
|
+
extrabold: "800",
|
|
378
|
+
ultrabold: "800",
|
|
379
|
+
black: "900",
|
|
380
|
+
heavy: "900"
|
|
381
|
+
};
|
|
382
|
+
if (weightMap[lowerWeight]) {
|
|
383
|
+
return weightMap[lowerWeight];
|
|
384
|
+
}
|
|
385
|
+
const numWeight = parseInt(String(weight), 10);
|
|
386
|
+
if (!isNaN(numWeight) && numWeight >= 100 && numWeight <= 900) {
|
|
387
|
+
return String(numWeight);
|
|
388
|
+
}
|
|
389
|
+
console.warn(`Invalid font weight "${weight}", defaulting to 400`);
|
|
390
|
+
return "400";
|
|
391
|
+
}
|
|
361
392
|
var FontRegistry = class _FontRegistry {
|
|
362
393
|
hb;
|
|
363
394
|
faces = /* @__PURE__ */ new Map();
|
|
@@ -415,7 +446,8 @@ var FontRegistry = class _FontRegistry {
|
|
|
415
446
|
return this.hb;
|
|
416
447
|
}
|
|
417
448
|
key(desc) {
|
|
418
|
-
|
|
449
|
+
const normalizedWeight = normalizeWeight(desc.weight);
|
|
450
|
+
return `${desc.family}__${normalizedWeight}`;
|
|
419
451
|
}
|
|
420
452
|
async registerFromBytes(bytes, desc) {
|
|
421
453
|
try {
|
|
@@ -427,8 +459,8 @@ var FontRegistry = class _FontRegistry {
|
|
|
427
459
|
const font = this.hb.createFont(face);
|
|
428
460
|
const upem = face.upem || 1e3;
|
|
429
461
|
font.setScale(upem, upem);
|
|
430
|
-
const
|
|
431
|
-
const weightNum =
|
|
462
|
+
const normalizedWeight = normalizeWeight(desc.weight);
|
|
463
|
+
const weightNum = parseInt(normalizedWeight, 10);
|
|
432
464
|
if (weightNum !== 400 && typeof font.setVariations === "function") {
|
|
433
465
|
try {
|
|
434
466
|
font.setVariations(`wght=${weightNum}`);
|
|
@@ -462,14 +494,15 @@ var FontRegistry = class _FontRegistry {
|
|
|
462
494
|
const loader = _FontRegistry.fallbackLoader;
|
|
463
495
|
if (!loader) return false;
|
|
464
496
|
try {
|
|
497
|
+
const normalizedWeight = normalizeWeight(desc.weight);
|
|
465
498
|
const bytes = await loader({
|
|
466
499
|
family: desc.family,
|
|
467
|
-
weight:
|
|
500
|
+
weight: normalizedWeight
|
|
468
501
|
});
|
|
469
502
|
if (!bytes) return false;
|
|
470
503
|
await this.registerFromBytes(bytes, {
|
|
471
504
|
family: desc.family,
|
|
472
|
-
weight:
|
|
505
|
+
weight: normalizedWeight
|
|
473
506
|
});
|
|
474
507
|
return true;
|
|
475
508
|
} catch {
|
|
@@ -831,19 +864,20 @@ async function buildDrawOps(p) {
|
|
|
831
864
|
const scale = p.font.size / upem;
|
|
832
865
|
const numLines = p.lines.length;
|
|
833
866
|
const lineHeightPx = p.font.size * p.style.lineHeight;
|
|
867
|
+
const textOffsetY = borderWidth + padding.top;
|
|
834
868
|
let blockY;
|
|
835
869
|
switch (p.align.vertical) {
|
|
836
870
|
case "top":
|
|
837
|
-
blockY = p.font.size +
|
|
871
|
+
blockY = p.font.size + textOffsetY;
|
|
838
872
|
break;
|
|
839
873
|
case "bottom":
|
|
840
|
-
blockY = p.textRect.height - (numLines - 1) * lineHeightPx +
|
|
874
|
+
blockY = p.textRect.height - (numLines - 1) * lineHeightPx + textOffsetY;
|
|
841
875
|
break;
|
|
842
876
|
case "middle":
|
|
843
877
|
default:
|
|
844
878
|
const capHeightRatio = 0.35;
|
|
845
879
|
const visualOffset = p.font.size * capHeightRatio;
|
|
846
|
-
blockY = (p.textRect.height - (numLines - 1) * lineHeightPx) / 2 + visualOffset +
|
|
880
|
+
blockY = (p.textRect.height - (numLines - 1) * lineHeightPx) / 2 + visualOffset + textOffsetY;
|
|
847
881
|
break;
|
|
848
882
|
}
|
|
849
883
|
const fill = p.style.gradient ? gradientSpecFrom(p.style.gradient, 1) : { kind: "solid", color: p.font.color, opacity: p.font.opacity };
|
|
@@ -852,17 +886,18 @@ async function buildDrawOps(p) {
|
|
|
852
886
|
const highlighterOps = [];
|
|
853
887
|
let gMinX = Infinity, gMinY = Infinity, gMaxX = -Infinity, gMaxY = -Infinity;
|
|
854
888
|
for (const line of p.lines) {
|
|
889
|
+
const textOffsetX = borderWidth + padding.left;
|
|
855
890
|
let lineX;
|
|
856
891
|
switch (p.align.horizontal) {
|
|
857
892
|
case "left":
|
|
858
|
-
lineX =
|
|
893
|
+
lineX = textOffsetX;
|
|
859
894
|
break;
|
|
860
895
|
case "right":
|
|
861
|
-
lineX = p.textRect.width - line.width +
|
|
896
|
+
lineX = p.textRect.width - line.width + textOffsetX;
|
|
862
897
|
break;
|
|
863
898
|
case "center":
|
|
864
899
|
default:
|
|
865
|
-
lineX = (p.textRect.width - line.width) / 2 +
|
|
900
|
+
lineX = (p.textRect.width - line.width) / 2 + textOffsetX;
|
|
866
901
|
break;
|
|
867
902
|
}
|
|
868
903
|
let xCursor = lineX;
|
|
@@ -2442,8 +2477,9 @@ async function createTextEngine(opts = {}) {
|
|
|
2442
2477
|
width: asset.width ?? width,
|
|
2443
2478
|
height: asset.height ?? height
|
|
2444
2479
|
};
|
|
2445
|
-
const
|
|
2446
|
-
const
|
|
2480
|
+
const borderWidth = asset.border?.width ?? 0;
|
|
2481
|
+
const canvasW = (asset.width ?? width) + padding.left + padding.right + borderWidth * 2;
|
|
2482
|
+
const canvasH = (asset.height ?? height) + padding.top + padding.bottom + borderWidth * 2;
|
|
2447
2483
|
const canvasPR = pixelRatio;
|
|
2448
2484
|
let ops0;
|
|
2449
2485
|
try {
|
package/dist/entry.web.js
CHANGED
|
@@ -362,6 +362,37 @@ async function initHB(wasmBaseURL) {
|
|
|
362
362
|
|
|
363
363
|
// src/core/font-registry.ts
|
|
364
364
|
import * as fontkit from "fontkit";
|
|
365
|
+
function normalizeWeight(weight) {
|
|
366
|
+
if (weight === void 0 || weight === null) return "400";
|
|
367
|
+
if (typeof weight === "number") return String(weight);
|
|
368
|
+
const lowerWeight = String(weight).toLowerCase().trim();
|
|
369
|
+
const weightMap = {
|
|
370
|
+
thin: "100",
|
|
371
|
+
hairline: "100",
|
|
372
|
+
extralight: "200",
|
|
373
|
+
ultralight: "200",
|
|
374
|
+
light: "300",
|
|
375
|
+
normal: "400",
|
|
376
|
+
regular: "400",
|
|
377
|
+
medium: "500",
|
|
378
|
+
semibold: "600",
|
|
379
|
+
demibold: "600",
|
|
380
|
+
bold: "700",
|
|
381
|
+
extrabold: "800",
|
|
382
|
+
ultrabold: "800",
|
|
383
|
+
black: "900",
|
|
384
|
+
heavy: "900"
|
|
385
|
+
};
|
|
386
|
+
if (weightMap[lowerWeight]) {
|
|
387
|
+
return weightMap[lowerWeight];
|
|
388
|
+
}
|
|
389
|
+
const numWeight = parseInt(String(weight), 10);
|
|
390
|
+
if (!isNaN(numWeight) && numWeight >= 100 && numWeight <= 900) {
|
|
391
|
+
return String(numWeight);
|
|
392
|
+
}
|
|
393
|
+
console.warn(`Invalid font weight "${weight}", defaulting to 400`);
|
|
394
|
+
return "400";
|
|
395
|
+
}
|
|
365
396
|
var _FontRegistry = class _FontRegistry {
|
|
366
397
|
constructor(wasmBaseURL) {
|
|
367
398
|
__publicField(this, "hb");
|
|
@@ -418,7 +449,8 @@ var _FontRegistry = class _FontRegistry {
|
|
|
418
449
|
return this.hb;
|
|
419
450
|
}
|
|
420
451
|
key(desc) {
|
|
421
|
-
|
|
452
|
+
const normalizedWeight = normalizeWeight(desc.weight);
|
|
453
|
+
return `${desc.family}__${normalizedWeight}`;
|
|
422
454
|
}
|
|
423
455
|
async registerFromBytes(bytes, desc) {
|
|
424
456
|
try {
|
|
@@ -430,8 +462,8 @@ var _FontRegistry = class _FontRegistry {
|
|
|
430
462
|
const font = this.hb.createFont(face);
|
|
431
463
|
const upem = face.upem || 1e3;
|
|
432
464
|
font.setScale(upem, upem);
|
|
433
|
-
const
|
|
434
|
-
const weightNum =
|
|
465
|
+
const normalizedWeight = normalizeWeight(desc.weight);
|
|
466
|
+
const weightNum = parseInt(normalizedWeight, 10);
|
|
435
467
|
if (weightNum !== 400 && typeof font.setVariations === "function") {
|
|
436
468
|
try {
|
|
437
469
|
font.setVariations(`wght=${weightNum}`);
|
|
@@ -465,14 +497,15 @@ var _FontRegistry = class _FontRegistry {
|
|
|
465
497
|
const loader = _FontRegistry.fallbackLoader;
|
|
466
498
|
if (!loader) return false;
|
|
467
499
|
try {
|
|
500
|
+
const normalizedWeight = normalizeWeight(desc.weight);
|
|
468
501
|
const bytes = await loader({
|
|
469
502
|
family: desc.family,
|
|
470
|
-
weight:
|
|
503
|
+
weight: normalizedWeight
|
|
471
504
|
});
|
|
472
505
|
if (!bytes) return false;
|
|
473
506
|
await this.registerFromBytes(bytes, {
|
|
474
507
|
family: desc.family,
|
|
475
|
-
weight:
|
|
508
|
+
weight: normalizedWeight
|
|
476
509
|
});
|
|
477
510
|
return true;
|
|
478
511
|
} catch {
|
|
@@ -836,19 +869,20 @@ async function buildDrawOps(p) {
|
|
|
836
869
|
const scale = p.font.size / upem;
|
|
837
870
|
const numLines = p.lines.length;
|
|
838
871
|
const lineHeightPx = p.font.size * p.style.lineHeight;
|
|
872
|
+
const textOffsetY = borderWidth + padding.top;
|
|
839
873
|
let blockY;
|
|
840
874
|
switch (p.align.vertical) {
|
|
841
875
|
case "top":
|
|
842
|
-
blockY = p.font.size +
|
|
876
|
+
blockY = p.font.size + textOffsetY;
|
|
843
877
|
break;
|
|
844
878
|
case "bottom":
|
|
845
|
-
blockY = p.textRect.height - (numLines - 1) * lineHeightPx +
|
|
879
|
+
blockY = p.textRect.height - (numLines - 1) * lineHeightPx + textOffsetY;
|
|
846
880
|
break;
|
|
847
881
|
case "middle":
|
|
848
882
|
default:
|
|
849
883
|
const capHeightRatio = 0.35;
|
|
850
884
|
const visualOffset = p.font.size * capHeightRatio;
|
|
851
|
-
blockY = (p.textRect.height - (numLines - 1) * lineHeightPx) / 2 + visualOffset +
|
|
885
|
+
blockY = (p.textRect.height - (numLines - 1) * lineHeightPx) / 2 + visualOffset + textOffsetY;
|
|
852
886
|
break;
|
|
853
887
|
}
|
|
854
888
|
const fill = p.style.gradient ? gradientSpecFrom(p.style.gradient, 1) : { kind: "solid", color: p.font.color, opacity: p.font.opacity };
|
|
@@ -857,17 +891,18 @@ async function buildDrawOps(p) {
|
|
|
857
891
|
const highlighterOps = [];
|
|
858
892
|
let gMinX = Infinity, gMinY = Infinity, gMaxX = -Infinity, gMaxY = -Infinity;
|
|
859
893
|
for (const line of p.lines) {
|
|
894
|
+
const textOffsetX = borderWidth + padding.left;
|
|
860
895
|
let lineX;
|
|
861
896
|
switch (p.align.horizontal) {
|
|
862
897
|
case "left":
|
|
863
|
-
lineX =
|
|
898
|
+
lineX = textOffsetX;
|
|
864
899
|
break;
|
|
865
900
|
case "right":
|
|
866
|
-
lineX = p.textRect.width - line.width +
|
|
901
|
+
lineX = p.textRect.width - line.width + textOffsetX;
|
|
867
902
|
break;
|
|
868
903
|
case "center":
|
|
869
904
|
default:
|
|
870
|
-
lineX = (p.textRect.width - line.width) / 2 +
|
|
905
|
+
lineX = (p.textRect.width - line.width) / 2 + textOffsetX;
|
|
871
906
|
break;
|
|
872
907
|
}
|
|
873
908
|
let xCursor = lineX;
|
|
@@ -2153,8 +2188,9 @@ async function createTextEngine(opts = {}) {
|
|
|
2153
2188
|
width: asset.width ?? width,
|
|
2154
2189
|
height: asset.height ?? height
|
|
2155
2190
|
};
|
|
2156
|
-
const
|
|
2157
|
-
const
|
|
2191
|
+
const borderWidth = asset.border?.width ?? 0;
|
|
2192
|
+
const canvasW = (asset.width ?? width) + padding.left + padding.right + borderWidth * 2;
|
|
2193
|
+
const canvasH = (asset.height ?? height) + padding.top + padding.bottom + borderWidth * 2;
|
|
2158
2194
|
const canvasPR = pixelRatio;
|
|
2159
2195
|
let ops0;
|
|
2160
2196
|
try {
|
package/package.json
CHANGED