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-2015 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
*
* ---------------
* FXDisplay.java
* ---------------
*/package org.jpedal.render;
import java.awt.image.*;
import java.util.Arrays;
import javafx.application.Platform;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.effect.BlendMode;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.transform.Affine;
import javafx.scene.transform.NonInvertibleTransformException;
import javafx.scene.transform.Transform;
//import javafx.stage.Modality;import org.jpedal.color.ColorSpaces;
import org.jpedal.color.PatternColorSpace;
import org.jpedal.constants.PDFImageProcessing;
import org.jpedal.exception.PdfException;
//import org.jpedal.examples.viewer.gui.javafx.dialog.FXMessageDialog;import org.jpedal.fonts.PdfFont;
import org.jpedal.fonts.glyph.*;
import org.jpedal.fonts.tt.TTGlyph;
import org.jpedal.io.ObjectStore;
import org.jpedal.objects.GraphicsState;
import org.jpedal.objects.raw.PdfDictionary;
import org.jpedal.utils.LogWriter;
import org.jpedal.utils.repositories.Vector_Int;
import org.jpedal.utils.repositories.Vector_Object;
import org.jpedal.utils.repositories.generic.Vector_Rectangle_Int;
import java.util.ArrayList;
import javafx.scene.image.Image;
import javafx.scene.paint.ImagePattern;
publicclassFXDisplayextendsGUIDisplay{
final Group pdfContent = new Group();
// private final ObservableList children=pdfContent.getChildren();privatefinal java.util.List collection=new ArrayList(2000);
publicFXDisplay(finalint pageNumber, finalboolean addBackground, finalint defaultSize, final ObjectStore newObjectRef){
this.rawPageNumber =pageNumber;
this.objectStoreRef = newObjectRef;
this.addBackground=addBackground;
setupArrays(defaultSize);
}
@OverridepublicvoidflushAdditionalObjOnPage(){
thrownew RuntimeException("NOt used in JavaFX implementation - please redecode the page");
}
publicFXDisplay(finalint pageNumber, final ObjectStore newObjectRef, finalboolean isPrinting){
this.rawPageNumber =pageNumber;
this.objectStoreRef = newObjectRef;
this.isPrinting=isPrinting;
setupArrays(defaultSize);
}
/* remove all page objects and flush queue */@Overridepublicvoidflush(){
// children.clear();
pageObjects.clear();
objectType.clear();
areas.clear();
currentItem = 0;
}
/*Method to add Shape, Text or image to main display on page over PDF - will be flushed on redraw*/@OverridepublicvoiddrawAdditionalObjectsOverPage(finalint[] type, final java.awt.Color[] colors, final Object[] obj)throws PdfException {
if(obj==null){
return ;
}
if(Platform.isFxApplicationThread()){
drawUserContent(type, obj, colors);
}else{
Platform.runLater(new Runnable(){
@Overridepublicvoidrun(){
try {
drawUserContent(type, obj, colors);
} catch (final PdfException e) {
//tell user and logif (LogWriter.isOutput()) {
LogWriter.writeLog("Exception with additional objects: " + e.getMessage());
}
}
}
});
}
}
/* save image in array to draw */@OverridepublicintdrawImage(finalint pageNumber, final BufferedImage image,
final GraphicsState currentGraphicsState,
finalboolean alreadyCached, final String name, finalint optionsApplied, finalint previousUse){
this.rawPageNumber =pageNumber;
float CTM[][]=currentGraphicsState.CTM;
final WritableImage fxImage = SwingFXUtils.toFXImage(image, null);
finalfloat imageW=(float) fxImage.getWidth();
finalfloat imageH=(float) fxImage.getHeight();
final ImageView im1View = new ImageView(fxImage);
// Stores the affine used on the image to use on the clip laterfloat[] affine = newfloat[6];
if(optionsApplied==PDFImageProcessing.IMAGE_INVERTED){
affine = newfloat[]{CTM[0][0]/imageW,CTM[0][1]/imageW,
CTM[1][0]/imageH,CTM[1][1]/imageH,
CTM[2][0],CTM[2][1]};
im1View.getTransforms().setAll(Transform.affine(affine[0], affine[1], affine[2], affine[3], affine[4], affine[5]));
}elseif(optionsApplied==PDFImageProcessing.NOTHING){
affine = newfloat[]{CTM[0][0]/imageW,CTM[0][1]/imageW,
-CTM[1][0]/imageH,-CTM[1][1]/imageH,
CTM[2][0]+CTM[1][0],CTM[2][1]+CTM[1][1]};
im1View.getTransforms().setAll(Transform.affine(affine[0], affine[1], affine[2], affine[3], affine[4], affine[5]));
}else{
//
}
setClip(currentGraphicsState, affine, im1View);
setBlendMode(currentGraphicsState, im1View);
addToScene(im1View);
finalfloat WidthModifier = 1;
finalfloat HeightModifier = 1;
//ignore in this case /PDFdata/baseline_screens/customers3/1773_A2.pdfif(CTM[0][0]>0 && CTM[0][0]<0.05 && CTM[0][1]!=0 && CTM[1][0]!=0 && CTM[1][1]!=0){
areas.addElement(null);
}else{
w=(int)(CTM[0][0]*WidthModifier);
if(w==0) {
w = (int) (CTM[0][1] * WidthModifier);
}
h=(int)(CTM[1][1]*HeightModifier);
if(h==0) {
h = (int) (CTM[1][0] * HeightModifier);
}
//fix for bug if sheered in low resif(!useHiResImageForDisplay && CTM[1][0]<0 && CTM[0][1]>0 && CTM[0][0]==0 && CTM[1][1]==0){
finalint tmp=w;
w=-h;
h=tmp;
}
//corrected in generationif(h<0 && !useHiResImageForDisplay) {
h = -h;
}
//fix negative height on Ghostscript image in printingfinalint x1=(int)currentGraphicsState.x;
int y1=(int)currentGraphicsState.y;
finalint w1=w;
int h1=h;
if(h1<0){
y1 += h1;
h1=-h1;
}
if(h1==0) {
h1 = 1;
}
finalint[] rectParams = {x1,y1,w1,h1};
areas.addElement(rectParams);
objectType.addElement(DynamicVectorRenderer.IMAGE);
}
if(!isRenderingToImage()){ //don ot cache image on disk if generating imagefinalboolean cacheInMemory=(image.getWidth()<100 && image.getHeight()<100) || image.getHeight()==1;
if(useHiResImageForDisplay && !cacheInMemory){
pageObjects.addElement(null);
}else {
pageObjects.addElement(image);
}
if(rawKey==null){
objectStoreRef.saveStoredImage(pageNumber+"_HIRES_"+currentItem,image,false,false,"tif");
imageIDtoName.put(currentItem,pageNumber+"_HIRES_"+currentItem);
}else{
objectStoreRef.saveStoredImage(pageNumber+"_HIRES_"+currentItem+ '_' +rawKey,image,false,false,"tif");
imageIDtoName.put(currentItem,pageNumber+"_HIRES_"+currentItem+ '_' +rawKey);
}
}
currentItem++;
return currentItem-1;
}
/*save shape in array to draw*/@OverridepublicvoiddrawShape(final Object rawShape, final GraphicsState currentGraphicsState, finalint cmd){
final Shape currentShape=(javafx.scene.shape.Shape)rawShape;
finalfloat[] affine = {currentGraphicsState.CTM[0][0], currentGraphicsState.CTM[0][1], currentGraphicsState.CTM[1][0], currentGraphicsState.CTM[1][1], currentGraphicsState.CTM[2][0], currentGraphicsState.CTM[2][1]};
// Fixes Pages from FDB-B737-FRM_nowatermark.pdf// if((affine[3] < 1 && affine[3] > 0)){// affine[3] = 1; //// }
currentShape.getTransforms().add(javafx.scene.transform.Transform.affine(affine[0], affine[1], affine[2], affine[3], affine[4], affine[5]));
//if Pattern, convert to Image with Pattern on insteadif(currentGraphicsState.nonstrokeColorSpace.getID()==ColorSpaces.Pattern){
drawPatternedShape(currentGraphicsState, (Path) currentShape);
}else{
setFXParams(currentShape,currentGraphicsState.getFillType(),currentGraphicsState, changeLineArtAndText);
setClip(currentGraphicsState, affine, currentShape);
setBlendMode(currentGraphicsState, currentShape);
addToScene(currentShape);
}
finalint[] shapeBounds = {(int)currentShape.getBoundsInLocal().getMinX(), (int)currentShape.getBoundsInLocal().getMinY()
, (int)currentShape.getBoundsInLocal().getWidth(), (int)currentShape.getBoundsInLocal().getHeight()};
pageObjects.addElement(currentShape);
objectType.addElement(DynamicVectorRenderer.SHAPE);
areas.addElement(shapeBounds);
currentItem++;
}
privatevoiddrawPatternedShape(final GraphicsState currentGraphicsState, final Path currentShape){
// if(true) return;final PatternColorSpace fillCS=(PatternColorSpace)currentGraphicsState.nonstrokeColorSpace;
//get Image as BufferedImage and convert to javafx WritableImagefinal BufferedImage imageForPattern = fillCS.getImageForPatternedShape(currentGraphicsState);
if(imageForPattern == null) {
return;
}
Image fxImage = SwingFXUtils.toFXImage(imageForPattern, null);
double iw = fxImage.getWidth();
double ih = fxImage.getHeight();
// final double xPos=currentShape.getBoundsInParent().getMinX();// final double yPos=currentShape.getBoundsInParent().getMinY();// double pw = currentShape.getBoundsInLocal().getWidth();// double ph = currentShape.getBoundsInLocal().getHeight();
ImagePattern pattern = new ImagePattern(fxImage, 0, 0, iw, ih,false);
currentShape.setStroke(new Color(0, 0, 0, 0));
currentShape.setFill(pattern);
addToScene(currentShape);
// if(true) return;// final PatternColorSpace fillCS=(PatternColorSpace)currentGraphicsState.nonstrokeColorSpace;// //get Image as BufferedImage and convert to javafx WritableImage// final BufferedImage imageForPattern = fillCS.getImageForPatternedShape(currentShape);// if(imageForPattern == null) {// return;// }//// final WritableImage pattern = SwingFXUtils.toFXImage(imageForPattern, null);// final double xPos=currentShape.getBoundsInParent().getMinX();// final double yPos=currentShape.getBoundsInParent().getMinY();//// final ImageView patternView = new ImageView(pattern);// patternView.setX(xPos+1);// patternView.setY(yPos+1); //addToScene(patternView, currentShape);
}
protectedstaticvoidsetFXParams(final Shape currentShape, finalint fillType, final GraphicsState currentGraphicsState, boolean allowColorChange){
// Removes the default black stroke on shapes
currentShape.setStroke(null);
if (fillType == GraphicsState.FILL || fillType == GraphicsState.FILLSTROKE) {
//get fill colourint fillCol=currentGraphicsState.nonstrokeColorSpace.getColor().getRGB();
if (allowColorChange) {
//If we have an alt text color, its within threshold and not an additional item, use alt colorif (textColor != null && (itemToRender == -1 || (endItem == -1 || itemToRender <= endItem)) && checkColorThreshold(fillCol)) {
fillCol = textColor.getRGB();
}
}
//get value as rgb and set current colour used in fillfinalint r = ((fillCol >> 16) & 255); //redfinalint g = ((fillCol >> 8) & 255); //greenfinalint b = ((fillCol) & 255); //bluefinaldouble a=currentGraphicsState.getAlpha(GraphicsState.FILL); //alpha
currentShape.setFill(javafx.scene.paint.Color.rgb(r,g,b,a));
}
if (fillType == GraphicsState.STROKE) {
//get fill colourint strokeCol=currentGraphicsState.strokeColorSpace.getColor().getRGB();
if (allowColorChange) {
//If we have an alt text color, its within threshold and not an additional item, use alt colorif (textColor != null && (itemToRender == -1 || (endItem == -1 || itemToRender <= endItem)) && checkColorThreshold(strokeCol)) {
strokeCol = textColor.getRGB();
}
}
//get value as rgb and set current colour used in fillfinalint r = ((strokeCol >> 16) & 255); //redfinalint g = ((strokeCol >> 8) & 255); //greenfinalint b = ((strokeCol) & 255); //bluefinaldouble a=currentGraphicsState.getAlpha(GraphicsState.STROKE); //alpha
currentShape.setStroke(javafx.scene.paint.Color.rgb(r,g,b,a));
currentGraphicsState.applyFXStroke(currentShape);
}
}
@OverridepublicvoiddrawCustom(final Object value){
addToScene((Shape) value);
}
/**
* store glyph info
* @param Trm the Trm matrix (x,y is Trm[2][0], Trm[2][1]), other values are width (usually Trm[0][0] unless
* rotated when could be Trm[0][1]) and height (usually Trm[1][1] or sometimes Trm[1][0]) Trm is defined in PDF
* specification
* @param fontSize The font size of the drawn text
* @param embeddedGlyph For displaying rendered test
* @param javaGlyph Is of type object used to draw text
* @param type The type of text rendering
* @param gs The graphics state to use
* @param textScaling An array of text scaling
* @param glyf Is of type String used to draw text in the Viewer
* @param currentFontData font of the current decoded page in the Viewer
* @param glyfWidth The width of drawn text
*/@OverridepublicvoiddrawEmbeddedText(finalfloat[][] Trm, finalint fontSize, final PdfGlyph embeddedGlyph,
final Object javaGlyph, finalint type, final GraphicsState gs, finaldouble[] textScaling, final String glyf, final PdfFont currentFontData, finalfloat glyfWidth){
//lock out type3if(type==DynamicVectorRenderer.TYPE3) {
return;
}
//case one - text is using Java to draw itif(embeddedGlyph == null && javaGlyph == null){
final Text t = new Text(glyf);
// Get the affine/**
* Set the font for the current decoded page in the Viewer
*/final Font f = Font.font(currentFontData.getGlyphData().font_family_name, fontSize);
t.setFont(f);
/**
* Set the text color (fill and stroke)
*/
setFXParams(t, GraphicsState.FILL, gs, textColor!=null);
// If the stroke is needed, fill it inif((gs.getTextRenderType() & GraphicsState.STROKE) == GraphicsState.STROKE ){
setFXParams(t, GraphicsState.STROKE, gs, textColor!=null);
}
setBlendMode(gs, t);
// Set the affinesif(type!=DynamicVectorRenderer.TRUETYPE){
finaldouble r=1d / (double) fontSize;
t.getTransforms().add(Transform.affine(textScaling[0]*r,textScaling[1]*r,textScaling[2]*r,textScaling[3]*r,Trm[2][0],Trm[2][1]));
}else{
finaldouble r=1d / (double) fontSize;
t.getTransforms().setAll(Transform.affine(Trm[0][0]*r,Trm[0][1]*r,Trm[1][0]*r,Trm[1][1]*r,Trm[2][0],Trm[2][1]));
}
finalfloat[] transform= {Trm[0][0],Trm[1][0],Trm[0][1],Trm[1][1],Trm[2][0],Trm[2][1]};
final Shape clip = gs.getFXClippingShape();
if(clip!=null && !clip.contains(Trm[2][0],Trm[2][1])){
setClip(gs, transform, t);
}
pageObjects.addElement(t);
addToScene(t);
}else { //case two - text is using our font engine// System.out.println("embeddedGlyph = "+ embeddedGlyph+" "+at+" "+Trm[0][0]);final Path path=embeddedGlyph.getPath();
path.setFillRule(FillRule.EVEN_ODD);
if(type!=DynamicVectorRenderer.TRUETYPE){
path.getTransforms().setAll(Transform.affine(textScaling[0],textScaling[1],textScaling[2],textScaling[3],textScaling[4],textScaling[5]));
}else{
finaldouble r=1d/100d;
if(!TTGlyph.useHinting) {
path.getTransforms().setAll(Transform.affine(textScaling[0], textScaling[1], textScaling[2], textScaling[3], textScaling[4], textScaling[5]));
} else {
path.getTransforms().setAll(Transform.affine(textScaling[0] * r, textScaling[1] * r, textScaling[2] * r, textScaling[3] * r, textScaling[4], textScaling[5]));
}
}
setFXParams(path,gs.getTextRenderType(),gs, textColor!=null);
setBlendMode(gs, path);
finalfloat[] transform= {Trm[0][0],Trm[1][0],Trm[0][1],Trm[1][1],Trm[2][0],Trm[2][1]};
final Shape clip = gs.getFXClippingShape();
if(clip!=null && !clip.contains(Trm[2][0],Trm[2][1])){
setClip(gs, transform, path);
}
pageObjects.addElement(path);
addToScene(path);
}
objectType.addElement(type);
if(type<0){
areas.addElement(null);
}else{
if(javaGlyph!=null){
finalint[] rectParams = {(int)(Trm[2][0]),(int)Trm[2][1],fontSize,fontSize};
areas.addElement(rectParams);
}else{
/**now text*/int realSize=fontSize;
if(realSize<0) {
realSize = -realSize;
}
finalint[] area= {(int)(Trm[2][0]),(int)Trm[2][1],realSize,realSize};
areas.addElement(area);
}
}
currentItem++;
}
/**
* When Transform.affine() is applied to the image, it's applied to the clip as well.
* This causes the clip to be transformed into the incorrect position.
*
* This code essentially un-transforms the clip so it clips correctly again.
*/privatestaticvoidsetClip(final GraphicsState currentGraphicsState, finalfloat[] affine, final Node baseNode){
final Shape clip = currentGraphicsState.getFXClippingShape();
if(clip != null){
try {
// Lock out specific matrices from being reversedif(!Arrays.equals(affine, newfloat[]{1,0,0,-1,0,0})){
// Side note: initialising a straight up Affine uses the doubles in a different orderfinal Affine inverseAff = Transform.affine(affine[0], affine[1], affine[2], affine[3], affine[4], affine[5]).createInverse();
clip.getTransforms().add(inverseAff);
}
/**
*
* PDFdata\test_data\Hand_Test\awjune2003.pdf and
* PDFdata\test_data\Hand_Test\rechnung_file.PDF
* PDFdata\test_data\Hand_Test\jj.PDF
* PDFdata\test_data\sample_pdfs\CIDs\Article7.pdf
* */boolean applyClip = clip.getBoundsInLocal().getMinX()>baseNode.getBoundsInLocal().getMinX() &&
baseNode.getBoundsInLocal().getMaxY() > clip.getBoundsInLocal().getMaxY();
if (applyClip) {
baseNode.setClip(clip);
}
} catch (final NonInvertibleTransformException ex) {
ex.printStackTrace();
}
}
}
public Group getFXPane(){
// System.out.println("getFXPane "+this);if(collection!=null && !collection.isEmpty()){
// pdfContent.getChildren().removeAll(collection);
pdfContent.getChildren().addAll(collection);
collection.clear();
}
return pdfContent;
}
protectedstaticvoidsetBlendMode(final GraphicsState gs, final Node n){
switch(gs.getBMValue()){
case PdfDictionary.Multiply:
n.setBlendMode(BlendMode.MULTIPLY);
break;
case PdfDictionary.Screen:
n.setBlendMode(BlendMode.SCREEN);
break;
case PdfDictionary.Overlay:
n.setBlendMode(BlendMode.OVERLAY);
break;
case PdfDictionary.Darken:
n.setBlendMode(BlendMode.DARKEN);
break;
case PdfDictionary.Lighten:
n.setBlendMode(BlendMode.LIGHTEN);
break;
case PdfDictionary.ColorDodge:
n.setBlendMode(BlendMode.COLOR_DODGE);
break;
case PdfDictionary.ColorBurn:
n.setBlendMode(BlendMode.COLOR_BURN);
break;
case PdfDictionary.HardLight:
n.setBlendMode(BlendMode.HARD_LIGHT);
break;
case PdfDictionary.SoftLight:
n.setBlendMode(BlendMode.SOFT_LIGHT);
break;
case PdfDictionary.Difference:
n.setBlendMode(BlendMode.DIFFERENCE);
break;
case PdfDictionary.Exclusion:
n.setBlendMode(BlendMode.EXCLUSION);
break;
default:
n.setBlendMode(null);
break;
}
}
/**
* Adds items to scene, ensuring we are on the FX thread
* @param items All the nodes that are added to the Scene
*/privatevoidaddToScene(final Node items){
collection.add(items);
}
/**
* Adds items to scene, ensuring we are on the FX thread
* @param items All the nodes that are added to the Scene
*/// private void addToScenes(final Node... items){// if(Platform.isFxApplicationThread()){// children.addAll(items);// }else{// Platform.runLater(new Runnable(){// @Override public void run() {// children.addAll(items);// }// });// }// }/**
*
* @param defaultSize The size of the array
*/privatevoidsetupArrays(finalint defaultSize){
areas=new Vector_Rectangle_Int(defaultSize);
objectType=new Vector_Int(defaultSize);
pageObjects=new Vector_Object(defaultSize);
currentItem = 0;
}
@OverridepublicvoidpaintBackground(final java.awt.Shape dirtyRegion){
if (addBackground) {
Path background = new Path();
background.getElements().add(new MoveTo(xx, yy));
background.getElements().add(new LineTo(xx, yy+(int) (h * scaling)));
background.getElements().add(new LineTo(xx+ (int) (w * scaling), yy+(int) (h * scaling)));
background.getElements().add(new LineTo(xx+ (int) (w * scaling), yy));
background.getElements().add(new LineTo(xx, yy));
background.setFill(new Color(backgroundColor.getRed()/255.0f, backgroundColor.getGreen()/255.0f, backgroundColor.getBlue()/255.0f, 1.0f));
addToScene(background);
}
}
}