diff --git a/pom.xml b/pom.xml index 5c95e850..88081b11 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ 6.0 2.10.1 4.5.14 - 2.10.377 + 2.0.30 12.4 2.12.1 2.0.13 @@ -97,6 +97,11 @@ httpclient ${apache.httpcomponents.version} + + org.apache.pdfbox + pdfbox + ${pdfbox.version} + net.sf.saxon Saxon-HE @@ -297,55 +302,6 @@ - - org.codehaus.mojo - wagon-maven-plugin - 2.0.2 - - - download-pdfjs-main - initialize - - download-single - - - - https://cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjs.version}/build/pdf.min.js - - ${project.resources[0].directory}/digital/slovensko/autogram/ui/gui/vendor/pdfjs - true - - - - download-pdfjs-worker - initialize - - download-single - - - - https://cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.js - - ${project.resources[0].directory}/digital/slovensko/autogram/ui/gui/vendor/pdfjs - true - - - - download-pdfjs-cmaps - initialize - - download - - - https://cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjs.version} - cmaps - - ${project.resources[0].directory}/digital/slovensko/autogram/ui/gui/vendor/pdfjs/cmaps - - - - - com.igormaznitsa mvn-jlink-wrapper diff --git a/src/main/java/digital/slovensko/autogram/core/Autogram.java b/src/main/java/digital/slovensko/autogram/core/Autogram.java index 842d9b8d..37ca78fa 100644 --- a/src/main/java/digital/slovensko/autogram/core/Autogram.java +++ b/src/main/java/digital/slovensko/autogram/core/Autogram.java @@ -73,7 +73,7 @@ public void startVisualization(SigningJob job) { } try { - var visualization = DocumentVisualizationBuilder.fromJob(job); + var visualization = DocumentVisualizationBuilder.fromJob(job, settings); ui.onUIThreadDo(() -> ui.showVisualization(visualization, this)); } catch (AutogramException e) { ui.onUIThreadDo(() -> ui.showError(e)); diff --git a/src/main/java/digital/slovensko/autogram/core/UserSettings.java b/src/main/java/digital/slovensko/autogram/core/UserSettings.java index d9fefb9b..580c3e80 100644 --- a/src/main/java/digital/slovensko/autogram/core/UserSettings.java +++ b/src/main/java/digital/slovensko/autogram/core/UserSettings.java @@ -29,6 +29,7 @@ public class UserSettings implements PasswordManagerSettings, SignatureTokenSett private boolean tsaEnabled; private String customTsaServer; private boolean bulkEnabled; + private int pdfDpi; public static UserSettings load() { var prefs = Preferences.userNodeForPackage(UserSettings.class); @@ -51,6 +52,7 @@ public static UserSettings load() { settings.setTsaServer(prefs.get("TSA_SERVER", "http://tsa.izenpe.com")); settings.setCustomTsaServer(prefs.get("CUSTOM_TSA_SERVER", "")); settings.setTsaEnabled(prefs.getBoolean("TSA_ENABLE", false)); + settings.setPdfDpi(prefs.getInt("PDF_DPI", 100)); return settings; } @@ -75,6 +77,7 @@ public void save() { prefs.put("TSA_SERVER", tsaServer); prefs.put("CUSTOM_TSA_SERVER", customTsaServer); prefs.putBoolean("TSA_ENABLE", tsaEnabled); + prefs.putInt("PDF_DPI", pdfDpi); } private void setSignatureType(String signatureType) { @@ -260,4 +263,12 @@ public DriverDetector getDriverDetector() { public boolean isBulkEnabled() { return bulkEnabled; } + + public int getPdfDpi() { + return pdfDpi; + } + + public void setPdfDpi(int value) { + pdfDpi = value; + } } diff --git a/src/main/java/digital/slovensko/autogram/core/visualization/DocumentVisualizationBuilder.java b/src/main/java/digital/slovensko/autogram/core/visualization/DocumentVisualizationBuilder.java index 1eeb64f0..3b8d85f6 100644 --- a/src/main/java/digital/slovensko/autogram/core/visualization/DocumentVisualizationBuilder.java +++ b/src/main/java/digital/slovensko/autogram/core/visualization/DocumentVisualizationBuilder.java @@ -5,6 +5,7 @@ import javax.xml.parsers.ParserConfigurationException; +import digital.slovensko.autogram.core.UserSettings; import eu.europa.esig.dss.model.DSSDocument; import org.xml.sax.SAXException; @@ -29,15 +30,15 @@ private DocumentVisualizationBuilder(DSSDocument document, SigningParameters par this.parameters = parameters; } - public static Visualization fromJob(SigningJob job) throws IOException, ParserConfigurationException, SAXException { - return new DocumentVisualizationBuilder(job.getDocument(), job.getParameters()).build(job); + public static Visualization fromJob(SigningJob job, UserSettings userSettings) throws IOException, ParserConfigurationException, SAXException { + return new DocumentVisualizationBuilder(job.getDocument(), job.getParameters()).build(job, userSettings); } - private Visualization build(SigningJob job) throws IOException, ParserConfigurationException, SAXException { - return createVisualization(job); + private Visualization build(SigningJob job, UserSettings userSettings) throws IOException, ParserConfigurationException, SAXException { + return createVisualization(job, userSettings); } - private Visualization createVisualization(SigningJob job) + private Visualization createVisualization(SigningJob job, UserSettings userSettings) throws IOException, ParserConfigurationException, SAXException { var documentToDisplay = document; @@ -70,7 +71,7 @@ private Visualization createVisualization(SigningJob job) return new PlainTextVisualization(new String(documentToDisplay.openStream().readAllBytes(), StandardCharsets.UTF_8), job); if (documentToDisplay.getMimeType().equals(MimeTypeEnum.PDF)) - return new PDFVisualization(documentToDisplay, job); + return new PDFVisualization(documentToDisplay, job, userSettings); if (documentToDisplay.getMimeType().equals(MimeTypeEnum.JPEG) || documentToDisplay.getMimeType().equals(MimeTypeEnum.PNG)) return new ImageVisualization(documentToDisplay, job); diff --git a/src/main/java/digital/slovensko/autogram/core/visualization/PDFVisualization.java b/src/main/java/digital/slovensko/autogram/core/visualization/PDFVisualization.java index e4cfc1e8..fde1d9ce 100644 --- a/src/main/java/digital/slovensko/autogram/core/visualization/PDFVisualization.java +++ b/src/main/java/digital/slovensko/autogram/core/visualization/PDFVisualization.java @@ -1,32 +1,49 @@ package digital.slovensko.autogram.core.visualization; +import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Base64; +import java.util.ArrayList; import digital.slovensko.autogram.core.SigningJob; +import digital.slovensko.autogram.core.UserSettings; import digital.slovensko.autogram.ui.Visualizer; import eu.europa.esig.dss.model.DSSDocument; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.rendering.ImageType; +import org.apache.pdfbox.rendering.PDFRenderer; + +import javax.imageio.ImageIO; public class PDFVisualization extends Visualization { private final DSSDocument document; + private final UserSettings settings; + - public PDFVisualization(DSSDocument document, SigningJob job) { + public PDFVisualization(DSSDocument document, SigningJob job, UserSettings settings) { super(job); this.document = document; + this.settings = settings; } - private String getBase64EncodedDocument() { - try (var is = document.openStream()) { - return new String(Base64.getEncoder().encode(is.readAllBytes()), StandardCharsets.UTF_8); - } catch (IOException e) { - throw new RuntimeException(e); + private ArrayList getPdfImages() throws IOException { + var pdfDocument = PDDocument.load(this.document.openStream()); + var pdfRenderer = new PDFRenderer(pdfDocument); + var divs = new ArrayList(); + for (int page = 0; page < pdfDocument.getNumberOfPages(); ++page) { + var os = new ByteArrayOutputStream(); + var bim = pdfRenderer.renderImageWithDPI(page, settings.getPdfDpi(), ImageType.RGB); + ImageIO.write(bim, "png", os); + divs.add(os.toByteArray()); } + + pdfDocument.close(); + + return divs; } @Override - public void initialize(Visualizer visualizer) { + public void initialize(Visualizer visualizer) throws IOException { visualizer.setPrefWidth(getVisualizationWidth()); - visualizer.showPDFVisualization(getBase64EncodedDocument()); + visualizer.showPDFVisualization(getPdfImages()); } } \ No newline at end of file diff --git a/src/main/java/digital/slovensko/autogram/core/visualization/Visualization.java b/src/main/java/digital/slovensko/autogram/core/visualization/Visualization.java index 24359943..f0dc0a7e 100644 --- a/src/main/java/digital/slovensko/autogram/core/visualization/Visualization.java +++ b/src/main/java/digital/slovensko/autogram/core/visualization/Visualization.java @@ -3,6 +3,8 @@ import digital.slovensko.autogram.core.SigningJob; import digital.slovensko.autogram.ui.Visualizer; +import java.io.IOException; + public abstract class Visualization { private final SigningJob job; @@ -10,7 +12,7 @@ protected Visualization(SigningJob job) { this.job = job; } - public abstract void initialize(Visualizer visualizer); + public abstract void initialize(Visualizer visualizer) throws IOException; public SigningJob getJob() { return job; diff --git a/src/main/java/digital/slovensko/autogram/ui/Visualizer.java b/src/main/java/digital/slovensko/autogram/ui/Visualizer.java index 1ebc8646..06c5cb60 100644 --- a/src/main/java/digital/slovensko/autogram/ui/Visualizer.java +++ b/src/main/java/digital/slovensko/autogram/ui/Visualizer.java @@ -2,10 +2,12 @@ import eu.europa.esig.dss.model.DSSDocument; +import java.util.ArrayList; + public interface Visualizer { void showUnsupportedVisualization(); - void showPDFVisualization(String base64EncodedDocument); + void showPDFVisualization(ArrayList base64EncodedDocument); void showHTMLVisualization(String document); diff --git a/src/main/java/digital/slovensko/autogram/ui/gui/GUI.java b/src/main/java/digital/slovensko/autogram/ui/gui/GUI.java index d405831c..79f00e41 100644 --- a/src/main/java/digital/slovensko/autogram/ui/gui/GUI.java +++ b/src/main/java/digital/slovensko/autogram/ui/gui/GUI.java @@ -319,7 +319,16 @@ public void showVisualization(Visualization visualization, Autogram autogram) { var controller = new SigningDialogController(visualization, autogram, this, title, userSettings.isSignaturesValidity()); jobControllers.put(visualization.getJob(), controller); - var root = GUIUtils.loadFXML(controller, "signing-dialog.fxml"); + Parent root; + try { + root = GUIUtils.loadFXML(controller, "signing-dialog.fxml"); + } catch (AutogramException e) { + showError(e); + return; + } catch (Exception e) { + showError(new UnrecognizedException(e)); + return; + } var stage = new Stage(); stage.setTitle(title); stage.setScene(new Scene(root)); diff --git a/src/main/java/digital/slovensko/autogram/ui/gui/SettingsDialogController.java b/src/main/java/digital/slovensko/autogram/ui/gui/SettingsDialogController.java index be9f3a45..212efd59 100644 --- a/src/main/java/digital/slovensko/autogram/ui/gui/SettingsDialogController.java +++ b/src/main/java/digital/slovensko/autogram/ui/gui/SettingsDialogController.java @@ -47,6 +47,8 @@ public class SettingsDialogController { @FXML private HBox localServerEnabledRadios; @FXML + private ChoiceBox pdfDpiChoiceBox; + @FXML private ChoiceBox slotIndexChoiceBox; @FXML private TextField customKeystorePathTextField; @@ -81,6 +83,7 @@ public void initialize() { initializeLocalServerEnabledCheckBox(); initializeTrustedCountriesList(); initializeSlotIndexSettings(); + initializePdfDpiSettings(); initializeCustomKeystoreSettings(); } @@ -277,6 +280,14 @@ private void initializeSlotIndexSettings() { }); } + private void initializePdfDpiSettings() { + pdfDpiChoiceBox.getItems().addAll("50 dpi", "70 dpi", "100 dpi", "150 dpi", "200 dpi", "300 dpi"); + pdfDpiChoiceBox.setValue(String.valueOf(userSettings.getPdfDpi()) + " dpi"); + pdfDpiChoiceBox.getSelectionModel().selectedItemProperty() + .addListener((observable, oldValue, newValue) -> + userSettings.setPdfDpi(Integer.parseInt(newValue.replace(" dpi", "")))); + } + private void initializeCustomKeystoreSettings() { customKeystorePathTextField.setText(userSettings.getCustomKeystorePath()); customKeystorePathTextField.setOnKeyTyped((e) -> { diff --git a/src/main/java/digital/slovensko/autogram/ui/gui/SigningDialogController.java b/src/main/java/digital/slovensko/autogram/ui/gui/SigningDialogController.java index 900c9dd7..229fa544 100644 --- a/src/main/java/digital/slovensko/autogram/ui/gui/SigningDialogController.java +++ b/src/main/java/digital/slovensko/autogram/ui/gui/SigningDialogController.java @@ -2,6 +2,7 @@ import digital.slovensko.autogram.core.Autogram; import digital.slovensko.autogram.core.SignatureValidator; +import digital.slovensko.autogram.core.visualization.ImageVisualization; import digital.slovensko.autogram.core.visualization.Visualization; import digital.slovensko.autogram.ui.Visualizer; import digital.slovensko.autogram.util.DSSUtils; @@ -20,11 +21,17 @@ import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.input.ContextMenuEvent; +import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.scene.text.Text; import javafx.scene.web.WebView; import javafx.stage.Modality; import javafx.stage.Stage; +import org.verapdf.xmp.impl.Base64; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.ArrayList; import static digital.slovensko.autogram.ui.gui.GUIValidationUtils.*; @@ -50,6 +57,10 @@ public class SigningDialogController implements SuppressedFocusController, Visua @FXML VBox webViewContainer; @FXML + ScrollPane pdfVisualizationContainer; + @FXML + VBox pdfVisualizationBox; + @FXML ImageView imageVisualization; @FXML ScrollPane imageVisualizationContainer; @@ -73,7 +84,7 @@ public SigningDialogController(Visualization visualization, Autogram autogram, G this.shouldCheckValidityBeforeSigning = shouldCheckValidityBeforeSigning; } - public void initialize() { + public void initialize() throws IOException { headerText.setText(title); signaturesTable.setManaged(false); signaturesTable.setVisible(false); @@ -298,19 +309,20 @@ public void showHTMLVisualization(String html) { webViewContainer.setManaged(true); } - public void showPDFVisualization(String base64EncodedPdf) { - var engine = webView.getEngine(); - engine.setJavaScriptEnabled(true); - engine.getLoadWorker().stateProperty().addListener((observable, oldState, newState) -> { - if (newState == Worker.State.SUCCEEDED) { - engine.executeScript( - "displayPdf('" + base64EncodedPdf + "')"); - } + public void showPDFVisualization(ArrayList data) { + data.forEach(page -> { + var imgView = new ImageView(); + imgView.fitWidthProperty().bind(pdfVisualizationContainer.widthProperty().subtract(30)); + imgView.setImage(new Image(new ByteArrayInputStream(page))); + imgView.setPreserveRatio(true); + imgView.setSmooth(true); + + pdfVisualizationBox.getChildren().add(new HBox(imgView)); }); - engine.load(getClass().getResource("visualization-pdf.html").toExternalForm()); - webViewContainer.getStyleClass().add("autogram-visualizer-pdf"); - webViewContainer.setVisible(true); - webViewContainer.setManaged(true); + + pdfVisualizationContainer.setFitToWidth(true); + pdfVisualizationContainer.setVisible(true); + pdfVisualizationContainer.setManaged(true); } public void showImageVisualization(DSSDocument doc) { diff --git a/src/main/resources/digital/slovensko/autogram/ui/gui/idsk.css b/src/main/resources/digital/slovensko/autogram/ui/gui/idsk.css index b37000d0..d71a833b 100644 --- a/src/main/resources/digital/slovensko/autogram/ui/gui/idsk.css +++ b/src/main/resources/digital/slovensko/autogram/ui/gui/idsk.css @@ -447,6 +447,7 @@ .autogram-visualizer-plaintext, .autogram-visualizer-html, +.autogram-visualizer-pdf VBox > HBox, .autogram-visualizer-image { -fx-border-color: -autogram-input-border-colour; -fx-border-width: 2px; @@ -454,6 +455,11 @@ -fx-wrap-text: true; } +.autogram-visualizer-pdf VBox { + -fx-spacing: 10px; + -fx-padding: 5px; +} + .autogram-visualizer-plaintext { -fx-padding: 5px; } diff --git a/src/main/resources/digital/slovensko/autogram/ui/gui/settings-dialog.fxml b/src/main/resources/digital/slovensko/autogram/ui/gui/settings-dialog.fxml index b0d0a9d6..1f0b4104 100644 --- a/src/main/resources/digital/slovensko/autogram/ui/gui/settings-dialog.fxml +++ b/src/main/resources/digital/slovensko/autogram/ui/gui/settings-dialog.fxml @@ -336,6 +336,23 @@ styleClass="autogram-smaller-radio-buttons" /> + + + + + Rozlíšenie náhľadu PDF + + + + + Vyššie DPI môže pri veľkých PDF dokumentoch spôsobovať výrazne pomalé zobrazenie. Naopak pri nízkom DPI je zobrazenie rýchlejšie, no dokument je viac rozmazaný. + + + + + + + diff --git a/src/main/resources/digital/slovensko/autogram/ui/gui/signing-dialog.fxml b/src/main/resources/digital/slovensko/autogram/ui/gui/signing-dialog.fxml index c7f94bc7..2b4b8ac7 100644 --- a/src/main/resources/digital/slovensko/autogram/ui/gui/signing-dialog.fxml +++ b/src/main/resources/digital/slovensko/autogram/ui/gui/signing-dialog.fxml @@ -21,11 +21,16 @@ - + + + + + +