Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* ===========================================
* 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
*
@LICENSE@
*
* ---------------
* SingleDisplayFX.java
* ---------------
*/
package org.jpedal.display.javafx;
import javafx.application.Platform;
import javafx.scene.Group;
import javafx.scene.Node;
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.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(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() {
return new java.awt.Rectangle(0, 0, 0, 0);
}
/**
* Performs a Bitshift so we can use Swing get sRGB with JavaFX Color.
*
* @param raw of type int
* @return Color
*/
private static final Color shiftColorSpaceToFX(final int raw) {
final int r = ((raw >> 16) & 255);
final int g = ((raw >> 8) & 255);
final int b = ((raw) & 255);
return Color.rgb(r, g, b);
}
}