demo reupload plus translations and pdf editor cleanups, test amd64

This commit is contained in:
Anthony Stirling 2025-11-14 17:22:06 +00:00
parent e8d8aa8f46
commit a5e21bc35c
3 changed files with 117 additions and 5 deletions

View File

@ -76,6 +76,6 @@ jobs:
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }}
platforms: linux/amd64,linux/arm64/v8
platforms: linux/amd64
provenance: true
sbom: true

View File

@ -5285,5 +5285,111 @@
"offline": "Backend Offline",
"starting": "Backend starting up...",
"wait": "Please wait for the backend to finish launching and try again."
},
"pdfTextEditor": {
"title": "PDF JSON Editor",
"imageLabel": "Placed image",
"pageSummary": "Page {{number}} of {{total}}",
"currentFile": "Current file: {{name}}",
"pagePreviewAlt": "Page preview",
"noTextOnPage": "No editable text was detected on this page.",
"empty": {
"title": "No document loaded",
"subtitle": "Load a PDF or JSON file to begin editing text content."
},
"pageType": {
"sparse": "Sparse text"
},
"badges": {
"unsaved": "Edited",
"modified": "Edited",
"earlyAccess": "Early Access"
},
"actions": {
"reset": "Reset Changes",
"downloadJson": "Download JSON",
"generatePdf": "Generate PDF"
},
"fontAnalysis": {
"details": "Font Details",
"embedded": "Embedded",
"type": "Type",
"webFormat": "Web Format",
"warnings": "Warnings",
"suggestions": "Notes",
"currentPageFonts": "Fonts on this page",
"allFonts": "All fonts",
"fallback": "fallback",
"missing": "missing",
"perfect": "perfect",
"subset": "subset",
"perfectMessage": "All fonts are perfectly matched",
"warningMessage": "Some fonts may render differently",
"infoMessage": "Font information"
},
"manual": {
"resizeHandle": "Adjust text width"
},
"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"
},
"options": {
"autoScaleText": {
"title": "Auto-scale text to fit boxes",
"description": "Automatically scales text horizontally to fit within its original bounding box when font rendering differs from PDF."
},
"groupingMode": {
"title": "Text Grouping Mode",
"autoDescription": "Automatically detects page type and groups text appropriately.",
"paragraphDescription": "Groups aligned lines into multi-line paragraph text boxes."
},
"manualGrouping": {
"descriptionInline": "Tip: Hold Ctrl (Cmd) or Shift to multi-select text boxes. A floating toolbar will appear above the selection so you can merge, ungroup, or adjust widths."
},
"forceSingleElement": {
"title": "Lock edited text to a single PDF element",
"description": "When enabled, the editor exports each edited text box as one PDF text element to avoid overlapping glyphs or mixed fonts."
}
},
"groupingMode": {
"auto": "Auto",
"paragraph": "Paragraph",
"singleLine": "Single Line"
},
"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.",
"previewVariance": "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible.",
"alpha": "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
},
"welcomeBanner": {
"title": "Welcome to PDF Text Editor (Early Access)",
"experimental": "This is an experimental feature in active development. Expect some instability and issues during use.",
"howItWorks": "This tool converts your PDF to an editable format where you can modify text content and reposition images. Changes are saved back as a new PDF.",
"bestFor": "Works Best With:",
"bestFor1": "Simple PDFs containing primarily text and images",
"bestFor2": "Documents with standard paragraph formatting",
"bestFor3": "Letters, essays, reports, and basic documents",
"notIdealFor": "Not Ideal For:",
"notIdealFor1": "PDFs with special formatting like bullet points, tables, or multi-column layouts",
"notIdealFor2": "Magazines, brochures, or heavily designed documents",
"notIdealFor3": "Instruction manuals with complex layouts",
"limitations": "Current Limitations:",
"limitation1": "Font rendering may differ slightly from the original PDF",
"limitation2": "Complex graphics, form fields, and annotations are preserved but not editable",
"limitation3": "Large files may take time to convert and process",
"knownIssues": "Known Issues (Being Fixed):",
"issue1": "Text colour is not currently preserved (will be added soon)",
"issue2": "Paragraph mode has more alignment and spacing issues - Single Line mode recommended",
"issue3": "The preview display differs from the exported PDF - exported PDFs are closer to the original",
"issue4": "Rotated text alignment may need manual adjustment",
"issue5": "Transparency and layering effects may vary from original",
"feedback": "This is an early access feature. Please report any issues you encounter to help us improve!",
"gotIt": "Got it",
"dontShowAgain": "Don't show again"
}
}
}

View File

@ -2084,7 +2084,8 @@ const selectionToolbarPosition = useMemo(() => {
const isActive = activeGroupId === group.id || editingGroupId === group.id;
const isEditing = editingGroupId === group.id;
const baseFontSize = group.fontMatrixSize ?? group.fontSize ?? 12;
const fontSizePx = Math.max(baseFontSize * scale, 6);
// Reduce font size by ~2% to account for browser rendering differences and prevent wrapping
const fontSizePx = Math.max(baseFontSize * scale * 0.98, 6);
const effectiveFontId = resolveFontIdForIndex(pageGroupIndex) ?? group.fontId;
const fontFamily = getFontFamily(effectiveFontId, group.pageIndex);
let lineHeightPx = getLineHeightPx(effectiveFontId, group.pageIndex, fontSizePx);
@ -2154,9 +2155,12 @@ const selectionToolbarPosition = useMemo(() => {
const fontWeight = group.fontWeight || getFontWeight(effectiveFontId, group.pageIndex);
// Determine text wrapping behavior based on whether text has been changed
// Only wrap if: it's a multi-line paragraph, width extended, or text changed
// Don't wrap single lines just because we're in paragraph mode
const hasChanges = changed;
const widthExtended = resolvedWidth - baseWidth > 0.5;
const enableWrap = isParagraphLayout || widthExtended || isEditing || hasChanges;
const isMultiLineParagraph = isParagraphLayout && lineCount > 1;
const enableWrap = isMultiLineParagraph || widthExtended || hasChanges;
const whiteSpace = enableWrap ? 'pre-wrap' : 'pre';
const wordBreak = enableWrap ? 'break-word' : 'normal';
const overflowWrap = enableWrap ? 'break-word' : 'normal';
@ -2169,7 +2173,7 @@ const selectionToolbarPosition = useMemo(() => {
// We need to add this to the container width to compensate, so the inner content
// has the full PDF-defined width available for text
// Add extra padding to prevent text from being too tight and wrapping prematurely
const WRAPPER_HORIZONTAL_PADDING = 10;
const WRAPPER_HORIZONTAL_PADDING = 15;
const containerStyle: React.CSSProperties = {
position: 'absolute',
@ -2301,6 +2305,7 @@ const selectionToolbarPosition = useMemo(() => {
}
const textScale = textScales.get(group.id) ?? 1;
// Apply scale when needed to prevent text overflow, even when editing
const shouldScale = autoScaleText && textScale < 0.98;
return (
@ -2333,7 +2338,8 @@ const selectionToolbarPosition = useMemo(() => {
data-text-content
style={{
pointerEvents: 'none',
display: enableWrap ? 'inline' : 'inline-block',
// Keep inline-block even when wrapping to maintain scaleX transform
display: 'inline-block',
transform: shouldScale ? `scaleX(${textScale})` : 'none',
transformOrigin: 'left center',
whiteSpace,