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

org.jpedal.render.FXDisplay 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


 *
 * ---------------
 * FXDisplay.java
 * ---------------
 */
package org.jpedal.render;


import com.idrsolutions.pdf.color.shading.ShadingFactory;

import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Arrays;

import javafx.application.Platform;
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.Bounds;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.effect.BlendMode;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.paint.*;
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 org.jpedal.color.*;
import org.jpedal.exception.PdfException;
import org.jpedal.fonts.PdfFont;
import org.jpedal.fonts.glyph.PdfGlyph;
import org.jpedal.fonts.tt.TTGlyph;
import org.jpedal.function.FunctionFactory;
import org.jpedal.function.PDFFunction;
import org.jpedal.io.ObjectStore;
import org.jpedal.io.PdfObjectReader;
import org.jpedal.objects.GraphicsState;
import org.jpedal.objects.raw.PatternObject;
import org.jpedal.objects.raw.PdfArrayIterator;
import org.jpedal.objects.raw.PdfDictionary;
import org.jpedal.objects.raw.PdfObject;
import org.jpedal.utils.LogWriter;
import org.jpedal.utils.Matrix;
import org.jpedal.utils.repositories.Vector_Int;
import org.jpedal.utils.repositories.Vector_Object;
import org.jpedal.utils.repositories.generic.Vector_Rectangle_Int;


public class FXDisplay extends GUIDisplay {


    private int xx, yy;

    final Group pdfContent = new Group();

    // private final ObservableList children=pdfContent.getChildren();

    private final java.util.List collection = new ArrayList(2000);

    public FXDisplay(final int pageNumber, final boolean addBackground, final int defaultSize, final ObjectStore newObjectRef) {

        this.rawPageNumber = pageNumber;
        this.objectStoreRef = newObjectRef;
        this.addBackground = addBackground;

        setupArrays(defaultSize);

    }

    public void setInset(final DynamicVectorRenderer currentDisplay, final int x, final int y) {
        ((FXDisplay) currentDisplay).setInset(x, y);
    }

    public void setInset(final int x, final int y) {
        xx = x;
        yy = y;

    }

    public FXDisplay(final int pageNumber, final ObjectStore newObjectRef, final boolean isPrinting) {

        this.rawPageNumber = pageNumber;
        this.objectStoreRef = newObjectRef;
        this.isPrinting = isPrinting;

        setupArrays(defaultSize);

    }

    /**
     * Add output to correct area so we can assemble later.
     * Can also be used for any specific code features (ie setting a value)
     */
    @Override
    public synchronized void writeCustom(final int section, final Object str) {

        switch (section) {

            case FLUSH:
                flush();
                break;

            default:
                super.writeCustom(section, str);
        }
    }

    /* remove all page objects and flush queue */
    private void flush() {

        // 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*/
    @Override
    public void drawAdditionalObjectsOverPage(final int[] 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() {
                @Override
                public void run() {
                    try {
                        drawUserContent(type, obj, colors);
                    } catch (final PdfException e) {
                        LogWriter.writeLog("Exception with additional objects: " + e.getMessage());
                    }
                }
            });
        }
    }

    /* save image in array to draw */
    @Override
    public int drawImage(final int pageNumber, final BufferedImage image,
                         final GraphicsState currentGraphicsState,
                         final boolean alreadyCached, final String name, final int previousUse) {

        this.rawPageNumber = pageNumber;
        final float[][] CTM = currentGraphicsState.CTM;

        final WritableImage fxImage = SwingFXUtils.toFXImage(image, null);

        final float imageW = (float) fxImage.getWidth();
        final float imageH = (float) fxImage.getHeight();

        final ImageView im1View = new ImageView(fxImage);

        // Stores the affine used on the image to use on the clip later
        final float[] affine = {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]));

        setClip(currentGraphicsState, affine, im1View);
        setBlendMode(currentGraphicsState, im1View);

        addToScene(im1View);

        final float WidthModifier = 1;
        final float HeightModifier = 1;

        //ignore in this case /PDFdata/baseline_screens/customers3/1773_A2.pdf
        if (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 negative height on Ghostscript image in printing
            final int x1 = (int) currentGraphicsState.x;
            int y1 = (int) currentGraphicsState.y;
            final int w1 = w;
            int h1 = h;
            if (h1 < 0) {
                y1 += h1;
                h1 = -h1;
            }

            if (h1 == 0) {
                h1 = 1;
            }

            final int[] rectParams = {x1, y1, w1, h1};

            areas.addElement(rectParams);
            objectType.addElement(DynamicVectorRenderer.IMAGE);
        }

        final boolean cacheInMemory = (image.getWidth() < 100 && image.getHeight() < 100) || image.getHeight() == 1;
        if (!cacheInMemory) {
            pageObjects.addElement(null);
        } else {
            pageObjects.addElement(image);
        }

        if (rawKey == null) {
            objectStoreRef.saveStoredImageAsBytes(pageNumber + "_HIRES_" + currentItem, image, false);
            imageIDtoName.put(currentItem, pageNumber + "_HIRES_" + currentItem);
        } else {
            objectStoreRef.saveStoredImageAsBytes(pageNumber + "_HIRES_" + currentItem + '_' + rawKey, image, false);
            imageIDtoName.put(currentItem, pageNumber + "_HIRES_" + currentItem + '_' + rawKey);
        }

        currentItem++;

        return currentItem - 1;
    }

    /*save shape in array to draw*/
    @Override
    public void drawShape(final Object rawShape, final GraphicsState currentGraphicsState) {

        final Shape currentShape = (javafx.scene.shape.Shape) rawShape;

        final float[] 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 instead
        if (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);
        }
        final int[] 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++;

    }

    private void drawPatternedShape(final GraphicsState currentGraphicsState, final Path currentShape) {
        final PatternColorSpace patternCS = (PatternColorSpace) currentGraphicsState.nonstrokeColorSpace;
        final Bounds bounds = currentShape.getBoundsInParent();

        final PatternObject patternObj = patternCS.getPatternObj();
        final int patternType = patternObj.getInt(PdfDictionary.PatternType);
        if (patternType == 1) { //tiling pattern
            //get Image as BufferedImage and convert to javafx WritableImage
            final BufferedImage imageForPattern = patternCS.getImageForPatternedShape(currentGraphicsState);
            if (imageForPattern == null) {
                return;
            }
            final Image fxImage = SwingFXUtils.toFXImage(imageForPattern, null);
            final double iw = fxImage.getWidth();
            final 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();  
            final ImagePattern pattern = new ImagePattern(fxImage, 0, 0, iw, ih, false);
            currentShape.setStroke(new Color(0, 0, 0, 0));
            currentShape.setFill(pattern);

        } else {
            currentShape.setFill(getShadingPaint(patternObj, patternCS, bounds));
        }

        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);
    }

    private static Paint getShadingPaint(final PatternObject patternObj, final PatternColorSpace patternCS, final Bounds bounds) {

        final PdfObjectReader currentPdfFile = patternCS.getObjectReader();
        final PdfObject shading = patternObj.getDictionary(PdfDictionary.Shading);
        final PdfArrayIterator ColorSpace = shading.getMixedArray(PdfDictionary.ColorSpace);
        final GenericColorSpace newColorSpace = ColorspaceFactory.getColorSpaceInstance(currentPdfFile, ColorSpace);

        float[][] matrix = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
        final float[] inputs = patternObj.getFloatArray(PdfDictionary.Matrix);
        if (inputs != null) {
            matrix = new float[][]{{inputs[0], inputs[1], 0f}, {inputs[2], inputs[3], 0f}, {inputs[4], inputs[5], 1f}};
        }

        final int shadingType = shading.getInt(PdfDictionary.ShadingType);
        final float[] background = shading.getFloatArray(PdfDictionary.Background);

        final PdfObject functionObj = shading.getDictionary(PdfDictionary.Function);
        final PdfArrayIterator keys = shading.getMixedArray(PdfDictionary.Function);
        PDFFunction[] function = null;
        if (functionObj != null) {
            function = new PDFFunction[1];
            function[0] = FunctionFactory.getFunction(functionObj, currentPdfFile);
        } else if (keys != null) {
            int functionCount = 0;
            if (keys != null) {
                functionCount = keys.getTokenCount();
            }

            if (keys != null) {
                final PdfObject[] subFunction = new PdfObject[functionCount];

                for (int i = 0; i < functionCount; i++) {

                    subFunction[i] = ColorspaceFactory.getFunctionObjectFromRefOrDirect(currentPdfFile, keys.getNextValueAsByte(true));

                }
                function = new PDFFunction[subFunction.length];
                for (int i1 = 0, imax = subFunction.length; i1 < imax; i1++) {
                    function[i1] = FunctionFactory.getFunction(subFunction[i1], currentPdfFile);
                }
            }
        }

        if (shadingType == 2) {
            return getAxialPaint(newColorSpace, background, shading, matrix, function, bounds);
        } else {
            return new Color(0, 0, 0, 0);
        }

    }

    private static Paint getAxialPaint(final GenericColorSpace shadingColorSpace, final float[] background, final PdfObject shadingObject, final float[][] mm, final PDFFunction[] function, final Bounds bounds) {

        float[] domain = shadingObject.getFloatArray(PdfDictionary.Domain);
        if (domain == null) {
            domain = new float[]{0.0f, 1.0f};
        }
        boolean[] extension = shadingObject.getBooleanArray(PdfDictionary.Extend);
        if (extension == null) {
            extension = new boolean[]{false, false};
        }

        Color bgColor = new Color(0, 0, 0, 0);

        if (background != null) {
            shadingColorSpace.setColor(background, 4);
            shadingColorSpace.getColor();
            final PdfPaint pp = shadingColorSpace.getColor();
            final int rgb = pp.getRGB();
            bgColor = new Color(((rgb >> 16) & 0xff) / 255.0, ((rgb >> 8) & 0xff) / 255.0, (rgb & 0xff) / 255.0, 1);
        }

        Color colorE0 = bgColor;
        Color colorE1 = bgColor;

        final float[] coords = shadingObject.getFloatArray(PdfDictionary.Coords);

        float x0 = coords[0];
        float y0 = coords[1];
        float x1 = coords[2];
        float y1 = coords[3];

        float[] temp = Matrix.transformPoint(mm, x0, y0);
        x0 = temp[0];
        y0 = temp[1];

        temp = Matrix.transformPoint(mm, x1, y1);
        x1 = temp[0];
        y1 = temp[1];

        final float t0 = domain[0];
        final float t1 = domain[1];

        final Color colorT0 = calculateColor(t0, shadingColorSpace, function);
        final Color colorT1 = calculateColor(t1, shadingColorSpace, function);

        colorE0 = extension[0] ? colorT0 : colorE0;
        colorE1 = extension[1] ? colorT1 : colorE1;

        final Stop[] stops = {new Stop(0, colorE0), new Stop(0.01, colorT0), new Stop(0.99, colorT1), new Stop(1, colorE1)};
//        Stop[] stops = new Stop[]{new Stop(0.1, colorT0), new Stop(0.9, colorT1)};
        if (1 == 2) {
            Matrix.show(mm);
            final double bx = bounds.getMinX();
            final double by = bounds.getMinY();
            final double mx = bounds.getMaxX();
            final double my = bounds.getMaxY();

            System.out.println(bx + by + mx + my);
        }
        return new LinearGradient(x0, y0, x1, y1, false, CycleMethod.NO_CYCLE, stops);
    }

    private static Color calculateColor(final float val, final GenericColorSpace shadingColorSpace, final PDFFunction[] function) {
        final float[] colValues = ShadingFactory.applyFunctions(function, new float[]{val});
        shadingColorSpace.setColor(colValues, colValues.length);
        final PdfPaint pp = shadingColorSpace.getColor();
        final int rgb = pp.getRGB();
        return new Color(((rgb >> 16) & 0xff) / 255.0, ((rgb >> 8) & 0xff) / 255.0, (rgb & 0xff) / 255.0, 1);
    }

    protected void setFXParams(final Shape currentShape, final int fillType, final GraphicsState currentGraphicsState, final boolean allowColorChange) {

        // Removes the default black stroke on shapes
        currentShape.setStroke(null);

        if (fillType == GraphicsState.FILL || fillType == GraphicsState.FILLSTROKE) {

            //get fill colour
            int fillCol = currentGraphicsState.nonstrokeColorSpace.getColor().getRGB();

            if (allowColorChange) {
                //If we have an alt text color, its within threshold and not an additional item, use alt color
                if (textColor != null && (itemToRender == -1 || (endItem == -1 || itemToRender <= endItem)) && checkColorThreshold(fillCol)) {
                    fillCol = textColor.getRGB();
                }
            }
            //get value as rgb and set current colour used in fill
            final int r = ((fillCol >> 16) & 255);    //red
            final int g = ((fillCol >> 8) & 255);     //green
            final int b = ((fillCol) & 255);          //blue
            final double a = currentGraphicsState.getAlpha(GraphicsState.FILL);     //alpha

            currentShape.setFill(javafx.scene.paint.Color.rgb(r, g, b, a));
        }

        if (fillType == GraphicsState.STROKE) {

            //get fill colour
            int strokeCol = currentGraphicsState.strokeColorSpace.getColor().getRGB();

            if (allowColorChange) {
                //If we have an alt text color, its within threshold and not an additional item, use alt color
                if (textColor != null && (itemToRender == -1 || (endItem == -1 || itemToRender <= endItem)) && checkColorThreshold(strokeCol)) {
                    strokeCol = textColor.getRGB();
                }
            }

            //get value as rgb and set current colour used in fill
            final int r = ((strokeCol >> 16) & 255);    //red
            final int g = ((strokeCol >> 8) & 255);     //green
            final int b = ((strokeCol) & 255);          //blue
            final double a = currentGraphicsState.getAlpha(GraphicsState.STROKE);     //alpha

            currentShape.setStroke(javafx.scene.paint.Color.rgb(r, g, b, a));
            currentGraphicsState.applyFXStroke(currentShape);
        }
    }

    @Override
    public void drawCustom(final Object value) {

        addToScene((Node) 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
     */
    @Override
    public void drawEmbeddedText(final float[][] Trm, final int fontSize, final PdfGlyph embeddedGlyph,
                                 final Object javaGlyph, final int type, final GraphicsState gs, final double[] textScaling, final String glyf, final PdfFont currentFontData, final float glyfWidth) {

        //lock out type3
        if (type == DynamicVectorRenderer.TYPE3) {
            return;
        }

        //case one - text is using Java to draw it
        if (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 in
            if ((gs.getTextRenderType() & GraphicsState.STROKE) == GraphicsState.STROKE) {
                setFXParams(t, GraphicsState.STROKE, gs, textColor != null);
            }

            setBlendMode(gs, t);

            // Set the affines
            if (type != DynamicVectorRenderer.TRUETYPE) {
                final double r = 1d / 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 {
                final double r = 1d / 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]));
            }

            final float[] 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 = (Path) embeddedGlyph.getPath();

            if (path == null) {
                if (LogWriter.isRunningFromIDE) {
                    System.out.println("Null FX path in " + embeddedGlyph);
                }

                return;
            }

            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 {
                final double 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);

            final float[] 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) {
                final int[] 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;
                }
                final int[] 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. */ private static void setClip(final GraphicsState currentGraphicsState, final float[] affine, final Node baseNode) { final Shape clip = currentGraphicsState.getFXClippingShape(); if (clip != null) { try { // Lock out specific matrices from being reversed if (!Arrays.equals(affine, new float[]{1, 0, 0, -1, 0, 0})) { // Side note: initialising a straight up Affine uses the doubles in a different order final 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 * */ //remove hacky fix with clip to make 23700 work correctly // 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; } protected static void setBlendMode(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 */ private void addToScene(final Node items) { collection.add(items); } /** * @param defaultSize The size of the array */ private void setupArrays(final int defaultSize) { areas = new Vector_Rectangle_Int(defaultSize); objectType = new Vector_Int(defaultSize); pageObjects = new Vector_Object(defaultSize); currentItem = 0; } @Override public void paintBackground(final java.awt.Shape dirtyRegion) { if (addBackground) { final 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); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy