All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jpedal.display.javafx.SingleDisplayFX Maven / Gradle / Ivy

/*
 * ===========================================
 * Java Pdf Extraction Decoding Access Library
 * ===========================================
 *
 * Project Info:  http://www.idrsolutions.com
 * Help section for developers at http://www.idrsolutions.com/support/
 *
 * (C) Copyright 1997-2017 IDRsolutions and Contributors.
 *
 * This file is part of JPedal/JPDF2HTML5
 *
     This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


 *
 * ---------------
 * SingleDisplayFX.java
 * ---------------
 */
package org.jpedal.display.javafx;


import javafx.application.Platform;
import javafx.geometry.Bounds;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.transform.Transform;
import org.jpedal.PdfDecoderFX;
import org.jpedal.display.Display;
import org.jpedal.display.GUIDisplay;
import org.jpedal.examples.viewer.commands.javafx.JavaFXPreferences;
import org.jpedal.examples.viewer.gui.JavaFxGUI;
import org.jpedal.external.Options;
import org.jpedal.objects.acroforms.AcroRenderer;
import org.jpedal.parser.DecoderOptions;
import org.jpedal.render.DynamicVectorRenderer;
import org.jpedal.render.FXDisplay;

public class SingleDisplayFX extends GUIDisplay {

    final PdfDecoderFX pdf;

    // Rectangle drawn on screen by user
    private int[] cursorBoxOnScreen;

    final Pane cursorBoxPane = new Pane();

    public SingleDisplayFX(int pageNumber, final DynamicVectorRenderer currentDisplay, final PdfDecoderFX pdf, final DecoderOptions options) {

        if (pageNumber < 1) {
            pageNumber = 1;
        }

        this.pageNumber = pageNumber;
        this.currentDisplay = currentDisplay;
        this.pdf = pdf;

        this.options = options;

        displayOffsets = pdf.getDisplayOffsets();

        pageData = pdf.getPdfPageData();

    }

    public SingleDisplayFX(final PdfDecoderFX pdf, final DecoderOptions options) {

        this.pdf = pdf;

        this.options = options;

        displayOffsets = pdf.getDisplayOffsets();

        pageData = pdf.getPdfPageData();
    }

    @Override
    public void refreshDisplay() {

        if (Platform.isFxApplicationThread()) {
            if (displayScalingDbl != null) {
                pdf.getTransforms().setAll(Transform.affine(displayScalingDbl[0], displayScalingDbl[1], displayScalingDbl[2], displayScalingDbl[3], displayScalingDbl[4], displayScalingDbl[5]));
            }

            if (currentDisplay != null) {
                paintPage(pdf.highlightsPane, pdf.getFormRenderer());
            }
        } else {
            // Ensure dialog is handled on FX thread
            Platform.runLater(new Runnable() {
                @Override
                public void run() {

                    if (displayScalingDbl != null) {
                        pdf.getTransforms().setAll(Transform.affine(displayScalingDbl[0], displayScalingDbl[1], displayScalingDbl[2], displayScalingDbl[3], displayScalingDbl[4], displayScalingDbl[5]));
                    }

                    if (currentDisplay != null) {
                        paintPage(pdf.highlightsPane, pdf.getFormRenderer());
                    }
                }
            });
        }
    }

    /**
     * initialise panel and set size to display during updates and update the AffineTransform to new values
* * @param newRotation int value to specify the rotation for the page */ @Override public void setPageRotation(final int newRotation) { super.setPageRotation(newRotation); // force redraw if screen being cached refreshDisplay(); } static Path getBorder(final int crw, final int crh) { final Path border = new Path(); border.getElements().add(new MoveTo(-1, -1)); border.getElements().add(new LineTo(crw + 2, -1)); border.getElements().add(new LineTo(crw + 2, crh + 2)); border.getElements().add(new LineTo(-1, crh + 2)); border.getElements().add(new ClosePath()); border.setStroke(Color.rgb(0, 0, 0)); return border; } /** * Resets the FXPane when we open a new PDF */ @Override public void disableScreen() { if (currentDisplay != null) { final Group FXpane = ((FXDisplay) currentDisplay).getFXPane(); if (pdf.getChildren().contains(FXpane)) { final int count = pdf.getChildren().size(); for (int i = 0; i < count; i++) { pdf.getChildren().remove(0); } } } } private void paintPage(final Object rawBox, final AcroRenderer formRenderer) { final boolean debugPane = false; final Pane box = (Pane) rawBox; final Group fxPane = ((FXDisplay) currentDisplay).getFXPane(); final String pageNumberStr = String.valueOf(pageNumber); final Rectangle clip = new Rectangle(crx, cry, crw, crh); clip.setFill(Color.WHITE); // Remove box from the current node it belongs to - avoids duplication errors if (box != null && box.getParent() != null) { ((Group) box.getParent()).getChildren().remove(box); } fxPane.getChildren().addAll(box); pdf.setPrefSize(crw, crh); if (displayView == SINGLE_PAGE) { pdf.getChildren().clear(); if (formRenderer.isXFA()) { // Draw wihte background border on xfa contents final Path border = getBorder(crw, crh); border.setFill(Color.WHITE); pdf.getChildren().addAll(border); border.setLayoutX(crx); border.setLayoutY(cry); } if (!pdf.getChildren().contains(fxPane)) { pdf.getChildren().addAll(fxPane); } fxPane.setLayoutX(-crx); fxPane.setLayoutY(-cry); } else { Node pagePath = null; for (final Node child : pdf.getChildren()) { if (child.getId() != null && child.getId().equals(pageNumberStr)) { if (child instanceof Path) { pagePath = child; } } } if (pagePath != null) { pdf.getChildren().remove(pagePath); } fxPane.setId(pageNumberStr); if (!pdf.getChildren().contains(fxPane)) { pdf.getChildren().addAll(fxPane); } final int[] xReached = multiDisplayOptions.getxReached(); final int[] yReached = multiDisplayOptions.getyReached(); int cx; final int cy; final int j = pageNumber; cx = (int) (xReached[j] / scaling); cy = (int) (yReached[j] / scaling); // Code works differently in Swing and FX so needs reversing if (displayView == CONTINUOUS_FACING) { cx = currentOffset.getWidestPageR() - cx; } fxPane.setLayoutX(-cx); fxPane.setLayoutY(pdf.getHeight() - cy); } if (!debugPane) { clip.setFill(Color.WHITE); fxPane.setClip(clip); } else { // Debug Different GUI Display Panes clip.setFill(Color.BLUE); clip.setOpacity(0.5); fxPane.getChildren().add(clip); pdf.setStyle("-fx-background-color: red;"); pdf.getParent().setStyle("-fx-background-color: yellow;"); fxPane.setStyle("-fx-background-color: green;"); } addForms(formRenderer); } private void addForms(final AcroRenderer formRenderer) { int start = pageNumber, end = pageNumber; // Control if we display forms on multiple pages if (displayView != Display.SINGLE_PAGE) { start = getStartPage(); end = getEndPage(); if (start == 0 || end == 0 || lastEnd != end || lastStart != start) { lastFormPage = -1; } lastEnd = end; lastStart = start; } if ((lastFormPage != pageNumber) && (formRenderer != null)) { formRenderer.displayComponentsOnscreen(start, end); // Switch off if forms for this page found if (formRenderer.getCompData().hasformsOnPageDecoded(pageNumber)) { lastFormPage = pageNumber; //ensure not called too early } } // Add the forms to the Pane if (formRenderer != null && currentOffset != null) { // If all forms flattened, we can get a null value for currentOffset so avoid this case formRenderer.getCompData().setPageValues(scaling, displayRotation, (int) indent, displayOffsets.getUserOffsetX(), displayOffsets.getUserOffsetY(), displayView, currentOffset.getWidestPageNR(), currentOffset.getWidestPageR()); formRenderer.getCompData().resetScaledLocation(scaling, displayRotation, (int) indent); // Indent here does nothing. } } @Override public void init(final float scaling, final int displayRotation, final int pageNumber, final DynamicVectorRenderer currentDisplay, final boolean isInit) { this.pageData = pdf.getPdfPageData(); super.init(scaling, displayRotation, pageNumber, currentDisplay, isInit); setPageSize(pageNumber, scaling); lastFormPage = -1; } /** * Set the page size for the given page and scaling. * The scaling is not actually applied here. It is instead passed along to * used by FX transformations. * * @param pageNumber int value representing the page number * @param scaling float value representing the scaling for the page */ @Override public void setPageSize(final int pageNumber, final float scaling) { // Handle clip - crop box values pageData.setScalingValue(scaling); //ensure aligned topW = pageData.getCropBoxWidth(pageNumber); topH = pageData.getCropBoxHeight(pageNumber); final double mediaH = pageData.getMediaBoxHeight(pageNumber); cropX = pageData.getCropBoxX(pageNumber); cropY = pageData.getCropBoxY(pageNumber); cropW = topW; cropH = topH; // Actual clip values - for flipped page if (displayView == Display.SINGLE_PAGE) { crx = (int) (insetW + cropX); cry = (int) (insetH - cropY); } else { crx = insetW; cry = insetH; } // Amount needed to move cropped page into correct position int offsetY = (int) (mediaH - cropH); // Adjust the offset more in cases like costena if (!pageData.getMediaValue(pageNumber).isEmpty()) { offsetY -= pageData.getMediaBoxHeight(pageNumber) - (int) (cropY + cropH) - pageData.getCropBoxY(pageNumber); } crw = (int) (cropW); crh = (int) (cropH); cry += offsetY; } @Override public int[] getCursorBoxOnScreenAsArray() { return cursorBoxOnScreen; } @Override public void updateCursorBoxOnScreen(final int[] newOutlineRectangle, final int outlineColor, final int pageNumber, final int x_size, final int y_size) { if (displayView != Display.SINGLE_PAGE && getPageSize(displayView)[0] == 0 && getPageSize(displayView)[1] == 0) { return; } if (newOutlineRectangle != null) { final int x = newOutlineRectangle[0] - pageData.getCropBoxX(pageNumber); final int y = newOutlineRectangle[1] - pageData.getCropBoxY(pageNumber); final int w = newOutlineRectangle[2]; final int h = newOutlineRectangle[3]; cursorBoxOnScreen = new int[]{x, y, w, h}; if (DecoderOptions.showMouseBox) { //Setup Cursor box. final Rectangle cursorRect = new Rectangle(x, y, w, h); cursorRect.setStroke(JavaFXPreferences.shiftColorSpaceToFX(outlineColor)); cursorRect.setFill(Color.TRANSPARENT); //Draw Cursor box. if (pdf.getChildren().contains(cursorBoxPane)) { cursorBoxPane.getChildren().clear(); cursorBoxPane.getChildren().add(cursorRect); pdf.getChildren().remove(cursorBoxPane); } pdf.getChildren().add(cursorBoxPane); } } else { cursorBoxOnScreen = null; if (pdf.getChildren().contains(cursorBoxPane)) { cursorBoxPane.getChildren().clear(); pdf.getChildren().remove(cursorBoxPane); } } } @Override public java.awt.Rectangle getDisplayedRectangle() { final ScrollPane customFXHandle = ((JavaFxGUI) pdf.getExternalHandler(Options.MultiPageUpdate)).getPageContainer(); if (customFXHandle == null) { return new java.awt.Rectangle(0, 0, 0, 0); } final Bounds bounds = customFXHandle.getViewportBounds(); return getDisplayedRectangle(true, new java.awt.Rectangle((int) bounds.getMinX(), (int) -bounds.getMinY(), (int) bounds.getWidth(), (int) bounds.getHeight())); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy