@pixldocs/canvas-renderer 0.5.43 → 0.5.44

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
@@ -4908,40 +4908,107 @@ function applyTextBackground(obj, cfg) {
4908
4908
  const originalToSVG = (_a = obj.toSVG) == null ? void 0 : _a.bind(obj);
4909
4909
  if (typeof originalToSVG === "function") {
4910
4910
  obj.toSVG = function(reviver) {
4911
- const svg = originalToSVG(reviver);
4911
+ let svg = originalToSVG(reviver);
4912
4912
  const bg = this[PD_BG_KEY];
4913
- if (!hasTextBackground(bg)) return svg;
4913
+ const shadow = this.shadow;
4914
+ const hasBg = hasTextBackground(bg);
4915
+ const hasShadow = !!shadow && !!shadow.color && shadow.color !== "transparent";
4916
+ if (!hasBg && !hasShadow) return svg;
4914
4917
  const w = this.width ?? 0;
4915
4918
  const h = this.height ?? 0;
4916
- const pT = Math.max(0, Number(bg.padTop ?? 0));
4917
- const pR = Math.max(0, Number(bg.padRight ?? 0));
4918
- const pB = Math.max(0, Number(bg.padBottom ?? 0));
4919
- const pL = Math.max(0, Number(bg.padLeft ?? 0));
4919
+ const pT = Math.max(0, Number((bg == null ? void 0 : bg.padTop) ?? 0));
4920
+ const pR = Math.max(0, Number((bg == null ? void 0 : bg.padRight) ?? 0));
4921
+ const pB = Math.max(0, Number((bg == null ? void 0 : bg.padBottom) ?? 0));
4922
+ const pL = Math.max(0, Number((bg == null ? void 0 : bg.padLeft) ?? 0));
4920
4923
  const x = -w / 2 - pL;
4921
4924
  const y = -h / 2 - pT;
4922
4925
  const bgW = w + pL + pR;
4923
4926
  const bgH = h + pT + pB;
4924
- const d = buildRoundedRectPathD(
4927
+ const bgD = buildRoundedRectPathD(
4925
4928
  x,
4926
4929
  y,
4927
4930
  bgW,
4928
4931
  bgH,
4929
- bg.rxTL ?? 0,
4930
- bg.rxTR ?? 0,
4931
- bg.rxBR ?? 0,
4932
- bg.rxBL ?? 0
4932
+ (bg == null ? void 0 : bg.rxTL) ?? 0,
4933
+ (bg == null ? void 0 : bg.rxTR) ?? 0,
4934
+ (bg == null ? void 0 : bg.rxBR) ?? 0,
4935
+ (bg == null ? void 0 : bg.rxBL) ?? 0
4933
4936
  );
4934
- const fill = bg.color;
4935
- const bgPath = `<path d="${d}" fill="${escapeXmlAttr(fill)}" />`;
4937
+ const bgFill = (bg == null ? void 0 : bg.color) || "";
4938
+ const bgPath = hasBg ? `<path d="${bgD}" fill="${escapeXmlAttr(bgFill)}" />` : "";
4939
+ svg = svg.replace(/style="[^"]*filter:\s*url\([^)]+\)[^"]*"/i, "");
4940
+ svg = svg.replace(/<filter[\s\S]*?<\/filter>/gi, "");
4941
+ let shadowLayer = "";
4942
+ if (hasShadow) {
4943
+ const ox = Number(shadow.offsetX ?? 0) || 0;
4944
+ const oy = Number(shadow.offsetY ?? 0) || 0;
4945
+ const blur = Math.max(0, Number(shadow.blur ?? 0));
4946
+ const shadowColor = String(shadow.color);
4947
+ const shadowBgPath = hasBg ? `<path d="${bgD}" fill="${escapeXmlAttr(shadowColor)}" />` : "";
4948
+ const inner = extractGInnerMarkup(svg);
4949
+ const recoloredText = recolorSvgFills(inner, shadowColor);
4950
+ const layers = [];
4951
+ if (blur > 0) {
4952
+ const ringCount = Math.min(6, Math.max(2, Math.round(blur / 2)));
4953
+ for (let i = 1; i <= ringCount; i++) {
4954
+ const t = i / ringCount;
4955
+ const dist = blur * t * 0.6;
4956
+ const op = (0.18 * (1 - t * 0.7)).toFixed(3);
4957
+ const ringOffsets = [
4958
+ [dist, 0],
4959
+ [-dist, 0],
4960
+ [0, dist],
4961
+ [0, -dist],
4962
+ [dist * 0.7, dist * 0.7],
4963
+ [-dist * 0.7, dist * 0.7],
4964
+ [dist * 0.7, -dist * 0.7],
4965
+ [-dist * 0.7, -dist * 0.7]
4966
+ ];
4967
+ for (const [dx, dy] of ringOffsets) {
4968
+ layers.push(
4969
+ `<g transform="translate(${(ox + dx).toFixed(3)} ${(oy + dy).toFixed(3)})" opacity="${op}">${shadowBgPath}${recoloredText}</g>`
4970
+ );
4971
+ }
4972
+ }
4973
+ layers.push(
4974
+ `<g transform="translate(${ox.toFixed(3)} ${oy.toFixed(3)})" opacity="0.25">${shadowBgPath}${recoloredText}</g>`
4975
+ );
4976
+ } else {
4977
+ layers.push(
4978
+ `<g transform="translate(${ox.toFixed(3)} ${oy.toFixed(3)})">${shadowBgPath}${recoloredText}</g>`
4979
+ );
4980
+ }
4981
+ shadowLayer = layers.join("");
4982
+ }
4936
4983
  const openTagMatch = svg.match(/^\s*<g\b[^>]*>/);
4984
+ const inserted = shadowLayer + bgPath;
4937
4985
  if (openTagMatch) {
4938
4986
  const openTag = openTagMatch[0];
4939
- return svg.replace(openTag, openTag + bgPath);
4987
+ return svg.replace(openTag, openTag + inserted);
4940
4988
  }
4941
- return `<g>${bgPath}${svg}</g>`;
4989
+ return `<g>${inserted}${svg}</g>`;
4942
4990
  };
4943
4991
  }
4944
4992
  }
4993
+ function recolorSvgFills(svg, color) {
4994
+ const safe = escapeXmlAttr(color);
4995
+ let out = svg.replace(
4996
+ /(<(?:text|tspan|path|rect)\b[^>]*?\sfill=")([^"]*)("[^>]*>)/gi,
4997
+ (_m, pre, val, post) => {
4998
+ const v = val.trim().toLowerCase();
4999
+ if (v === "none" || v === "transparent") return pre + val + post;
5000
+ return pre + safe + post;
5001
+ }
5002
+ );
5003
+ out = out.replace(
5004
+ /(<(?:text|tspan|path|rect)\b[^>]*?\sstyle=")([^"]*)("[^>]*>)/gi,
5005
+ (_m, pre, styleVal, post) => {
5006
+ const replaced = styleVal.replace(/fill\s*:\s*[^;"]+/gi, `fill: ${color}`);
5007
+ return pre + replaced + post;
5008
+ }
5009
+ );
5010
+ return out;
5011
+ }
4945
5012
  function buildRoundedRectPathD(x, y, w, h, rTL, rTR, rBR, rBL) {
4946
5013
  const maxR = Math.min(w, h) / 2;
4947
5014
  const tl = Math.min(Math.max(0, rTL), maxR);
@@ -4965,6 +5032,13 @@ function buildRoundedRectPathD(x, y, w, h, rTL, rTR, rBR, rBL) {
4965
5032
  function escapeXmlAttr(s) {
4966
5033
  return String(s).replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
4967
5034
  }
5035
+ function extractGInnerMarkup(markup) {
5036
+ const openMatch = markup.match(/^\s*<g\b[^>]*>/);
5037
+ if (!openMatch) return markup;
5038
+ const closeIdx = markup.lastIndexOf("</g>");
5039
+ if (closeIdx <= openMatch[0].length) return markup;
5040
+ return markup.slice(openMatch[0].length, closeIdx);
5041
+ }
4968
5042
  const TRIANGLE_STROKE_MITER_LIMIT = 1e6;
4969
5043
  const toSafeNumber = (value, fallback = 0) => Number.isFinite(value) ? Math.max(0, Number(value)) : fallback;
4970
5044
  function normalizeShapeType(shapeType) {
@@ -12286,7 +12360,7 @@ function PixldocsPreview(props) {
12286
12360
  !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..." }) })
12287
12361
  ] });
12288
12362
  }
12289
- const PACKAGE_VERSION = "0.5.43";
12363
+ const PACKAGE_VERSION = "0.5.44";
12290
12364
  let __underlineFixInstalled = false;
12291
12365
  function installUnderlineFix(fab) {
12292
12366
  var _a;