From 0aa50282dd3119a48d07782e06612714285bf324 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sat, 18 Apr 2026 18:31:26 +0000 Subject: [PATCH] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/components/forms/custom-form-builder.tsx | 52 ++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/components/forms/custom-form-builder.tsx b/src/components/forms/custom-form-builder.tsx index 01603fb..498a22c 100644 --- a/src/components/forms/custom-form-builder.tsx +++ b/src/components/forms/custom-form-builder.tsx @@ -1131,6 +1131,58 @@ export function CustomFormBuilder() { continue; } + if (seg.kind === "image") { + // Decode data URL to bytes for ImageRun + const m = seg.src.match(/^data:image\/(png|jpeg|jpg|gif|webp);base64,(.*)$/i); + if (!m) { + // Skip non-data URLs we can't fetch synchronously + continue; + } + const fmtRaw = m[1].toLowerCase(); + const fmt: "png" | "jpg" | "gif" = fmtRaw === "png" ? "png" : fmtRaw === "gif" ? "gif" : "jpg"; + const b64 = m[2]; + const bin = atob(b64); + const bytes = new Uint8Array(bin.length); + for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i); + // Convert px → EMU/pt: docx uses pixels for ImageRun transformation + const wPx = seg.widthPx ?? 320; + let hPx = seg.heightPx ?? 0; + if (!hPx) { + // Fallback: read natural size synchronously via Image() + try { + const im = new Image(); + im.src = seg.src; + const nw = im.naturalWidth || 0; + const nh = im.naturalHeight || 0; + hPx = nw > 0 && nh > 0 ? Math.round(wPx * (nh / nw)) : Math.round(wPx * 0.75); + } catch { + hPx = Math.round(wPx * 0.75); + } + } + const docxAlign = + seg.align === "center" + ? AlignmentType.CENTER + : seg.align === "right" + ? AlignmentType.RIGHT + : AlignmentType.LEFT; + children.push( + new DocxParagraph({ + alignment: docxAlign, + children: [ + new ImageRun({ + type: fmt as any, + data: bytes, + transformation: { width: wPx, height: hPx }, + altText: seg.alt + ? { title: seg.alt, description: seg.alt, name: seg.alt } + : undefined, + }), + ], + }), + ); + continue; + } + const align = seg.align === "center" ? AlignmentType.CENTER