@pixldocs/canvas-renderer 0.5.58 → 0.5.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -264,6 +264,57 @@ const WIDTH_BUCKET_PX = 8;
264
264
  function bucketWidth(w) {
265
265
  return Math.round(w / WIDTH_BUCKET_PX) * WIDTH_BUCKET_PX;
266
266
  }
267
+ let measureCanvas = null;
268
+ function getMeasureContext() {
269
+ if (typeof document === "undefined") return null;
270
+ measureCanvas ?? (measureCanvas = document.createElement("canvas"));
271
+ return measureCanvas.getContext("2d");
272
+ }
273
+ function lineToString(line) {
274
+ return Array.isArray(line) ? line.join("") : String(line ?? "");
275
+ }
276
+ function measureTextLineWithCanvas(textbox, lineText, lineIndex) {
277
+ var _a, _b, _c, _d, _e;
278
+ if (!lineText) return 0;
279
+ const ctx = getMeasureContext();
280
+ if (!ctx) return null;
281
+ const tb = textbox;
282
+ const fontSize = Number(((_a = tb.getValueOfPropertyAt) == null ? void 0 : _a.call(tb, lineIndex, 0, "fontSize")) ?? textbox.fontSize ?? 16);
283
+ const fontStyle = String(((_b = tb.getValueOfPropertyAt) == null ? void 0 : _b.call(tb, lineIndex, 0, "fontStyle")) ?? textbox.fontStyle ?? "normal");
284
+ const fontWeight = String(((_c = tb.getValueOfPropertyAt) == null ? void 0 : _c.call(tb, lineIndex, 0, "fontWeight")) ?? textbox.fontWeight ?? "400");
285
+ const fontFamily = String(((_d = tb.getValueOfPropertyAt) == null ? void 0 : _d.call(tb, lineIndex, 0, "fontFamily")) ?? textbox.fontFamily ?? "Open Sans");
286
+ const charSpacing = Number(((_e = tb.getValueOfPropertyAt) == null ? void 0 : _e.call(tb, lineIndex, 0, "charSpacing")) ?? textbox.charSpacing ?? 0);
287
+ ctx.save();
288
+ ctx.font = `${fontStyle} normal ${fontWeight} ${fontSize}px ${fontFamily}`;
289
+ const measured = ctx.measureText(lineText).width;
290
+ ctx.restore();
291
+ const graphemeCount = Array.from(lineText).length;
292
+ const spacingWidth = graphemeCount > 1 ? charSpacing / 1e3 * fontSize * (graphemeCount - 1) : 0;
293
+ return Math.max(0, measured + spacingWidth);
294
+ }
295
+ function getCanvasMeasuredTextboxLineWidths(textbox) {
296
+ const rawLines = textbox._textLines ?? textbox.textLines ?? [];
297
+ const fallback = textbox.__lineWidths ?? [];
298
+ if (!rawLines.length) return fallback;
299
+ const measured = rawLines.map((line, index) => measureTextLineWithCanvas(textbox, lineToString(line), index));
300
+ if (measured.some((w) => w == null || Number.isNaN(w))) return fallback;
301
+ return measured;
302
+ }
303
+ function getTextboxWidthFitMetrics(textbox, targetWidth) {
304
+ const actualTextboxWidth = Number(textbox.width ?? targetWidth);
305
+ const dynamicMinWidth = Number(textbox.dynamicMinWidth ?? 0);
306
+ const lineWidths = getCanvasMeasuredTextboxLineWidths(textbox);
307
+ const maxLineWidth = lineWidths.length > 0 ? Math.max(...lineWidths) : 0;
308
+ const grownWidth = Math.max(actualTextboxWidth, dynamicMinWidth);
309
+ const widthDidGrow = grownWidth > targetWidth + 0.5;
310
+ return {
311
+ actualTextboxWidth,
312
+ dynamicMinWidth,
313
+ maxLineWidth,
314
+ widthDidGrow,
315
+ fitsWidth: !widthDidGrow && maxLineWidth <= targetWidth + 1
316
+ };
317
+ }
267
318
  function getCacheKey(element) {
268
319
  const widthPx = typeof element.width === "number" ? element.width : 200;
269
320
  return JSON.stringify({
@@ -320,11 +371,7 @@ function measureTextHeight(element) {
320
371
  const renderedLineCount = ((_a = testTb.textLines) == null ? void 0 : _a.length) || 1;
321
372
  const hasNoImplicitWrap = renderedLineCount <= explicitLineCount;
322
373
  const fitsHeight = !baseHeight || textHeight <= baseHeight;
323
- const actualTextboxWidth = testTb.width ?? measureWidth;
324
- const widthDidGrow = actualTextboxWidth > measureWidth + 0.5;
325
- const lineWidths = testTb.__lineWidths;
326
- const maxLineWidth = lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : 0;
327
- const fitsWidth = !widthDidGrow && maxLineWidth <= measureWidth + 1;
374
+ const { fitsWidth } = getTextboxWidthFitMetrics(testTb, measureWidth);
328
375
  if (hasNoImplicitWrap && fitsHeight && fitsWidth) break;
329
376
  fontSize--;
330
377
  }
@@ -5309,20 +5356,16 @@ function createText(element) {
5309
5356
  const renderedLineCount = ((_a = testTextbox.textLines) == null ? void 0 : _a.length) || 1;
5310
5357
  const hasNoImplicitWrap = renderedLineCount <= explicitLineCount;
5311
5358
  const fitsHeight = !baseHeight || textHeight <= baseHeight;
5312
- const actualTextboxWidth = testTextbox.width ?? fixedWidth;
5313
- const widthDidGrow = actualTextboxWidth > fixedWidth + 0.5;
5314
- const lineWidths = testTextbox.__lineWidths;
5315
- const maxLineWidth = lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : 0;
5316
- const fitsWidth = !widthDidGrow && maxLineWidth <= fixedWidth + 1;
5359
+ const widthMetrics = getTextboxWidthFitMetrics(testTextbox, fixedWidth);
5360
+ const { fitsWidth } = widthMetrics;
5317
5361
  if (debugAutoShrink) {
5318
5362
  lastIter = {
5319
5363
  fontSize,
5320
5364
  renderedLineCount,
5321
5365
  explicitLineCount,
5322
5366
  textHeight,
5323
- maxLineWidth,
5367
+ ...widthMetrics,
5324
5368
  fixedWidth,
5325
- widthDidGrow,
5326
5369
  hasNoImplicitWrap,
5327
5370
  fitsHeight,
5328
5371
  fitsWidth
@@ -8873,11 +8916,7 @@ const PageCanvas = react.forwardRef(
8873
8916
  const renderedLineCount = ((_b = testTextbox.textLines) == null ? void 0 : _b.length) || 1;
8874
8917
  const hasNoImplicitWrap = renderedLineCount <= explicitLineCount;
8875
8918
  const fitsHeight = rH <= 0 || textHeight <= rH;
8876
- const actualTextboxWidth = testTextbox.width ?? fixedWidth;
8877
- const widthDidGrow = actualTextboxWidth > fixedWidth + 0.5;
8878
- const lineWidths = testTextbox.__lineWidths;
8879
- const maxLineWidth = lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : 0;
8880
- const fitsWidth = !widthDidGrow && maxLineWidth <= fixedWidth + 1;
8919
+ const { fitsWidth } = getTextboxWidthFitMetrics(testTextbox, fixedWidth);
8881
8920
  if (hasNoImplicitWrap && fitsHeight && fitsWidth) {
8882
8921
  break;
8883
8922
  }
@@ -12523,7 +12562,7 @@ function PixldocsPreview(props) {
12523
12562
  !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..." }) })
12524
12563
  ] });
12525
12564
  }
12526
- const PACKAGE_VERSION = "0.5.57";
12565
+ const PACKAGE_VERSION = "0.5.59";
12527
12566
  let __underlineFixInstalled = false;
12528
12567
  function installUnderlineFix(fab) {
12529
12568
  var _a;
@@ -15202,8 +15241,8 @@ async function convertTextDecorationsToLines(svg) {
15202
15241
  let ctx = null;
15203
15242
  try {
15204
15243
  const realDoc = typeof document !== "undefined" ? document : doc;
15205
- const measureCanvas = realDoc.createElement("canvas");
15206
- ctx = measureCanvas.getContext("2d");
15244
+ const measureCanvas2 = realDoc.createElement("canvas");
15245
+ ctx = measureCanvas2.getContext("2d");
15207
15246
  } catch {
15208
15247
  }
15209
15248
  const textEls = Array.from(svg.querySelectorAll("text"));