diff --git a/src/qz/printer/action/PrintImage.java b/src/qz/printer/action/PrintImage.java index 90e8b9725..5d72a0ce8 100644 --- a/src/qz/printer/action/PrintImage.java +++ b/src/qz/printer/action/PrintImage.java @@ -100,6 +100,28 @@ public void parseData(JSONArray printData, PrintOptions options) throws JSONExce log.debug("Parsed {} images for printing", images.size()); } + private List breakupOverPages(BufferedImage img, PageFormat page) { + List splits = new ArrayList<>(); + + Rectangle printBounds = new Rectangle(0, 0, (int)page.getImageableWidth(), (int)page.getImageableHeight()); + + int columnsNeed = (int)Math.ceil(img.getWidth() / page.getImageableWidth()); + int rowsNeed = (int)Math.ceil(img.getHeight() / page.getImageableHeight()); + log.trace("Image to be printed across {} pages", columnsNeed * rowsNeed); + + for(int row = 0; row < rowsNeed; row++) { + for(int col = 0; col < columnsNeed; col++) { + Rectangle clip = new Rectangle((col * printBounds.width), (row * printBounds.height), printBounds.width, printBounds.height); + if (clip.x + clip.width > img.getWidth()) { clip.width = img.getWidth() - clip.x; } + if (clip.y + clip.height > img.getHeight()) { clip.height = img.getHeight() - clip.y; } + + splits.add(img.getSubimage(clip.x, clip.y, clip.width, clip.height)); + } + } + + return splits; + } + @Override public void print(PrintOutput output, PrintOptions options) throws PrinterException { if (images.isEmpty()) { @@ -126,6 +148,15 @@ public void print(PrintOutput output, PrintOptions options) throws PrinterExcept manualReverse = true; } + if (!scaleImage) { + //breakup large images to print across pages as needed + List split = new ArrayList<>(); + for(BufferedImage bi : images) { + split.addAll(breakupOverPages(bi, page)); + } + images = split; + } + job.setJobName(pxlOpts.getJobName(Constants.IMAGE_PRINT)); job.setPrintable(this, job.validatePage(page)); diff --git a/src/qz/printer/action/WebApp.java b/src/qz/printer/action/WebApp.java index 7a67ada1d..e74fa752e 100644 --- a/src/qz/printer/action/WebApp.java +++ b/src/qz/printer/action/WebApp.java @@ -13,7 +13,10 @@ import javafx.scene.Scene; import javafx.scene.SnapshotParameters; import javafx.scene.image.WritableImage; +import javafx.scene.shape.Rectangle; import javafx.scene.transform.Scale; +import javafx.scene.transform.Transform; +import javafx.scene.transform.Translate; import javafx.scene.web.WebView; import javafx.stage.Stage; import javafx.util.Duration; @@ -89,6 +92,7 @@ public class WebApp extends Application { webView.getTransforms().add(new Scale(scale, scale)); double increase = 96d / 72d; + log.trace("Setting HTML page width to {}", webView.getWidth() * increase); webView.setMinWidth(webView.getWidth() * increase); webView.setPrefWidth(webView.getWidth() * increase); webView.setMaxWidth(webView.getWidth() * increase); @@ -163,7 +167,38 @@ public static synchronized void print(final PrinterJob job, final WebAppModel mo webView.getTransforms().add(new Scale(scale, scale)); } - Platform.runLater(() -> complete.set(job.printPage(webView))); + Platform.runLater(() -> { + double useScale = 1; + for(Transform t : webView.getTransforms()) { + if (t instanceof Scale) { useScale *= ((Scale)t).getX(); } + } + + PageLayout page = job.getJobSettings().getPageLayout(); + Rectangle printBounds = new Rectangle(0, 0, page.getPrintableWidth(), page.getPrintableHeight()); + log.debug("Paper area: {},{}:{},{}", (int)page.getLeftMargin(), (int)page.getTopMargin(), + (int)page.getPrintableWidth(), (int)page.getPrintableHeight()); + + Translate activePage = new Translate(); + webView.getTransforms().add(activePage); + + int columnsNeed = (int)Math.ceil(webView.getWidth() / printBounds.getWidth() * useScale); + int rowsNeed = (int)Math.ceil(webView.getHeight() / printBounds.getHeight() * useScale); + log.debug("Document will be printed across {} pages", columnsNeed * rowsNeed); + + for(int row = 0; row < rowsNeed; row++) { + for(int col = 0; col < columnsNeed; col++) { + activePage.setX((-col * printBounds.getWidth()) / useScale); + activePage.setY((-row * printBounds.getHeight()) / useScale); + + job.printPage(webView); + } + } + + //reset state + webView.getTransforms().remove(activePage); + + complete.set(true); + }); } catch(Exception e) { thrown.set(e); } });