@shotstack/shotstack-canvas 2.0.12 → 2.0.14
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 +217 -35
- package/dist/entry.node.d.cts +11 -1
- package/dist/entry.node.d.ts +11 -1
- package/dist/entry.node.js +211 -35
- package/dist/entry.web.d.ts +11 -1
- package/dist/entry.web.js +975 -34
- package/package.json +66 -65
package/dist/entry.node.cjs
CHANGED
|
@@ -371,6 +371,7 @@ __export(entry_node_exports, {
|
|
|
371
371
|
calculateAnimationStatesForGroup: () => calculateAnimationStatesForGroup,
|
|
372
372
|
commandsToPathString: () => commandsToPathString,
|
|
373
373
|
computeSimplePathBounds: () => computeSimplePathBounds,
|
|
374
|
+
containsRTLCharacters: () => containsRTLCharacters,
|
|
374
375
|
createDefaultGeneratorConfig: () => createDefaultGeneratorConfig,
|
|
375
376
|
createFrameSchedule: () => createFrameSchedule,
|
|
376
377
|
createNodePainter: () => createNodePainter,
|
|
@@ -378,6 +379,8 @@ __export(entry_node_exports, {
|
|
|
378
379
|
createRichCaptionRenderer: () => createRichCaptionRenderer,
|
|
379
380
|
createTextEngine: () => createTextEngine,
|
|
380
381
|
createVideoEncoder: () => createVideoEncoder,
|
|
382
|
+
detectParagraphDirection: () => detectParagraphDirection,
|
|
383
|
+
detectParagraphDirectionFromWords: () => detectParagraphDirectionFromWords,
|
|
381
384
|
detectPlatform: () => detectPlatform,
|
|
382
385
|
detectSubtitleFormat: () => detectSubtitleFormat,
|
|
383
386
|
extractCaptionPadding: () => extractCaptionPadding,
|
|
@@ -389,10 +392,12 @@ __export(entry_node_exports, {
|
|
|
389
392
|
getDrawCaptionWordOps: () => getDrawCaptionWordOps,
|
|
390
393
|
getEncoderCapabilities: () => getEncoderCapabilities,
|
|
391
394
|
getEncoderWarning: () => getEncoderWarning,
|
|
395
|
+
getVisibleText: () => getVisibleText,
|
|
392
396
|
groupWordsByPause: () => groupWordsByPause,
|
|
393
397
|
isDrawCaptionWordOp: () => isDrawCaptionWordOp,
|
|
394
398
|
isRTLText: () => isRTLText,
|
|
395
399
|
isWebCodecsH264Supported: () => isWebCodecsH264Supported,
|
|
400
|
+
mirrorAnimationDirection: () => mirrorAnimationDirection,
|
|
396
401
|
normalizePath: () => normalizePath,
|
|
397
402
|
normalizePathString: () => normalizePathString,
|
|
398
403
|
parseSubtitleToWords: () => parseSubtitleToWords,
|
|
@@ -400,6 +405,7 @@ __export(entry_node_exports, {
|
|
|
400
405
|
quadraticToCubic: () => quadraticToCubic,
|
|
401
406
|
renderSvgAssetToPng: () => renderSvgAssetToPng,
|
|
402
407
|
renderSvgToPng: () => renderSvgToPng,
|
|
408
|
+
reorderWordsForLine: () => reorderWordsForLine,
|
|
403
409
|
richCaptionAssetSchema: () => richCaptionAssetSchema,
|
|
404
410
|
shapeToSvgString: () => shapeToSvgString,
|
|
405
411
|
svgAssetSchema: () => import_zod2.svgAssetSchema,
|
|
@@ -1220,10 +1226,9 @@ var FontRegistry = class _FontRegistry {
|
|
|
1220
1226
|
return;
|
|
1221
1227
|
}
|
|
1222
1228
|
try {
|
|
1223
|
-
const moduleName = "canvas";
|
|
1224
1229
|
const canvasMod = await import(
|
|
1225
1230
|
/* @vite-ignore */
|
|
1226
|
-
|
|
1231
|
+
"canvas"
|
|
1227
1232
|
);
|
|
1228
1233
|
const GlobalFonts = canvasMod.GlobalFonts;
|
|
1229
1234
|
if (GlobalFonts && typeof GlobalFonts.register === "function") {
|
|
@@ -1281,6 +1286,96 @@ var FontRegistry = class _FontRegistry {
|
|
|
1281
1286
|
}
|
|
1282
1287
|
};
|
|
1283
1288
|
|
|
1289
|
+
// src/core/bidi.ts
|
|
1290
|
+
var import_bidi_js = __toESM(require("bidi-js"), 1);
|
|
1291
|
+
var bidiInstance = null;
|
|
1292
|
+
function getBidi() {
|
|
1293
|
+
if (!bidiInstance) {
|
|
1294
|
+
bidiInstance = (0, import_bidi_js.default)();
|
|
1295
|
+
}
|
|
1296
|
+
return bidiInstance;
|
|
1297
|
+
}
|
|
1298
|
+
var RTL_SCRIPT_REGEX = /[--ۿ܀-ݏݐ-ݿހ-߀-߿ࠀ-ࡀ-ࡠ-ࢠ-ࣿיִ-ﭏﭐ-﷿ﹰ-𐴀-𐹠-𞠀-𞤀-𞥟--𞸀-]/u;
|
|
1299
|
+
function containsRTLCharacters(text) {
|
|
1300
|
+
return RTL_SCRIPT_REGEX.test(text);
|
|
1301
|
+
}
|
|
1302
|
+
function detectParagraphDirection(text) {
|
|
1303
|
+
const bidi = getBidi();
|
|
1304
|
+
const { paragraphs } = bidi.getEmbeddingLevels(text);
|
|
1305
|
+
if (paragraphs.length === 0) {
|
|
1306
|
+
return "ltr";
|
|
1307
|
+
}
|
|
1308
|
+
return paragraphs[0].level % 2 === 1 ? "rtl" : "ltr";
|
|
1309
|
+
}
|
|
1310
|
+
function detectParagraphDirectionFromWords(words) {
|
|
1311
|
+
const combined = words.join(" ");
|
|
1312
|
+
return detectParagraphDirection(combined);
|
|
1313
|
+
}
|
|
1314
|
+
function reorderWordsForLine(wordTexts, paragraphDirection) {
|
|
1315
|
+
if (wordTexts.length <= 1) {
|
|
1316
|
+
return wordTexts.map((_, i) => i);
|
|
1317
|
+
}
|
|
1318
|
+
const lineText = wordTexts.join(" ");
|
|
1319
|
+
const bidi = getBidi();
|
|
1320
|
+
const { levels } = bidi.getEmbeddingLevels(lineText, paragraphDirection);
|
|
1321
|
+
const wordLevels = [];
|
|
1322
|
+
let charIndex = 0;
|
|
1323
|
+
for (let i = 0; i < wordTexts.length; i++) {
|
|
1324
|
+
const wordLevel = levels[charIndex];
|
|
1325
|
+
wordLevels.push(wordLevel);
|
|
1326
|
+
charIndex += wordTexts[i].length;
|
|
1327
|
+
if (i < wordTexts.length - 1) {
|
|
1328
|
+
charIndex += 1;
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
const indices = wordTexts.map((_, i) => i);
|
|
1332
|
+
const maxLevel = Math.max(...wordLevels);
|
|
1333
|
+
const minOddLevel = paragraphDirection === "rtl" ? 1 : Math.min(...wordLevels.filter((l) => l % 2 === 1), maxLevel + 1);
|
|
1334
|
+
for (let level = maxLevel; level >= minOddLevel; level--) {
|
|
1335
|
+
let start = 0;
|
|
1336
|
+
while (start < indices.length) {
|
|
1337
|
+
if (wordLevels[indices[start]] >= level) {
|
|
1338
|
+
let end = start;
|
|
1339
|
+
while (end + 1 < indices.length && wordLevels[indices[end + 1]] >= level) {
|
|
1340
|
+
end++;
|
|
1341
|
+
}
|
|
1342
|
+
if (start < end) {
|
|
1343
|
+
let left = start;
|
|
1344
|
+
let right = end;
|
|
1345
|
+
while (left < right) {
|
|
1346
|
+
const tmp = indices[left];
|
|
1347
|
+
indices[left] = indices[right];
|
|
1348
|
+
indices[right] = tmp;
|
|
1349
|
+
left++;
|
|
1350
|
+
right--;
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
start = end + 1;
|
|
1354
|
+
} else {
|
|
1355
|
+
start++;
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
return indices;
|
|
1360
|
+
}
|
|
1361
|
+
function getVisibleText(text, visibleCharacters, isRTL) {
|
|
1362
|
+
if (visibleCharacters < 0 || visibleCharacters >= text.length) {
|
|
1363
|
+
return text;
|
|
1364
|
+
}
|
|
1365
|
+
if (visibleCharacters === 0) {
|
|
1366
|
+
return "";
|
|
1367
|
+
}
|
|
1368
|
+
return text.slice(0, visibleCharacters);
|
|
1369
|
+
}
|
|
1370
|
+
function mirrorAnimationDirection(direction, isRTL) {
|
|
1371
|
+
if (!isRTL) {
|
|
1372
|
+
return direction;
|
|
1373
|
+
}
|
|
1374
|
+
if (direction === "left") return "right";
|
|
1375
|
+
if (direction === "right") return "left";
|
|
1376
|
+
return direction;
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1284
1379
|
// src/core/layout.ts
|
|
1285
1380
|
function isEmoji(char) {
|
|
1286
1381
|
const code = char.codePointAt(0);
|
|
@@ -1310,7 +1405,7 @@ var LayoutEngine = class {
|
|
|
1310
1405
|
return t;
|
|
1311
1406
|
}
|
|
1312
1407
|
}
|
|
1313
|
-
async shapeFull(text, desc) {
|
|
1408
|
+
async shapeFull(text, desc, direction) {
|
|
1314
1409
|
try {
|
|
1315
1410
|
const hb = await this.fonts.getHB();
|
|
1316
1411
|
const buffer = hb.createBuffer();
|
|
@@ -1349,7 +1444,8 @@ var LayoutEngine = class {
|
|
|
1349
1444
|
let shaped;
|
|
1350
1445
|
try {
|
|
1351
1446
|
if (!emojiFallback) {
|
|
1352
|
-
|
|
1447
|
+
const textDirection = containsRTLCharacters(input) ? "rtl" : void 0;
|
|
1448
|
+
shaped = await this.shapeFull(input, desc, textDirection);
|
|
1353
1449
|
} else {
|
|
1354
1450
|
const chars = Array.from(input);
|
|
1355
1451
|
const runs = [];
|
|
@@ -1370,7 +1466,8 @@ var LayoutEngine = class {
|
|
|
1370
1466
|
shaped = [];
|
|
1371
1467
|
for (const run of runs) {
|
|
1372
1468
|
const runFont = run.isEmoji ? emojiFallback : desc;
|
|
1373
|
-
const
|
|
1469
|
+
const runDirection = containsRTLCharacters(run.text) ? "rtl" : void 0;
|
|
1470
|
+
const runShaped = await this.shapeFull(run.text, runFont, runDirection);
|
|
1374
1471
|
for (const glyph of runShaped) {
|
|
1375
1472
|
glyph.cl += run.startIndex;
|
|
1376
1473
|
glyph.fontDesc = runFont;
|
|
@@ -1471,9 +1568,11 @@ var LayoutEngine = class {
|
|
|
1471
1568
|
y: 0
|
|
1472
1569
|
});
|
|
1473
1570
|
}
|
|
1571
|
+
const textIsRTL = containsRTLCharacters(input);
|
|
1474
1572
|
const lineHeight = params.lineHeight * fontSize;
|
|
1475
1573
|
for (let i = 0; i < lines.length; i++) {
|
|
1476
1574
|
lines[i].y = (i + 1) * lineHeight;
|
|
1575
|
+
lines[i].isRTL = textIsRTL;
|
|
1477
1576
|
}
|
|
1478
1577
|
return lines;
|
|
1479
1578
|
} catch (err) {
|
|
@@ -1512,6 +1611,14 @@ function normalizePadding(padding) {
|
|
|
1512
1611
|
}
|
|
1513
1612
|
return padding;
|
|
1514
1613
|
}
|
|
1614
|
+
function resolveHorizontalAlign(align, isRTL) {
|
|
1615
|
+
if (!isRTL || align === "center") {
|
|
1616
|
+
return align;
|
|
1617
|
+
}
|
|
1618
|
+
if (align === "left") return "right";
|
|
1619
|
+
if (align === "right") return "left";
|
|
1620
|
+
return align;
|
|
1621
|
+
}
|
|
1515
1622
|
async function buildDrawOps(p) {
|
|
1516
1623
|
const ops = [];
|
|
1517
1624
|
const padding = normalizePadding(p.padding);
|
|
@@ -1552,7 +1659,8 @@ async function buildDrawOps(p) {
|
|
|
1552
1659
|
let gMinX = Infinity, gMinY = Infinity, gMaxX = -Infinity, gMaxY = -Infinity;
|
|
1553
1660
|
for (const line of p.lines) {
|
|
1554
1661
|
let lineX;
|
|
1555
|
-
|
|
1662
|
+
const effectiveAlign = resolveHorizontalAlign(p.align.horizontal, line.isRTL);
|
|
1663
|
+
switch (effectiveAlign) {
|
|
1556
1664
|
case "left":
|
|
1557
1665
|
lineX = 0;
|
|
1558
1666
|
break;
|
|
@@ -1680,7 +1788,7 @@ async function buildDrawOps(p) {
|
|
|
1680
1788
|
const contentWidth = p.contentRect?.width ?? p.canvas.width;
|
|
1681
1789
|
const contentHeight = p.contentRect?.height ?? p.canvas.height;
|
|
1682
1790
|
const borderWidth2 = p.border?.width ?? 0;
|
|
1683
|
-
const borderRadius = p.border?.radius ?? 0;
|
|
1791
|
+
const borderRadius = p.border?.radius ?? p.background?.borderRadius ?? 0;
|
|
1684
1792
|
const halfBorder = borderWidth2 / 2;
|
|
1685
1793
|
const canvasCenterX = p.canvas.width / 2;
|
|
1686
1794
|
const canvasCenterY = p.canvas.height / 2;
|
|
@@ -1798,7 +1906,15 @@ function applyAnimation(ops, lines, p) {
|
|
|
1798
1906
|
case "fadeIn":
|
|
1799
1907
|
return applyFadeInAnimation(ops, lines, progress, p.anim.style, p.fontSize, duration);
|
|
1800
1908
|
case "slideIn":
|
|
1801
|
-
return applySlideInAnimation(
|
|
1909
|
+
return applySlideInAnimation(
|
|
1910
|
+
ops,
|
|
1911
|
+
lines,
|
|
1912
|
+
progress,
|
|
1913
|
+
p.anim.direction ?? "left",
|
|
1914
|
+
p.fontSize,
|
|
1915
|
+
p.anim.style,
|
|
1916
|
+
duration
|
|
1917
|
+
);
|
|
1802
1918
|
case "shift":
|
|
1803
1919
|
return applyShiftAnimation(
|
|
1804
1920
|
ops,
|
|
@@ -1826,6 +1942,9 @@ function applyAnimation(ops, lines, p) {
|
|
|
1826
1942
|
}
|
|
1827
1943
|
var isShadowFill = (op) => op.op === "FillPath" && op.isShadow === true;
|
|
1828
1944
|
var isGlyphFill = (op) => op.op === "FillPath" && !op.isShadow === true;
|
|
1945
|
+
function isRTLLines(lines) {
|
|
1946
|
+
return lines.length > 0 && lines[0].isRTL === true;
|
|
1947
|
+
}
|
|
1829
1948
|
function getTextColorFromOps(ops) {
|
|
1830
1949
|
for (const op of ops) {
|
|
1831
1950
|
if (op.op === "FillPath") {
|
|
@@ -1845,28 +1964,32 @@ function applyTypewriterAnimation(ops, lines, progress, style, fontSize, time, d
|
|
|
1845
1964
|
const totalWords = wordSegments.length;
|
|
1846
1965
|
const visibleWords = Math.floor(progress * totalWords);
|
|
1847
1966
|
if (visibleWords === 0) {
|
|
1848
|
-
return ops.filter(
|
|
1967
|
+
return ops.filter(
|
|
1968
|
+
(x) => x.op === "BeginFrame" || x.op === "Rectangle" || x.op === "RectangleStroke"
|
|
1969
|
+
);
|
|
1849
1970
|
}
|
|
1850
1971
|
let totalVisibleGlyphs = 0;
|
|
1851
1972
|
for (let i = 0; i < Math.min(visibleWords, wordSegments.length); i++) {
|
|
1852
1973
|
totalVisibleGlyphs += wordSegments[i].glyphCount;
|
|
1853
1974
|
}
|
|
1854
|
-
const visibleOpsRaw = sliceGlyphOps(ops, totalVisibleGlyphs);
|
|
1975
|
+
const visibleOpsRaw = isRTLLines(lines) ? sliceGlyphOpsFromEnd(ops, totalVisibleGlyphs) : sliceGlyphOps(ops, totalVisibleGlyphs);
|
|
1855
1976
|
const visibleOps = progress >= DECORATION_DONE_THRESHOLD ? visibleOpsRaw : visibleOpsRaw.filter((o) => o.op !== "DecorationLine");
|
|
1856
1977
|
if (progress < 1 && totalVisibleGlyphs > 0) {
|
|
1857
|
-
return addTypewriterCursor(visibleOps, totalVisibleGlyphs, fontSize, time);
|
|
1978
|
+
return addTypewriterCursor(visibleOps, totalVisibleGlyphs, fontSize, time, isRTLLines(lines));
|
|
1858
1979
|
}
|
|
1859
1980
|
return visibleOps;
|
|
1860
1981
|
} else {
|
|
1861
1982
|
const totalGlyphs = lines.reduce((s, l) => s + l.glyphs.length, 0);
|
|
1862
1983
|
const visibleGlyphs = Math.floor(progress * totalGlyphs);
|
|
1863
1984
|
if (visibleGlyphs === 0) {
|
|
1864
|
-
return ops.filter(
|
|
1985
|
+
return ops.filter(
|
|
1986
|
+
(x) => x.op === "BeginFrame" || x.op === "Rectangle" || x.op === "RectangleStroke"
|
|
1987
|
+
);
|
|
1865
1988
|
}
|
|
1866
|
-
const visibleOpsRaw = sliceGlyphOps(ops, visibleGlyphs);
|
|
1989
|
+
const visibleOpsRaw = isRTLLines(lines) ? sliceGlyphOpsFromEnd(ops, visibleGlyphs) : sliceGlyphOps(ops, visibleGlyphs);
|
|
1867
1990
|
const visibleOps = progress >= DECORATION_DONE_THRESHOLD ? visibleOpsRaw : visibleOpsRaw.filter((o) => o.op !== "DecorationLine");
|
|
1868
1991
|
if (progress < 1 && visibleGlyphs > 0) {
|
|
1869
|
-
return addTypewriterCursor(visibleOps, visibleGlyphs, fontSize, time);
|
|
1992
|
+
return addTypewriterCursor(visibleOps, visibleGlyphs, fontSize, time, isRTLLines(lines));
|
|
1870
1993
|
}
|
|
1871
1994
|
return visibleOps;
|
|
1872
1995
|
}
|
|
@@ -1897,7 +2020,8 @@ function applyAscendAnimation(ops, lines, progress, direction, fontSize, duratio
|
|
|
1897
2020
|
acc += gcount;
|
|
1898
2021
|
}
|
|
1899
2022
|
if (wordIndex >= 0) {
|
|
1900
|
-
const
|
|
2023
|
+
const effectiveWordIndex = isRTLLines(lines) ? Math.max(0, totalWords - 1 - wordIndex) : wordIndex;
|
|
2024
|
+
const startF = effectiveWordIndex / Math.max(1, totalWords) * (duration / duration);
|
|
1901
2025
|
const endF = Math.min(1, startF + 0.3);
|
|
1902
2026
|
if (progress >= endF) {
|
|
1903
2027
|
result.push(op);
|
|
@@ -1977,7 +2101,8 @@ function applyShiftAnimation(ops, lines, progress, direction, fontSize, style, d
|
|
|
1977
2101
|
}
|
|
1978
2102
|
unitIndex = Math.max(0, wordIndex);
|
|
1979
2103
|
}
|
|
1980
|
-
const
|
|
2104
|
+
const effectiveUnit = isRTLLines(lines) ? Math.max(0, totalUnits - 1 - unitIndex) : unitIndex;
|
|
2105
|
+
const { startF, endF } = windowFor(effectiveUnit);
|
|
1981
2106
|
if (progress <= startF) {
|
|
1982
2107
|
const animated = { ...op, x: op.x + offset.x, y: op.y + offset.y };
|
|
1983
2108
|
if (op.op === "FillPath") {
|
|
@@ -2058,7 +2183,8 @@ function applyFadeInAnimation(ops, lines, progress, style, fontSize, duration) {
|
|
|
2058
2183
|
}
|
|
2059
2184
|
unitIndex = Math.max(0, wordIndex);
|
|
2060
2185
|
}
|
|
2061
|
-
const
|
|
2186
|
+
const effectiveUnit = isRTLLines(lines) ? Math.max(0, totalUnits - 1 - unitIndex) : unitIndex;
|
|
2187
|
+
const { startF, endF } = windowFor(effectiveUnit);
|
|
2062
2188
|
if (progress <= startF) {
|
|
2063
2189
|
const animated = { ...op };
|
|
2064
2190
|
if (op.op === "FillPath") {
|
|
@@ -2145,7 +2271,8 @@ function applySlideInAnimation(ops, lines, progress, direction, fontSize, style,
|
|
|
2145
2271
|
}
|
|
2146
2272
|
unitIndex = Math.max(0, wordIndex);
|
|
2147
2273
|
}
|
|
2148
|
-
const
|
|
2274
|
+
const effectiveUnit = isRTLLines(lines) ? Math.max(0, totalUnits - 1 - unitIndex) : unitIndex;
|
|
2275
|
+
const { startF, endF } = windowFor(effectiveUnit);
|
|
2149
2276
|
if (progress <= startF) {
|
|
2150
2277
|
const animated = { ...op, x: op.x + offset.x, y: op.y + offset.y };
|
|
2151
2278
|
if (op.op === "FillPath") {
|
|
@@ -2212,6 +2339,43 @@ function segmentLineBySpaces(line) {
|
|
|
2212
2339
|
if (current.length) words.push(current);
|
|
2213
2340
|
return words;
|
|
2214
2341
|
}
|
|
2342
|
+
function sliceGlyphOpsFromEnd(ops, maxGlyphs) {
|
|
2343
|
+
let totalGlyphs = 0;
|
|
2344
|
+
for (const op of ops) {
|
|
2345
|
+
if (op.op === "FillPath" && !isShadowFill(op)) totalGlyphs++;
|
|
2346
|
+
}
|
|
2347
|
+
const skipCount = Math.max(0, totalGlyphs - maxGlyphs);
|
|
2348
|
+
const result = [];
|
|
2349
|
+
let glyphCount = 0;
|
|
2350
|
+
let foundGlyphs = false;
|
|
2351
|
+
for (const op of ops) {
|
|
2352
|
+
if (op.op === "BeginFrame" || op.op === "Rectangle" || op.op === "RectangleStroke") {
|
|
2353
|
+
result.push(op);
|
|
2354
|
+
continue;
|
|
2355
|
+
}
|
|
2356
|
+
if (op.op === "FillPath" && !isShadowFill(op)) {
|
|
2357
|
+
if (glyphCount >= skipCount) {
|
|
2358
|
+
result.push(op);
|
|
2359
|
+
foundGlyphs = true;
|
|
2360
|
+
}
|
|
2361
|
+
glyphCount++;
|
|
2362
|
+
continue;
|
|
2363
|
+
}
|
|
2364
|
+
if (op.op === "StrokePath") {
|
|
2365
|
+
if (glyphCount >= skipCount) result.push(op);
|
|
2366
|
+
continue;
|
|
2367
|
+
}
|
|
2368
|
+
if (op.op === "FillPath" && isShadowFill(op)) {
|
|
2369
|
+
if (glyphCount >= skipCount) result.push(op);
|
|
2370
|
+
continue;
|
|
2371
|
+
}
|
|
2372
|
+
if (op.op === "DecorationLine" && foundGlyphs) {
|
|
2373
|
+
result.push(op);
|
|
2374
|
+
continue;
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
return result;
|
|
2378
|
+
}
|
|
2215
2379
|
function sliceGlyphOps(ops, maxGlyphs) {
|
|
2216
2380
|
const result = [];
|
|
2217
2381
|
let glyphCount = 0;
|
|
@@ -2244,27 +2408,30 @@ function sliceGlyphOps(ops, maxGlyphs) {
|
|
|
2244
2408
|
}
|
|
2245
2409
|
return result;
|
|
2246
2410
|
}
|
|
2247
|
-
function addTypewriterCursor(ops, glyphCount, fontSize, time) {
|
|
2411
|
+
function addTypewriterCursor(ops, glyphCount, fontSize, time, isRTL = false) {
|
|
2248
2412
|
if (glyphCount === 0) return ops;
|
|
2249
2413
|
const blinkRate = 1;
|
|
2250
2414
|
const cursorVisible = Math.floor(time * blinkRate * 2) % 2 === 0;
|
|
2251
2415
|
const alwaysShowCursor = true;
|
|
2252
2416
|
if (!alwaysShowCursor && !cursorVisible) return ops;
|
|
2253
2417
|
let last = null;
|
|
2418
|
+
let first = null;
|
|
2254
2419
|
let count = 0;
|
|
2255
2420
|
for (const op of ops) {
|
|
2256
2421
|
if (op.op === "FillPath" && !isShadowFill(op)) {
|
|
2257
2422
|
count++;
|
|
2423
|
+
if (count === 1) first = op;
|
|
2258
2424
|
if (count === glyphCount) {
|
|
2259
2425
|
last = op;
|
|
2260
2426
|
break;
|
|
2261
2427
|
}
|
|
2262
2428
|
}
|
|
2263
2429
|
}
|
|
2264
|
-
|
|
2430
|
+
const cursorAnchor = isRTL && first ? first : last;
|
|
2431
|
+
if (cursorAnchor && cursorAnchor.op === "FillPath") {
|
|
2265
2432
|
const color = getTextColorFromOps(ops);
|
|
2266
|
-
const cursorX =
|
|
2267
|
-
const cursorY =
|
|
2433
|
+
const cursorX = isRTL && first ? first.x - fontSize * 0.15 : cursorAnchor.x + fontSize * 0.5;
|
|
2434
|
+
const cursorY = cursorAnchor.y;
|
|
2268
2435
|
const cursorWidth = Math.max(3, fontSize / 15);
|
|
2269
2436
|
const cursorOp = {
|
|
2270
2437
|
op: "DecorationLine",
|
|
@@ -2624,7 +2791,7 @@ function calculateNoneState(ctx) {
|
|
|
2624
2791
|
isActive: isWordActive(ctx)
|
|
2625
2792
|
};
|
|
2626
2793
|
}
|
|
2627
|
-
function calculateWordAnimationState(wordStart, wordEnd, currentTime, config, activeScale = 1, charCount = 0, fontSize = 48) {
|
|
2794
|
+
function calculateWordAnimationState(wordStart, wordEnd, currentTime, config, activeScale = 1, charCount = 0, fontSize = 48, isRTL = false) {
|
|
2628
2795
|
const safeSpeed = config.speed > 0 ? config.speed : 1;
|
|
2629
2796
|
const ctx = {
|
|
2630
2797
|
wordStart,
|
|
@@ -2647,9 +2814,11 @@ function calculateWordAnimationState(wordStart, wordEnd, currentTime, config, ac
|
|
|
2647
2814
|
case "fade":
|
|
2648
2815
|
partialState = calculateFadeState(ctx, safeSpeed);
|
|
2649
2816
|
break;
|
|
2650
|
-
case "slide":
|
|
2651
|
-
|
|
2817
|
+
case "slide": {
|
|
2818
|
+
const slideDir = mirrorAnimationDirection(config.direction, isRTL);
|
|
2819
|
+
partialState = calculateSlideState(ctx, slideDir, config.speed, fontSize);
|
|
2652
2820
|
break;
|
|
2821
|
+
}
|
|
2653
2822
|
case "bounce":
|
|
2654
2823
|
partialState = calculateBounceState(ctx, safeSpeed, fontSize);
|
|
2655
2824
|
break;
|
|
@@ -2677,7 +2846,8 @@ function calculateAnimationStatesForGroup(words, currentTime, config, activeScal
|
|
|
2677
2846
|
config,
|
|
2678
2847
|
activeScale,
|
|
2679
2848
|
word.text.length,
|
|
2680
|
-
fontSize
|
|
2849
|
+
fontSize,
|
|
2850
|
+
word.isRTL
|
|
2681
2851
|
);
|
|
2682
2852
|
states.set(word.wordIndex, state);
|
|
2683
2853
|
}
|
|
@@ -2821,7 +2991,7 @@ function extractActiveScale(asset) {
|
|
|
2821
2991
|
}
|
|
2822
2992
|
function createDrawCaptionWordOp(word, animState, asset, fontConfig) {
|
|
2823
2993
|
const isActive = animState.isActive;
|
|
2824
|
-
const displayText =
|
|
2994
|
+
const displayText = getVisibleText(word.text, animState.visibleCharacters, word.isRTL);
|
|
2825
2995
|
return {
|
|
2826
2996
|
op: "DrawCaptionWord",
|
|
2827
2997
|
text: displayText,
|
|
@@ -3276,7 +3446,7 @@ async function createNodePainter(opts) {
|
|
|
3276
3446
|
renderToBoth((context) => {
|
|
3277
3447
|
for (const wordOp of captionWordOps) {
|
|
3278
3448
|
if (!wordOp.background) continue;
|
|
3279
|
-
const wordDisplayText = wordOp.
|
|
3449
|
+
const wordDisplayText = getVisibleText(wordOp.text, wordOp.visibleCharacters, wordOp.isRTL);
|
|
3280
3450
|
if (wordDisplayText.length === 0) continue;
|
|
3281
3451
|
context.save();
|
|
3282
3452
|
const bgTx = Math.round(wordOp.x + wordOp.transform.translateX);
|
|
@@ -3310,7 +3480,7 @@ async function createNodePainter(opts) {
|
|
|
3310
3480
|
context.restore();
|
|
3311
3481
|
}
|
|
3312
3482
|
for (const wordOp of captionWordOps) {
|
|
3313
|
-
const displayText = wordOp.
|
|
3483
|
+
const displayText = getVisibleText(wordOp.text, wordOp.visibleCharacters, wordOp.isRTL);
|
|
3314
3484
|
if (displayText.length === 0) continue;
|
|
3315
3485
|
context.save();
|
|
3316
3486
|
const tx = Math.round(wordOp.x + wordOp.transform.translateX);
|
|
@@ -4842,9 +5012,8 @@ function extractSvgDimensions(svgString) {
|
|
|
4842
5012
|
|
|
4843
5013
|
// src/core/rich-caption-layout.ts
|
|
4844
5014
|
var import_lru_cache = require("lru-cache");
|
|
4845
|
-
var RTL_RANGES = /[\u0590-\u05FF\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/;
|
|
4846
5015
|
function isRTLText(text) {
|
|
4847
|
-
return
|
|
5016
|
+
return containsRTLCharacters(text);
|
|
4848
5017
|
}
|
|
4849
5018
|
var WordTimingStore = class {
|
|
4850
5019
|
startTimes;
|
|
@@ -5103,6 +5272,8 @@ var CaptionLayoutEngine = class {
|
|
|
5103
5272
|
return (config.frameHeight - totalHeight) / 2 + config.fontSize;
|
|
5104
5273
|
}
|
|
5105
5274
|
};
|
|
5275
|
+
const allWordTexts = store.words.slice(0, store.length);
|
|
5276
|
+
const paragraphDirection = detectParagraphDirectionFromWords(allWordTexts);
|
|
5106
5277
|
const calculateLineX = (lineWidth) => {
|
|
5107
5278
|
switch (config.horizontalAlign) {
|
|
5108
5279
|
case "left":
|
|
@@ -5120,8 +5291,11 @@ var CaptionLayoutEngine = class {
|
|
|
5120
5291
|
const line = group.lines[lineIdx];
|
|
5121
5292
|
line.x = calculateLineX(line.width);
|
|
5122
5293
|
line.y = baseY + lineIdx * config.fontSize * config.lineHeight;
|
|
5294
|
+
const lineWordTexts = line.wordIndices.map((idx) => store.words[idx]);
|
|
5295
|
+
const visualOrder = reorderWordsForLine(lineWordTexts, paragraphDirection);
|
|
5123
5296
|
let xCursor = line.x;
|
|
5124
|
-
for (const
|
|
5297
|
+
for (const visualIdx of visualOrder) {
|
|
5298
|
+
const wordIdx = line.wordIndices[visualIdx];
|
|
5125
5299
|
store.xPositions[wordIdx] = xCursor;
|
|
5126
5300
|
store.yPositions[wordIdx] = line.y;
|
|
5127
5301
|
xCursor += store.widths[wordIdx] + spaceWidth;
|
|
@@ -5131,7 +5305,8 @@ var CaptionLayoutEngine = class {
|
|
|
5131
5305
|
return {
|
|
5132
5306
|
store,
|
|
5133
5307
|
groups,
|
|
5134
|
-
shapedWords
|
|
5308
|
+
shapedWords,
|
|
5309
|
+
paragraphDirection
|
|
5135
5310
|
};
|
|
5136
5311
|
}
|
|
5137
5312
|
getVisibleWordsAtTime(layout, timeMs) {
|
|
@@ -6602,7 +6777,7 @@ async function createTextEngine(opts = {}) {
|
|
|
6602
6777
|
horizontal: asset.align?.horizontal ?? "center",
|
|
6603
6778
|
vertical: asset.align?.vertical ?? "middle"
|
|
6604
6779
|
},
|
|
6605
|
-
background: asset.background,
|
|
6780
|
+
background: asset.background ? { color: asset.background.color, opacity: asset.background.opacity, borderRadius: typeof asset.background.borderRadius === "number" ? asset.background.borderRadius : Number(asset.background.borderRadius) || 0 } : void 0,
|
|
6606
6781
|
border: asset.border,
|
|
6607
6782
|
padding: asset.padding,
|
|
6608
6783
|
glyphPathProvider: (gid, fontDesc) => fonts.glyphPath(fontDesc || desc, gid),
|
|
@@ -6657,7 +6832,8 @@ async function createTextEngine(opts = {}) {
|
|
|
6657
6832
|
try {
|
|
6658
6833
|
const hasBackground = !!asset.background?.color;
|
|
6659
6834
|
const hasAnimation = !!asset.animation?.preset;
|
|
6660
|
-
const
|
|
6835
|
+
const bgBorderRadius = typeof asset.background?.borderRadius === "number" ? asset.background.borderRadius : Number(asset.background?.borderRadius) || 0;
|
|
6836
|
+
const hasBorderRadius = (asset.border?.radius ?? 0) > 0 || bgBorderRadius > 0;
|
|
6661
6837
|
const needsAlpha = !hasBackground && hasAnimation || hasBorderRadius;
|
|
6662
6838
|
console.log(
|
|
6663
6839
|
`\u{1F3A8} Video settings: Animation=${hasAnimation}, Background=${hasBackground}, BorderRadius=${hasBorderRadius}, Alpha=${needsAlpha}`
|
|
@@ -6716,6 +6892,7 @@ async function createTextEngine(opts = {}) {
|
|
|
6716
6892
|
calculateAnimationStatesForGroup,
|
|
6717
6893
|
commandsToPathString,
|
|
6718
6894
|
computeSimplePathBounds,
|
|
6895
|
+
containsRTLCharacters,
|
|
6719
6896
|
createDefaultGeneratorConfig,
|
|
6720
6897
|
createFrameSchedule,
|
|
6721
6898
|
createNodePainter,
|
|
@@ -6723,6 +6900,8 @@ async function createTextEngine(opts = {}) {
|
|
|
6723
6900
|
createRichCaptionRenderer,
|
|
6724
6901
|
createTextEngine,
|
|
6725
6902
|
createVideoEncoder,
|
|
6903
|
+
detectParagraphDirection,
|
|
6904
|
+
detectParagraphDirectionFromWords,
|
|
6726
6905
|
detectPlatform,
|
|
6727
6906
|
detectSubtitleFormat,
|
|
6728
6907
|
extractCaptionPadding,
|
|
@@ -6734,10 +6913,12 @@ async function createTextEngine(opts = {}) {
|
|
|
6734
6913
|
getDrawCaptionWordOps,
|
|
6735
6914
|
getEncoderCapabilities,
|
|
6736
6915
|
getEncoderWarning,
|
|
6916
|
+
getVisibleText,
|
|
6737
6917
|
groupWordsByPause,
|
|
6738
6918
|
isDrawCaptionWordOp,
|
|
6739
6919
|
isRTLText,
|
|
6740
6920
|
isWebCodecsH264Supported,
|
|
6921
|
+
mirrorAnimationDirection,
|
|
6741
6922
|
normalizePath,
|
|
6742
6923
|
normalizePathString,
|
|
6743
6924
|
parseSubtitleToWords,
|
|
@@ -6745,6 +6926,7 @@ async function createTextEngine(opts = {}) {
|
|
|
6745
6926
|
quadraticToCubic,
|
|
6746
6927
|
renderSvgAssetToPng,
|
|
6747
6928
|
renderSvgToPng,
|
|
6929
|
+
reorderWordsForLine,
|
|
6748
6930
|
richCaptionAssetSchema,
|
|
6749
6931
|
shapeToSvgString,
|
|
6750
6932
|
svgAssetSchema,
|
package/dist/entry.node.d.cts
CHANGED
|
@@ -594,6 +594,14 @@ declare class FontRegistry {
|
|
|
594
594
|
destroy(): void;
|
|
595
595
|
}
|
|
596
596
|
|
|
597
|
+
declare function containsRTLCharacters(text: string): boolean;
|
|
598
|
+
type ParagraphDirection = "ltr" | "rtl";
|
|
599
|
+
declare function detectParagraphDirection(text: string): ParagraphDirection;
|
|
600
|
+
declare function detectParagraphDirectionFromWords(words: string[]): ParagraphDirection;
|
|
601
|
+
declare function reorderWordsForLine(wordTexts: string[], paragraphDirection: ParagraphDirection): number[];
|
|
602
|
+
declare function getVisibleText(text: string, visibleCharacters: number, isRTL: boolean): string;
|
|
603
|
+
declare function mirrorAnimationDirection(direction: "left" | "right" | "up" | "down", isRTL: boolean): "left" | "right" | "up" | "down";
|
|
604
|
+
|
|
597
605
|
interface WordTiming {
|
|
598
606
|
text: string;
|
|
599
607
|
start: number;
|
|
@@ -658,6 +666,7 @@ interface CaptionLayout {
|
|
|
658
666
|
store: WordTimingStore;
|
|
659
667
|
groups: CaptionGroup[];
|
|
660
668
|
shapedWords: ShapedWord[];
|
|
669
|
+
paragraphDirection: ParagraphDirection;
|
|
661
670
|
}
|
|
662
671
|
declare function isRTLText(text: string): boolean;
|
|
663
672
|
declare class WordTimingStore {
|
|
@@ -771,6 +780,7 @@ type ShapedLine = {
|
|
|
771
780
|
glyphs: Glyph[];
|
|
772
781
|
width: number;
|
|
773
782
|
y: number;
|
|
783
|
+
isRTL?: boolean;
|
|
774
784
|
};
|
|
775
785
|
type DrawOp = {
|
|
776
786
|
op: "BeginFrame";
|
|
@@ -1331,4 +1341,4 @@ declare function createTextEngine(opts?: {
|
|
|
1331
1341
|
destroy(): void;
|
|
1332
1342
|
}>;
|
|
1333
1343
|
|
|
1334
|
-
export { ASCENT_RATIO, type AnimationDirection, type AnimationStyle, type ArcCommand, type BackgroundConfig, type BoundingBox, type CanvasRichCaptionAsset, CanvasRichCaptionAssetSchema, type CanvasRichTextAsset, CanvasRichTextAssetSchema, type CanvasSvgAsset, CanvasSvgAssetSchema, type CaptionGroup, type CaptionLayout, type CaptionLayoutConfig, CaptionLayoutEngine, type CaptionLine, type ClosePathCommand, type CubicBezierCommand, DESCENT_RATIO, type DrawOp, type EngineInit, type FastVideoOptions, type FastVideoResult, type FontConfig, FontRegistry, type FrameSchedule, type Glyph, type GradientSpec, type IVideoEncoder, type LineToCommand, type MoveToCommand, NodeRawEncoder, type NormalizedPathCommand, type ParsedPathCommand, type PathCommandType, type Point2D, type PositionedWord, type QuadraticBezierCommand, type RGBA, type RenderFrame, type RenderStats, type Renderer, type ResvgRenderOptions, type ResvgRenderResult, type RichCaptionGeneratorConfig, RichCaptionRenderer, type RichCaptionRendererOptions, type ShadowConfig, type ShapedLine, type ShapedWord, type ShapedWordGlyph, type ShotstackRichTextAsset, type ShotstackSvgAsset, type StrokeConfig, type StrokeSpec, type ValidAsset, type VideoEncoderCapabilities, type VideoEncoderConfig, type VideoEncoderProgress, WORD_BG_BORDER_RADIUS, WORD_BG_OPACITY, WORD_BG_PADDING_RATIO, type WordAnimationConfig, type WordAnimationState, type WordTiming, WordTimingStore, arcToCubicBeziers, breakIntoLines, calculateAnimationStatesForGroup, commandsToPathString, computeSimplePathBounds, createDefaultGeneratorConfig, createFrameSchedule, createNodePainter, createNodeRawEncoder, createRichCaptionRenderer, createTextEngine, createVideoEncoder, detectPlatform, detectSubtitleFormat, extractCaptionPadding, findWordAtTime, generateRichCaptionDrawOps, generateRichCaptionFrame, generateShapePathData, getDefaultAnimationConfig, getDrawCaptionWordOps, getEncoderCapabilities, getEncoderWarning, groupWordsByPause, isDrawCaptionWordOp, isRTLText, isWebCodecsH264Supported, normalizePath, normalizePathString, parseSubtitleToWords, parseSvgPath, quadraticToCubic, renderSvgAssetToPng, renderSvgToPng, richCaptionAssetSchema, shapeToSvgString };
|
|
1344
|
+
export { ASCENT_RATIO, type AnimationDirection, type AnimationStyle, type ArcCommand, type BackgroundConfig, type BoundingBox, type CanvasRichCaptionAsset, CanvasRichCaptionAssetSchema, type CanvasRichTextAsset, CanvasRichTextAssetSchema, type CanvasSvgAsset, CanvasSvgAssetSchema, type CaptionGroup, type CaptionLayout, type CaptionLayoutConfig, CaptionLayoutEngine, type CaptionLine, type ClosePathCommand, type CubicBezierCommand, DESCENT_RATIO, type DrawOp, type EngineInit, type FastVideoOptions, type FastVideoResult, type FontConfig, FontRegistry, type FrameSchedule, type Glyph, type GradientSpec, type IVideoEncoder, type LineToCommand, type MoveToCommand, NodeRawEncoder, type NormalizedPathCommand, type ParagraphDirection, type ParsedPathCommand, type PathCommandType, type Point2D, type PositionedWord, type QuadraticBezierCommand, type RGBA, type RenderFrame, type RenderStats, type Renderer, type ResvgRenderOptions, type ResvgRenderResult, type RichCaptionGeneratorConfig, RichCaptionRenderer, type RichCaptionRendererOptions, type ShadowConfig, type ShapedLine, type ShapedWord, type ShapedWordGlyph, type ShotstackRichTextAsset, type ShotstackSvgAsset, type StrokeConfig, type StrokeSpec, type ValidAsset, type VideoEncoderCapabilities, type VideoEncoderConfig, type VideoEncoderProgress, WORD_BG_BORDER_RADIUS, WORD_BG_OPACITY, WORD_BG_PADDING_RATIO, type WordAnimationConfig, type WordAnimationState, type WordTiming, WordTimingStore, arcToCubicBeziers, breakIntoLines, calculateAnimationStatesForGroup, commandsToPathString, computeSimplePathBounds, containsRTLCharacters, createDefaultGeneratorConfig, createFrameSchedule, createNodePainter, createNodeRawEncoder, createRichCaptionRenderer, createTextEngine, createVideoEncoder, detectParagraphDirection, detectParagraphDirectionFromWords, detectPlatform, detectSubtitleFormat, extractCaptionPadding, findWordAtTime, generateRichCaptionDrawOps, generateRichCaptionFrame, generateShapePathData, getDefaultAnimationConfig, getDrawCaptionWordOps, getEncoderCapabilities, getEncoderWarning, getVisibleText, groupWordsByPause, isDrawCaptionWordOp, isRTLText, isWebCodecsH264Supported, mirrorAnimationDirection, normalizePath, normalizePathString, parseSubtitleToWords, parseSvgPath, quadraticToCubic, renderSvgAssetToPng, renderSvgToPng, reorderWordsForLine, richCaptionAssetSchema, shapeToSvgString };
|
package/dist/entry.node.d.ts
CHANGED
|
@@ -594,6 +594,14 @@ declare class FontRegistry {
|
|
|
594
594
|
destroy(): void;
|
|
595
595
|
}
|
|
596
596
|
|
|
597
|
+
declare function containsRTLCharacters(text: string): boolean;
|
|
598
|
+
type ParagraphDirection = "ltr" | "rtl";
|
|
599
|
+
declare function detectParagraphDirection(text: string): ParagraphDirection;
|
|
600
|
+
declare function detectParagraphDirectionFromWords(words: string[]): ParagraphDirection;
|
|
601
|
+
declare function reorderWordsForLine(wordTexts: string[], paragraphDirection: ParagraphDirection): number[];
|
|
602
|
+
declare function getVisibleText(text: string, visibleCharacters: number, isRTL: boolean): string;
|
|
603
|
+
declare function mirrorAnimationDirection(direction: "left" | "right" | "up" | "down", isRTL: boolean): "left" | "right" | "up" | "down";
|
|
604
|
+
|
|
597
605
|
interface WordTiming {
|
|
598
606
|
text: string;
|
|
599
607
|
start: number;
|
|
@@ -658,6 +666,7 @@ interface CaptionLayout {
|
|
|
658
666
|
store: WordTimingStore;
|
|
659
667
|
groups: CaptionGroup[];
|
|
660
668
|
shapedWords: ShapedWord[];
|
|
669
|
+
paragraphDirection: ParagraphDirection;
|
|
661
670
|
}
|
|
662
671
|
declare function isRTLText(text: string): boolean;
|
|
663
672
|
declare class WordTimingStore {
|
|
@@ -771,6 +780,7 @@ type ShapedLine = {
|
|
|
771
780
|
glyphs: Glyph[];
|
|
772
781
|
width: number;
|
|
773
782
|
y: number;
|
|
783
|
+
isRTL?: boolean;
|
|
774
784
|
};
|
|
775
785
|
type DrawOp = {
|
|
776
786
|
op: "BeginFrame";
|
|
@@ -1331,4 +1341,4 @@ declare function createTextEngine(opts?: {
|
|
|
1331
1341
|
destroy(): void;
|
|
1332
1342
|
}>;
|
|
1333
1343
|
|
|
1334
|
-
export { ASCENT_RATIO, type AnimationDirection, type AnimationStyle, type ArcCommand, type BackgroundConfig, type BoundingBox, type CanvasRichCaptionAsset, CanvasRichCaptionAssetSchema, type CanvasRichTextAsset, CanvasRichTextAssetSchema, type CanvasSvgAsset, CanvasSvgAssetSchema, type CaptionGroup, type CaptionLayout, type CaptionLayoutConfig, CaptionLayoutEngine, type CaptionLine, type ClosePathCommand, type CubicBezierCommand, DESCENT_RATIO, type DrawOp, type EngineInit, type FastVideoOptions, type FastVideoResult, type FontConfig, FontRegistry, type FrameSchedule, type Glyph, type GradientSpec, type IVideoEncoder, type LineToCommand, type MoveToCommand, NodeRawEncoder, type NormalizedPathCommand, type ParsedPathCommand, type PathCommandType, type Point2D, type PositionedWord, type QuadraticBezierCommand, type RGBA, type RenderFrame, type RenderStats, type Renderer, type ResvgRenderOptions, type ResvgRenderResult, type RichCaptionGeneratorConfig, RichCaptionRenderer, type RichCaptionRendererOptions, type ShadowConfig, type ShapedLine, type ShapedWord, type ShapedWordGlyph, type ShotstackRichTextAsset, type ShotstackSvgAsset, type StrokeConfig, type StrokeSpec, type ValidAsset, type VideoEncoderCapabilities, type VideoEncoderConfig, type VideoEncoderProgress, WORD_BG_BORDER_RADIUS, WORD_BG_OPACITY, WORD_BG_PADDING_RATIO, type WordAnimationConfig, type WordAnimationState, type WordTiming, WordTimingStore, arcToCubicBeziers, breakIntoLines, calculateAnimationStatesForGroup, commandsToPathString, computeSimplePathBounds, createDefaultGeneratorConfig, createFrameSchedule, createNodePainter, createNodeRawEncoder, createRichCaptionRenderer, createTextEngine, createVideoEncoder, detectPlatform, detectSubtitleFormat, extractCaptionPadding, findWordAtTime, generateRichCaptionDrawOps, generateRichCaptionFrame, generateShapePathData, getDefaultAnimationConfig, getDrawCaptionWordOps, getEncoderCapabilities, getEncoderWarning, groupWordsByPause, isDrawCaptionWordOp, isRTLText, isWebCodecsH264Supported, normalizePath, normalizePathString, parseSubtitleToWords, parseSvgPath, quadraticToCubic, renderSvgAssetToPng, renderSvgToPng, richCaptionAssetSchema, shapeToSvgString };
|
|
1344
|
+
export { ASCENT_RATIO, type AnimationDirection, type AnimationStyle, type ArcCommand, type BackgroundConfig, type BoundingBox, type CanvasRichCaptionAsset, CanvasRichCaptionAssetSchema, type CanvasRichTextAsset, CanvasRichTextAssetSchema, type CanvasSvgAsset, CanvasSvgAssetSchema, type CaptionGroup, type CaptionLayout, type CaptionLayoutConfig, CaptionLayoutEngine, type CaptionLine, type ClosePathCommand, type CubicBezierCommand, DESCENT_RATIO, type DrawOp, type EngineInit, type FastVideoOptions, type FastVideoResult, type FontConfig, FontRegistry, type FrameSchedule, type Glyph, type GradientSpec, type IVideoEncoder, type LineToCommand, type MoveToCommand, NodeRawEncoder, type NormalizedPathCommand, type ParagraphDirection, type ParsedPathCommand, type PathCommandType, type Point2D, type PositionedWord, type QuadraticBezierCommand, type RGBA, type RenderFrame, type RenderStats, type Renderer, type ResvgRenderOptions, type ResvgRenderResult, type RichCaptionGeneratorConfig, RichCaptionRenderer, type RichCaptionRendererOptions, type ShadowConfig, type ShapedLine, type ShapedWord, type ShapedWordGlyph, type ShotstackRichTextAsset, type ShotstackSvgAsset, type StrokeConfig, type StrokeSpec, type ValidAsset, type VideoEncoderCapabilities, type VideoEncoderConfig, type VideoEncoderProgress, WORD_BG_BORDER_RADIUS, WORD_BG_OPACITY, WORD_BG_PADDING_RATIO, type WordAnimationConfig, type WordAnimationState, type WordTiming, WordTimingStore, arcToCubicBeziers, breakIntoLines, calculateAnimationStatesForGroup, commandsToPathString, computeSimplePathBounds, containsRTLCharacters, createDefaultGeneratorConfig, createFrameSchedule, createNodePainter, createNodeRawEncoder, createRichCaptionRenderer, createTextEngine, createVideoEncoder, detectParagraphDirection, detectParagraphDirectionFromWords, detectPlatform, detectSubtitleFormat, extractCaptionPadding, findWordAtTime, generateRichCaptionDrawOps, generateRichCaptionFrame, generateShapePathData, getDefaultAnimationConfig, getDrawCaptionWordOps, getEncoderCapabilities, getEncoderWarning, getVisibleText, groupWordsByPause, isDrawCaptionWordOp, isRTLText, isWebCodecsH264Supported, mirrorAnimationDirection, normalizePath, normalizePathString, parseSubtitleToWords, parseSvgPath, quadraticToCubic, renderSvgAssetToPng, renderSvgToPng, reorderWordsForLine, richCaptionAssetSchema, shapeToSvgString };
|