@pixldocs/canvas-renderer 0.5.76 → 0.5.77
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 +103 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +103 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -5213,6 +5213,17 @@ function buildRoundedTrianglePath(w, h, rTop, rBR, rBL) {
|
|
|
5213
5213
|
];
|
|
5214
5214
|
return parts.join(" ");
|
|
5215
5215
|
}
|
|
5216
|
+
const roundDiag = (value) => {
|
|
5217
|
+
if (typeof value !== "number") return value;
|
|
5218
|
+
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
5219
|
+
};
|
|
5220
|
+
const stringifyDiag = (payload) => {
|
|
5221
|
+
try {
|
|
5222
|
+
return JSON.stringify(payload, (_key, value) => roundDiag(value));
|
|
5223
|
+
} catch {
|
|
5224
|
+
return String(payload);
|
|
5225
|
+
}
|
|
5226
|
+
};
|
|
5216
5227
|
function buildRoundedRectPath(w, h, tl, tr, br, bl) {
|
|
5217
5228
|
return buildRoundedRectPath$1(w, h, getRoundedRectRadii(w, h, { rxTL: tl, rxTR: tr, rxBR: br, rxBL: bl }));
|
|
5218
5229
|
}
|
|
@@ -5323,11 +5334,11 @@ function createShape(element) {
|
|
|
5323
5334
|
}
|
|
5324
5335
|
}
|
|
5325
5336
|
function createText(element) {
|
|
5326
|
-
var _a;
|
|
5337
|
+
var _a, _b;
|
|
5327
5338
|
const overflowPolicy = element.overflowPolicy || "grow-and-push";
|
|
5328
5339
|
let text = element.text || "Text";
|
|
5329
5340
|
let fontSize = element.fontSize || 16;
|
|
5330
|
-
element.minFontSize || 8;
|
|
5341
|
+
const minFontSize = element.minFontSize || 8;
|
|
5331
5342
|
const maxLines = element.maxLines || 3;
|
|
5332
5343
|
const baseWidth = element.width && element.width > 0 ? element.width : 200;
|
|
5333
5344
|
const baseHeight = element.height;
|
|
@@ -5339,6 +5350,7 @@ function createText(element) {
|
|
|
5339
5350
|
const startFontSize = fontSize;
|
|
5340
5351
|
let breakReason = "min-font-size-reached";
|
|
5341
5352
|
let lastIter = null;
|
|
5353
|
+
const iterationSamples = [];
|
|
5342
5354
|
while (fontSize > 1) {
|
|
5343
5355
|
const testTextbox = new fabric__namespace.Textbox(text, {
|
|
5344
5356
|
width: fixedWidth,
|
|
@@ -5356,7 +5368,7 @@ function createText(element) {
|
|
|
5356
5368
|
const hasNoImplicitWrap = renderedLineCount <= explicitLineCount;
|
|
5357
5369
|
const fitsHeight = !baseHeight || textHeight <= baseHeight;
|
|
5358
5370
|
const widthMetrics = getTextboxWidthFitMetrics(testTextbox, fixedWidth);
|
|
5359
|
-
const { fitsWidth } = widthMetrics;
|
|
5371
|
+
const { maxLineWidth, widthDidGrow, fitsWidth } = widthMetrics;
|
|
5360
5372
|
if (debugAutoShrink) {
|
|
5361
5373
|
lastIter = {
|
|
5362
5374
|
fontSize,
|
|
@@ -5367,8 +5379,12 @@ function createText(element) {
|
|
|
5367
5379
|
fixedWidth,
|
|
5368
5380
|
hasNoImplicitWrap,
|
|
5369
5381
|
fitsHeight,
|
|
5370
|
-
fitsWidth
|
|
5382
|
+
fitsWidth,
|
|
5383
|
+
textLines: (testTextbox.textLines || []).map((line) => Array.isArray(line) ? line.join("") : String(line ?? ""))
|
|
5371
5384
|
};
|
|
5385
|
+
if (iterationSamples.length < 6 || fontSize <= minFontSize + 2) {
|
|
5386
|
+
iterationSamples.push(lastIter);
|
|
5387
|
+
}
|
|
5372
5388
|
}
|
|
5373
5389
|
if (hasNoImplicitWrap && fitsHeight && fitsWidth) {
|
|
5374
5390
|
breakReason = "fits";
|
|
@@ -5377,10 +5393,11 @@ function createText(element) {
|
|
|
5377
5393
|
fontSize--;
|
|
5378
5394
|
}
|
|
5379
5395
|
if (debugAutoShrink) {
|
|
5380
|
-
console.log("[auto-shrink][diag]"
|
|
5396
|
+
console.log("[auto-shrink][diag] " + stringifyDiag({
|
|
5381
5397
|
id: element.id,
|
|
5382
5398
|
name: element.name,
|
|
5383
|
-
text,
|
|
5399
|
+
text: text.slice(0, 180),
|
|
5400
|
+
textLength: text.length,
|
|
5384
5401
|
fontFamily: element.fontFamily,
|
|
5385
5402
|
fontWeight: element.fontWeight,
|
|
5386
5403
|
elementWidth: element.width,
|
|
@@ -5392,10 +5409,11 @@ function createText(element) {
|
|
|
5392
5409
|
startFontSize,
|
|
5393
5410
|
finalFontSize: fontSize,
|
|
5394
5411
|
breakReason,
|
|
5412
|
+
iterations: iterationSamples,
|
|
5395
5413
|
lastIter,
|
|
5396
5414
|
fontCheckRegular: typeof document !== "undefined" && document.fonts ? document.fonts.check(`16px "${element.fontFamily || "Open Sans"}"`) : null,
|
|
5397
5415
|
fontCheckBold: typeof document !== "undefined" && document.fonts ? document.fonts.check(`bold 16px "${element.fontFamily || "Open Sans"}"`) : null
|
|
5398
|
-
});
|
|
5416
|
+
}));
|
|
5399
5417
|
}
|
|
5400
5418
|
}
|
|
5401
5419
|
if (overflowPolicy === "max-lines-ellipsis") {
|
|
@@ -5470,6 +5488,22 @@ function createText(element) {
|
|
|
5470
5488
|
textbox.setCoords();
|
|
5471
5489
|
}
|
|
5472
5490
|
textbox.dirty = true;
|
|
5491
|
+
if (overflowPolicy === "auto-shrink" && typeof window !== "undefined" && window.__pixldocsDebugAutoShrink === true) {
|
|
5492
|
+
console.log("[auto-shrink][final-textbox] " + stringifyDiag({
|
|
5493
|
+
id: element.id,
|
|
5494
|
+
name: element.name,
|
|
5495
|
+
text: text.slice(0, 180),
|
|
5496
|
+
targetWidth,
|
|
5497
|
+
targetScaleX,
|
|
5498
|
+
targetScaleY,
|
|
5499
|
+
finalFontSize: fontSize,
|
|
5500
|
+
textboxWidth: textbox.width,
|
|
5501
|
+
textboxHeight: textbox.height,
|
|
5502
|
+
lineCount: ((_b = textbox.textLines) == null ? void 0 : _b.length) || 0,
|
|
5503
|
+
lines: (textbox.textLines || []).map((line) => Array.isArray(line) ? line.join("") : String(line ?? "")),
|
|
5504
|
+
widthMetrics: getTextboxWidthFitMetrics(textbox, targetWidth)
|
|
5505
|
+
}));
|
|
5506
|
+
}
|
|
5473
5507
|
applyTextBackground(textbox, extractTextBgConfig(element));
|
|
5474
5508
|
const shadow = buildTextShadow(element);
|
|
5475
5509
|
if (shadow) textbox.set("shadow", shadow);
|
|
@@ -12553,7 +12587,18 @@ function PixldocsPreview(props) {
|
|
|
12553
12587
|
!canvasSettled && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) })
|
|
12554
12588
|
] });
|
|
12555
12589
|
}
|
|
12556
|
-
const PACKAGE_VERSION = "0.5.
|
|
12590
|
+
const PACKAGE_VERSION = "0.5.77";
|
|
12591
|
+
const roundParityValue = (value) => {
|
|
12592
|
+
if (typeof value !== "number") return value;
|
|
12593
|
+
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
12594
|
+
};
|
|
12595
|
+
function logJsonLine(tag, payload) {
|
|
12596
|
+
try {
|
|
12597
|
+
console.log(`${tag} ${JSON.stringify(payload, (_key, value) => roundParityValue(value))}`);
|
|
12598
|
+
} catch {
|
|
12599
|
+
console.log(tag, payload);
|
|
12600
|
+
}
|
|
12601
|
+
}
|
|
12557
12602
|
let __underlineFixInstalled = false;
|
|
12558
12603
|
function installUnderlineFix(fab) {
|
|
12559
12604
|
var _a;
|
|
@@ -13429,6 +13474,42 @@ class PixldocsRenderer {
|
|
|
13429
13474
|
}
|
|
13430
13475
|
return null;
|
|
13431
13476
|
}
|
|
13477
|
+
logFabricTextParitySnapshot(stage, fabricInstance) {
|
|
13478
|
+
var _a;
|
|
13479
|
+
if (typeof window === "undefined" || window.__pixldocsDebugAutoShrink !== true) return;
|
|
13480
|
+
const sample = [];
|
|
13481
|
+
const visit = (obj, groupPath = "") => {
|
|
13482
|
+
var _a2;
|
|
13483
|
+
if (!obj) return;
|
|
13484
|
+
if (obj instanceof fabric__namespace.Textbox) {
|
|
13485
|
+
const lineWidths = getCanvasMeasuredTextboxLineWidths(obj);
|
|
13486
|
+
sample.push({
|
|
13487
|
+
id: getObjectId(obj),
|
|
13488
|
+
groupPath,
|
|
13489
|
+
text: String(obj.text ?? "").slice(0, 180),
|
|
13490
|
+
left: obj.left,
|
|
13491
|
+
top: obj.top,
|
|
13492
|
+
width: obj.width,
|
|
13493
|
+
height: obj.height,
|
|
13494
|
+
scaleX: obj.scaleX,
|
|
13495
|
+
scaleY: obj.scaleY,
|
|
13496
|
+
fontSize: obj.fontSize,
|
|
13497
|
+
fontFamily: obj.fontFamily,
|
|
13498
|
+
fontWeight: obj.fontWeight,
|
|
13499
|
+
lineCount: ((_a2 = obj.textLines) == null ? void 0 : _a2.length) || 0,
|
|
13500
|
+
lines: (obj.textLines || []).map((line) => Array.isArray(line) ? line.join("") : String(line ?? "")),
|
|
13501
|
+
lineWidths,
|
|
13502
|
+
maxLineWidth: lineWidths.length ? Math.max(...lineWidths) : 0
|
|
13503
|
+
});
|
|
13504
|
+
}
|
|
13505
|
+
if (obj instanceof fabric__namespace.Group && typeof obj.getObjects === "function") {
|
|
13506
|
+
const nextPath = [groupPath, getObjectId(obj) || obj.type || "group"].filter(Boolean).join("/");
|
|
13507
|
+
obj.getObjects().forEach((child) => visit(child, nextPath));
|
|
13508
|
+
}
|
|
13509
|
+
};
|
|
13510
|
+
(_a = fabricInstance == null ? void 0 : fabricInstance.getObjects) == null ? void 0 : _a.call(fabricInstance).forEach((obj) => visit(obj));
|
|
13511
|
+
logJsonLine("[canvas-renderer][fabric-text-parity]", { stage, textboxes: sample.length, sample });
|
|
13512
|
+
}
|
|
13432
13513
|
async waitForStableTextMetrics(container, config) {
|
|
13433
13514
|
var _a, _b, _c;
|
|
13434
13515
|
if (typeof document !== "undefined") {
|
|
@@ -13437,6 +13518,7 @@ class PixldocsRenderer {
|
|
|
13437
13518
|
}
|
|
13438
13519
|
const fabricInstance = this.getFabricCanvasFromContainer(container);
|
|
13439
13520
|
if (!(fabricInstance == null ? void 0 : fabricInstance.getObjects)) return;
|
|
13521
|
+
this.logFabricTextParitySnapshot("before-stable-text-metrics", fabricInstance);
|
|
13440
13522
|
const waitForPaint = () => new Promise((r) => requestAnimationFrame(() => requestAnimationFrame(() => r())));
|
|
13441
13523
|
const primeCharBounds = (obj) => {
|
|
13442
13524
|
if (obj instanceof fabric__namespace.Textbox) {
|
|
@@ -13463,6 +13545,7 @@ class PixldocsRenderer {
|
|
|
13463
13545
|
await waitForPaint();
|
|
13464
13546
|
(_c = fabricInstance.renderAll) == null ? void 0 : _c.call(fabricInstance);
|
|
13465
13547
|
await waitForPaint();
|
|
13548
|
+
this.logFabricTextParitySnapshot("after-stable-text-metrics", fabricInstance);
|
|
13466
13549
|
}
|
|
13467
13550
|
}
|
|
13468
13551
|
const FONT_WEIGHT_LABELS = {
|
|
@@ -14284,6 +14367,16 @@ const pdfFonts = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
|
|
|
14284
14367
|
resolveFontWeight,
|
|
14285
14368
|
rewriteSvgFontsForJsPDF
|
|
14286
14369
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
14370
|
+
function logParityJson(tag, stage, payload) {
|
|
14371
|
+
try {
|
|
14372
|
+
console.log(`${tag} ${stage} ${JSON.stringify(payload, (_key, value) => {
|
|
14373
|
+
if (typeof value !== "number") return value;
|
|
14374
|
+
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
14375
|
+
})}`);
|
|
14376
|
+
} catch {
|
|
14377
|
+
console.log(`${tag} ${stage}`, payload);
|
|
14378
|
+
}
|
|
14379
|
+
}
|
|
14287
14380
|
function dumpSvgTextDiagnostics(svgStr, pageIndex, tag, stage, maxItems = 30) {
|
|
14288
14381
|
try {
|
|
14289
14382
|
if (typeof DOMParser === "undefined") return;
|
|
@@ -14306,7 +14399,7 @@ function dumpSvgTextDiagnostics(svgStr, pageIndex, tag, stage, maxItems = 30) {
|
|
|
14306
14399
|
svgViewBox,
|
|
14307
14400
|
textCount: texts.length
|
|
14308
14401
|
};
|
|
14309
|
-
|
|
14402
|
+
logParityJson(tag, stage, { kind: "summary", ...summary });
|
|
14310
14403
|
const sample = texts.slice(0, maxItems).map((t, idx) => {
|
|
14311
14404
|
var _a, _b;
|
|
14312
14405
|
const tspans = Array.from(t.querySelectorAll("tspan"));
|
|
@@ -14338,7 +14431,7 @@ function dumpSvgTextDiagnostics(svgStr, pageIndex, tag, stage, maxItems = 30) {
|
|
|
14338
14431
|
tspanSample: tspanInfo
|
|
14339
14432
|
};
|
|
14340
14433
|
});
|
|
14341
|
-
|
|
14434
|
+
logParityJson(tag, stage, { kind: "text-sample", page: pageIndex, count: sample.length, total: texts.length, sample });
|
|
14342
14435
|
} catch (err) {
|
|
14343
14436
|
console.warn(`${tag} ${stage} page=${pageIndex} dump threw`, err);
|
|
14344
14437
|
}
|