@fieldnotes/core 0.40.0 → 0.40.1

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
@@ -4765,6 +4765,16 @@ function renderStyledRuns(ctx, runs, startX, startY, maxWidth) {
4765
4765
  }
4766
4766
  }
4767
4767
 
4768
+ // src/canvas/text-canvas-renderer.ts
4769
+ function renderTextOnCanvas(ctx, text) {
4770
+ const pad = 2;
4771
+ ctx.save();
4772
+ ctx.fillStyle = text.color;
4773
+ const runs = parseStyledRuns(text.text ?? "", text.fontSize);
4774
+ renderStyledRuns(ctx, runs, text.position.x + pad, text.position.y + pad, text.size.w - pad * 2);
4775
+ ctx.restore();
4776
+ }
4777
+
4768
4778
  // src/canvas/export-image.ts
4769
4779
  var center = (b) => ({ x: b.x + b.w / 2, y: b.y + b.h / 2 });
4770
4780
  function getStrokeBounds(el) {
@@ -4847,30 +4857,6 @@ function computeBounds(elements, padding) {
4847
4857
  h: maxY - minY + padding * 2
4848
4858
  };
4849
4859
  }
4850
- function renderTextOnCanvas(ctx, text) {
4851
- if (!text.text) return;
4852
- ctx.save();
4853
- ctx.fillStyle = text.color;
4854
- ctx.font = `${text.fontSize}px system-ui, sans-serif`;
4855
- ctx.textBaseline = "top";
4856
- ctx.textAlign = text.textAlign;
4857
- const pad = 2;
4858
- let textX = text.position.x + pad;
4859
- if (text.textAlign === "center") {
4860
- textX = text.position.x + text.size.w / 2;
4861
- } else if (text.textAlign === "right") {
4862
- textX = text.position.x + text.size.w - pad;
4863
- }
4864
- const lineHeight = text.fontSize * 1.4;
4865
- const lines = text.text.split("\n");
4866
- for (let i = 0; i < lines.length; i++) {
4867
- const line = lines[i];
4868
- if (line !== void 0) {
4869
- ctx.fillText(line, textX, text.position.y + pad + i * lineHeight);
4870
- }
4871
- }
4872
- ctx.restore();
4873
- }
4874
4860
  function renderGridForBounds(ctx, grid, bounds) {
4875
4861
  const visibleBounds = {
4876
4862
  minX: bounds.x,
@@ -5092,28 +5078,27 @@ function emitImage(image, dataUri) {
5092
5078
  const { w, h } = image.size;
5093
5079
  return `<image href="${esc(href)}" x="${n(x)}" y="${n(y)}" width="${n(w)}" height="${n(h)}" />`;
5094
5080
  }
5095
- function emitText(text) {
5081
+ function emitText(text, rasterScale) {
5096
5082
  if (!text.text) return "";
5097
- const pad = 2;
5098
- let anchor = "start";
5099
- let textX = text.position.x + pad;
5100
- if (text.textAlign === "center") {
5101
- anchor = "middle";
5102
- textX = text.position.x + text.size.w / 2;
5103
- } else if (text.textAlign === "right") {
5104
- anchor = "end";
5105
- textX = text.position.x + text.size.w - pad;
5106
- }
5107
- const lineHeight = text.fontSize * 1.4;
5108
- const lines = text.text.split("\n");
5109
- let out = "";
5110
- for (let i = 0; i < lines.length; i++) {
5111
- const line = lines[i];
5112
- if (line === void 0) continue;
5113
- const y = text.position.y + pad + i * lineHeight;
5114
- out += `<text x="${n(textX)}" y="${n(y)}" font-family="system-ui, sans-serif" font-size="${n(text.fontSize)}" fill="${esc(text.color)}" text-anchor="${anchor}" dominant-baseline="text-before-edge">${esc(line)}</text>`;
5083
+ const { x, y } = text.position;
5084
+ const { w, h } = text.size;
5085
+ if (typeof document === "undefined") return "";
5086
+ const canvas = document.createElement("canvas");
5087
+ canvas.width = Math.max(1, Math.ceil(w * rasterScale));
5088
+ canvas.height = Math.max(1, Math.ceil(h * rasterScale));
5089
+ const ctx = canvas.getContext("2d");
5090
+ if (!ctx) return "";
5091
+ ctx.scale(rasterScale, rasterScale);
5092
+ ctx.translate(-x, -y);
5093
+ renderTextOnCanvas(ctx, text);
5094
+ let dataUri;
5095
+ try {
5096
+ dataUri = canvas.toDataURL();
5097
+ } catch {
5098
+ return "";
5115
5099
  }
5116
- return out;
5100
+ if (!dataUri || !dataUri.startsWith("data:")) return "";
5101
+ return `<image href="${esc(dataUri)}" x="${n(x)}" y="${n(y)}" width="${n(w)}" height="${n(h)}" />`;
5117
5102
  }
5118
5103
  function emitNote(note, rasterScale) {
5119
5104
  const { x, y } = note.position;
@@ -5296,7 +5281,7 @@ function emitElement(el, imageDataUris, rasterScale, firstGrid, store) {
5296
5281
  case "image":
5297
5282
  return withRotationSvg(el, emitImage(el, imageDataUris.get(el.id)));
5298
5283
  case "text":
5299
- return withRotationSvg(el, emitText(el));
5284
+ return withRotationSvg(el, emitText(el, rasterScale));
5300
5285
  case "note":
5301
5286
  return withRotationSvg(el, emitNote(el, rasterScale));
5302
5287
  case "template":
@@ -5759,10 +5744,9 @@ var DomNodeManager = class {
5759
5744
  cursor: "default",
5760
5745
  userSelect: "none",
5761
5746
  wordWrap: "break-word",
5762
- whiteSpace: "pre-wrap",
5763
5747
  lineHeight: "1.4"
5764
5748
  });
5765
- node.textContent = element.text || "";
5749
+ node.innerHTML = element.text || "";
5766
5750
  const detector = new DoubleTapDetector();
5767
5751
  node.addEventListener("pointerup", (e) => {
5768
5752
  if (detector.feed(e)) {
@@ -5773,8 +5757,9 @@ var DomNodeManager = class {
5773
5757
  });
5774
5758
  }
5775
5759
  if (!this.isEditingElement(element.id)) {
5776
- if (node.textContent !== element.text) {
5777
- node.textContent = element.text || "";
5760
+ const text = element.text || "";
5761
+ if (node.innerHTML !== text) {
5762
+ node.innerHTML = text;
5778
5763
  }
5779
5764
  Object.assign(node.style, {
5780
5765
  fontSize: `${element.fontSize}px`,
@@ -9752,7 +9737,7 @@ var LaserTool = class {
9752
9737
  };
9753
9738
 
9754
9739
  // src/index.ts
9755
- var VERSION = "0.40.0";
9740
+ var VERSION = "0.40.1";
9756
9741
  // Annotate the CommonJS export names for ESM import in node:
9757
9742
  0 && (module.exports = {
9758
9743
  ArrowTool,