@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.d.ts CHANGED
@@ -254,7 +254,7 @@ export declare function normalizeFontFamily(fontStack: string): string;
254
254
  * Package version banner. Bump alongside package.json so we can confirm
255
255
  * (via browser:log) that the deployed bundle matches the expected build.
256
256
  */
257
- export declare const PACKAGE_VERSION = "0.5.57";
257
+ export declare const PACKAGE_VERSION = "0.5.59";
258
258
 
259
259
  export declare interface PageSettings {
260
260
  backgroundColor?: string;
package/dist/index.js CHANGED
@@ -245,6 +245,57 @@ const WIDTH_BUCKET_PX = 8;
245
245
  function bucketWidth(w) {
246
246
  return Math.round(w / WIDTH_BUCKET_PX) * WIDTH_BUCKET_PX;
247
247
  }
248
+ let measureCanvas = null;
249
+ function getMeasureContext() {
250
+ if (typeof document === "undefined") return null;
251
+ measureCanvas ?? (measureCanvas = document.createElement("canvas"));
252
+ return measureCanvas.getContext("2d");
253
+ }
254
+ function lineToString(line) {
255
+ return Array.isArray(line) ? line.join("") : String(line ?? "");
256
+ }
257
+ function measureTextLineWithCanvas(textbox, lineText, lineIndex) {
258
+ var _a, _b, _c, _d, _e;
259
+ if (!lineText) return 0;
260
+ const ctx = getMeasureContext();
261
+ if (!ctx) return null;
262
+ const tb = textbox;
263
+ const fontSize = Number(((_a = tb.getValueOfPropertyAt) == null ? void 0 : _a.call(tb, lineIndex, 0, "fontSize")) ?? textbox.fontSize ?? 16);
264
+ const fontStyle = String(((_b = tb.getValueOfPropertyAt) == null ? void 0 : _b.call(tb, lineIndex, 0, "fontStyle")) ?? textbox.fontStyle ?? "normal");
265
+ const fontWeight = String(((_c = tb.getValueOfPropertyAt) == null ? void 0 : _c.call(tb, lineIndex, 0, "fontWeight")) ?? textbox.fontWeight ?? "400");
266
+ const fontFamily = String(((_d = tb.getValueOfPropertyAt) == null ? void 0 : _d.call(tb, lineIndex, 0, "fontFamily")) ?? textbox.fontFamily ?? "Open Sans");
267
+ const charSpacing = Number(((_e = tb.getValueOfPropertyAt) == null ? void 0 : _e.call(tb, lineIndex, 0, "charSpacing")) ?? textbox.charSpacing ?? 0);
268
+ ctx.save();
269
+ ctx.font = `${fontStyle} normal ${fontWeight} ${fontSize}px ${fontFamily}`;
270
+ const measured = ctx.measureText(lineText).width;
271
+ ctx.restore();
272
+ const graphemeCount = Array.from(lineText).length;
273
+ const spacingWidth = graphemeCount > 1 ? charSpacing / 1e3 * fontSize * (graphemeCount - 1) : 0;
274
+ return Math.max(0, measured + spacingWidth);
275
+ }
276
+ function getCanvasMeasuredTextboxLineWidths(textbox) {
277
+ const rawLines = textbox._textLines ?? textbox.textLines ?? [];
278
+ const fallback = textbox.__lineWidths ?? [];
279
+ if (!rawLines.length) return fallback;
280
+ const measured = rawLines.map((line, index) => measureTextLineWithCanvas(textbox, lineToString(line), index));
281
+ if (measured.some((w) => w == null || Number.isNaN(w))) return fallback;
282
+ return measured;
283
+ }
284
+ function getTextboxWidthFitMetrics(textbox, targetWidth) {
285
+ const actualTextboxWidth = Number(textbox.width ?? targetWidth);
286
+ const dynamicMinWidth = Number(textbox.dynamicMinWidth ?? 0);
287
+ const lineWidths = getCanvasMeasuredTextboxLineWidths(textbox);
288
+ const maxLineWidth = lineWidths.length > 0 ? Math.max(...lineWidths) : 0;
289
+ const grownWidth = Math.max(actualTextboxWidth, dynamicMinWidth);
290
+ const widthDidGrow = grownWidth > targetWidth + 0.5;
291
+ return {
292
+ actualTextboxWidth,
293
+ dynamicMinWidth,
294
+ maxLineWidth,
295
+ widthDidGrow,
296
+ fitsWidth: !widthDidGrow && maxLineWidth <= targetWidth + 1
297
+ };
298
+ }
248
299
  function getCacheKey(element) {
249
300
  const widthPx = typeof element.width === "number" ? element.width : 200;
250
301
  return JSON.stringify({
@@ -301,11 +352,7 @@ function measureTextHeight(element) {
301
352
  const renderedLineCount = ((_a = testTb.textLines) == null ? void 0 : _a.length) || 1;
302
353
  const hasNoImplicitWrap = renderedLineCount <= explicitLineCount;
303
354
  const fitsHeight = !baseHeight || textHeight <= baseHeight;
304
- const actualTextboxWidth = testTb.width ?? measureWidth;
305
- const widthDidGrow = actualTextboxWidth > measureWidth + 0.5;
306
- const lineWidths = testTb.__lineWidths;
307
- const maxLineWidth = lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : 0;
308
- const fitsWidth = !widthDidGrow && maxLineWidth <= measureWidth + 1;
355
+ const { fitsWidth } = getTextboxWidthFitMetrics(testTb, measureWidth);
309
356
  if (hasNoImplicitWrap && fitsHeight && fitsWidth) break;
310
357
  fontSize--;
311
358
  }
@@ -5290,20 +5337,16 @@ function createText(element) {
5290
5337
  const renderedLineCount = ((_a = testTextbox.textLines) == null ? void 0 : _a.length) || 1;
5291
5338
  const hasNoImplicitWrap = renderedLineCount <= explicitLineCount;
5292
5339
  const fitsHeight = !baseHeight || textHeight <= baseHeight;
5293
- const actualTextboxWidth = testTextbox.width ?? fixedWidth;
5294
- const widthDidGrow = actualTextboxWidth > fixedWidth + 0.5;
5295
- const lineWidths = testTextbox.__lineWidths;
5296
- const maxLineWidth = lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : 0;
5297
- const fitsWidth = !widthDidGrow && maxLineWidth <= fixedWidth + 1;
5340
+ const widthMetrics = getTextboxWidthFitMetrics(testTextbox, fixedWidth);
5341
+ const { fitsWidth } = widthMetrics;
5298
5342
  if (debugAutoShrink) {
5299
5343
  lastIter = {
5300
5344
  fontSize,
5301
5345
  renderedLineCount,
5302
5346
  explicitLineCount,
5303
5347
  textHeight,
5304
- maxLineWidth,
5348
+ ...widthMetrics,
5305
5349
  fixedWidth,
5306
- widthDidGrow,
5307
5350
  hasNoImplicitWrap,
5308
5351
  fitsHeight,
5309
5352
  fitsWidth
@@ -8854,11 +8897,7 @@ const PageCanvas = forwardRef(
8854
8897
  const renderedLineCount = ((_b = testTextbox.textLines) == null ? void 0 : _b.length) || 1;
8855
8898
  const hasNoImplicitWrap = renderedLineCount <= explicitLineCount;
8856
8899
  const fitsHeight = rH <= 0 || textHeight <= rH;
8857
- const actualTextboxWidth = testTextbox.width ?? fixedWidth;
8858
- const widthDidGrow = actualTextboxWidth > fixedWidth + 0.5;
8859
- const lineWidths = testTextbox.__lineWidths;
8860
- const maxLineWidth = lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : 0;
8861
- const fitsWidth = !widthDidGrow && maxLineWidth <= fixedWidth + 1;
8900
+ const { fitsWidth } = getTextboxWidthFitMetrics(testTextbox, fixedWidth);
8862
8901
  if (hasNoImplicitWrap && fitsHeight && fitsWidth) {
8863
8902
  break;
8864
8903
  }
@@ -12504,7 +12543,7 @@ function PixldocsPreview(props) {
12504
12543
  !canvasSettled && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) })
12505
12544
  ] });
12506
12545
  }
12507
- const PACKAGE_VERSION = "0.5.57";
12546
+ const PACKAGE_VERSION = "0.5.59";
12508
12547
  let __underlineFixInstalled = false;
12509
12548
  function installUnderlineFix(fab) {
12510
12549
  var _a;
@@ -15183,8 +15222,8 @@ async function convertTextDecorationsToLines(svg) {
15183
15222
  let ctx = null;
15184
15223
  try {
15185
15224
  const realDoc = typeof document !== "undefined" ? document : doc;
15186
- const measureCanvas = realDoc.createElement("canvas");
15187
- ctx = measureCanvas.getContext("2d");
15225
+ const measureCanvas2 = realDoc.createElement("canvas");
15226
+ ctx = measureCanvas2.getContext("2d");
15188
15227
  } catch {
15189
15228
  }
15190
15229
  const textEls = Array.from(svg.querySelectorAll("text"));