From 338afbc8f3699891085ee3871273ee0e62aaf4c6 Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> Date: Wed, 12 Nov 2025 23:51:37 +0000 Subject: [PATCH] blank images --- .../service/PdfJsonConversionService.java | 28 +++++++++++++--- .../public/locales/en-GB/translation.json | 9 +++++- .../tools/pdfTextEditor/FontStatusPanel.tsx | 4 +-- .../tools/pdfTextEditor/PdfTextEditor.tsx | 32 ++++++++++++++++++- 4 files changed, 65 insertions(+), 8 deletions(-) diff --git a/app/proprietary/src/main/java/stirling/software/SPDF/service/PdfJsonConversionService.java b/app/proprietary/src/main/java/stirling/software/SPDF/service/PdfJsonConversionService.java index f72df4033..b0869dc16 100644 --- a/app/proprietary/src/main/java/stirling/software/SPDF/service/PdfJsonConversionService.java +++ b/app/proprietary/src/main/java/stirling/software/SPDF/service/PdfJsonConversionService.java @@ -2647,8 +2647,18 @@ public class PdfJsonConversionService { pageNumber); continue; } - contentStream.showText( - new String(encoded, StandardCharsets.ISO_8859_1)); + try { + contentStream.showText( + new String(encoded, StandardCharsets.ISO_8859_1)); + } catch (IllegalArgumentException ex) { + log.warn( + "Failed to render text '{}' with font {} on page {}: {}", + run.text(), + run.font().getName(), + pageNumber, + ex.getMessage()); + continue; + } } } } @@ -3380,8 +3390,18 @@ public class PdfJsonConversionService { // or return null to trigger fallback font } else if (!isType3Font || fontModel == null) { // For non-Type3 fonts without Type3 metadata, use standard encoding - byte[] encoded = font.encode(text); - return sanitizeEncoded(encoded); + try { + byte[] encoded = font.encode(text); + return sanitizeEncoded(encoded); + } catch (IllegalArgumentException ex) { + log.info( + "[FONT-DEBUG] Font {} cannot encode text '{}': {}", + font.getName(), + text, + ex.getMessage()); + // Return null to trigger fallback font mechanism + return null; + } } // Type3 glyph mapping logic (for actual Type3 fonts AND normalized Type3 fonts) diff --git a/frontend/public/locales/en-GB/translation.json b/frontend/public/locales/en-GB/translation.json index d44661a23..c972fd919 100644 --- a/frontend/public/locales/en-GB/translation.json +++ b/frontend/public/locales/en-GB/translation.json @@ -4471,7 +4471,8 @@ "title": "PDF Editor", "badges": { "unsaved": "Unsaved changes", - "modified": "Edited" + "modified": "Edited", + "earlyAccess": "Early Access - Pre-Alpha" }, "controls": { "title": "Document Controls" @@ -4526,6 +4527,12 @@ "paragraph": "Paragraph", "singleLine": "Single Line" }, + "modeChange": { + "title": "Confirm Mode Change", + "warning": "Changing the text grouping mode will reset all unsaved changes. Are you sure you want to continue?", + "cancel": "Cancel", + "confirm": "Reset and Change Mode" + }, "disclaimer": { "heading": "Preview limitations", "textFocus": "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here.", diff --git a/frontend/src/proprietary/components/tools/pdfTextEditor/FontStatusPanel.tsx b/frontend/src/proprietary/components/tools/pdfTextEditor/FontStatusPanel.tsx index 244e31494..4bb8ce65c 100644 --- a/frontend/src/proprietary/components/tools/pdfTextEditor/FontStatusPanel.tsx +++ b/frontend/src/proprietary/components/tools/pdfTextEditor/FontStatusPanel.tsx @@ -255,8 +255,8 @@ const FontStatusPanel: React.FC = ({ document, pageIndex } {/* Font List */} - {fonts.map((font) => ( - + {fonts.map((font, index) => ( + ))} diff --git a/frontend/src/proprietary/tools/pdfTextEditor/PdfTextEditor.tsx b/frontend/src/proprietary/tools/pdfTextEditor/PdfTextEditor.tsx index 42b26384b..8ef040338 100644 --- a/frontend/src/proprietary/tools/pdfTextEditor/PdfTextEditor.tsx +++ b/frontend/src/proprietary/tools/pdfTextEditor/PdfTextEditor.tsx @@ -976,6 +976,36 @@ const PdfTextEditor = ({ onComplete, onError }: BaseToolProps) => { } catch (textError) { console.warn('[PdfTextEditor] Failed to strip text from preview', textError); } + + // Also mask out images to prevent ghost/shadow images when they're moved + try { + const pageImages = imagesByPage[pageIndex] ?? []; + if (pageImages.length > 0) { + context.save(); + context.globalCompositeOperation = 'destination-out'; + context.fillStyle = '#000000'; + for (const image of pageImages) { + if (!image) continue; + // Get image bounds in PDF coordinates + const left = image.left ?? image.x ?? 0; + const bottom = image.bottom ?? image.y ?? 0; + const width = image.width ?? Math.max((image.right ?? left) - left, 0); + const height = image.height ?? Math.max((image.top ?? bottom) - bottom, 0); + const right = left + width; + const top = bottom + height; + + // Convert to canvas coordinates (PDF origin is bottom-left, canvas is top-left) + const canvasX = left * scale; + const canvasY = canvas.height - top * scale; + const canvasWidth = width * scale; + const canvasHeight = height * scale; + context.fillRect(canvasX, canvasY, canvasWidth, canvasHeight); + } + context.restore(); + } + } catch (imageError) { + console.warn('[PdfTextEditor] Failed to strip images from preview', imageError); + } const dataUrl = canvas.toDataURL('image/png'); page.cleanup(); if (previewRequestIdRef.current !== currentToken) { @@ -993,7 +1023,7 @@ const PdfTextEditor = ({ onComplete, onError }: BaseToolProps) => { previewRenderingRef.current.delete(pageIndex); } }, - [hasVectorPreview], + [hasVectorPreview, imagesByPage], ); // Re-group text when grouping mode changes without forcing a full reload