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

org.jpedal.objects.JavaFXShape Maven / Gradle / Ivy

The newest version!
/*
 * ===========================================
 * 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


 *
 * ---------------
 * JavaFXShape.java
 * ---------------
 */
package org.jpedal.objects;

import java.io.Serializable;
import javafx.collections.ObservableList;

import javafx.scene.shape.ClosePath;
import javafx.scene.shape.CubicCurveTo;
import javafx.scene.shape.FillRule;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.PathElement;
import javafx.scene.shape.QuadCurveTo;


/**
 * 

* defines the current shape which is created by command stream *

*

* This class is NOT part of the API *

. Shapes can be drawn onto pdf or used as a clip on other * image/shape/text. Shape is built up by storing commands and then turning * these commands into a shape. Has to be done this way as Winding rule is not * necessarily declared at start. */ public class JavaFXShape implements Serializable, PdfShape { /**used to stop lots of huge, complex shapes. * Note we DO NOT reset as we reuse this object and * it stores cumulative count */ int complexClipCount; /**flag to show if image is for clip*/ private boolean isClip; private Path path = new Path(); ObservableList elements = path.getElements(); private FillRule windingRule; // Stores the previously moved to path (Used for addBezierCurveV()) private final float[] currentPos = new float[2]; private boolean isClosed; ///////////////////////////////////////////////////////////////////////// /** * end a shape, storing info for later */ @Override public final void closeShape() { elements.add(new ClosePath()); } ////////////////////////////////////////////////////////////////////////// /** * add a curve to the shape */ @Override public final void addBezierCurveC( final float x, final float y, final float x2, final float y2, final float x3, final float y3 ) { elements.add(new CubicCurveTo(x,y,x2,y2,x3,y3)); currentPos[0] = x3; currentPos[1] = y3; } ////////////////////////////////////////////////////////////////////////// /** * set winding rule - non zero */ @Override public final void setNONZEROWindingRule() { setWindingRule(FillRule.NON_ZERO); } ////////////////////////////////////////////////////////////////////////// /** * add a line to the shape */ @Override public final void lineTo( final float x, final float y ) { elements.add(new LineTo(x,y)); currentPos[0] = x; currentPos[1] = y; } /////////////////////////////////////////////////////////////////////////// /** * add a curve to the shape */ @Override public final void addBezierCurveV( final float x2, final float y2, final float x3, final float y3 ) { elements.add(new CubicCurveTo(currentPos[0], currentPos[1],x2,y2,x3,y3)); currentPos[0] = x3; currentPos[1] = y3; } ////////////////////////////////////////////////////////////////////////// /** * turn shape commands into a Shape object, storing info for later. Has to * be done this way because we need the winding rule to initialise the shape * in Java, and it could be set anywhere in the command stream */ @Override public final java.awt.Shape generateShapeFromPath( final float[][] CTM, final float thickness, final int cmd, final int type){ //may need to code this in if we ever implement // isClosed=false; // set in code if H called // returns an empty path as null breaks stuff. return new java.awt.geom.GeneralPath(); /** * Code kept in case it needs to be used in future: */ //used to debug // final boolean show = false; // final boolean debug= false; //transform matrix only if needed // if((CTM[0][0] == (float)1.0)&&(CTM[1][0] == (float)0.0)&& // (CTM[2][0] == (float)0.0)&&(CTM[0][1] == (float)0.0)&& // (CTM[1][1] == (float)1.0)&&(CTM[2][1] == (float)0.0)&& // (CTM[0][2] == (float)0.0)&&(CTM[1][2] == (float)0.0)&&(CTM[2][2] == (float)1.0)){ // //don't waste time if not needed // }else{ // AffineTransform CTM_transform = new AffineTransform( CTM[0][0], CTM[0][1], CTM[1][0], CTM[1][1], CTM[2][0], CTM[2][1]); // // //apply CTM alterations // if( current_path != null ){ // // //transform // current_path.transform( CTM_transform ); // //if(CTM[0][0]==0 && CTM[1][1]==0 && CTM[0][1]<0 && CTM[1][0]>0){ // // current_path.transform(AffineTransform.getTranslateInstance(0,current_path.getBounds().height/CTM[0][1])); // //System.out.println("transforms "+CTM_transform+" "+current_path.getBounds()); // //} // }else if( current_area != null ) // current_area.transform( CTM_transform ); // } /** * fix for single rotated lines with thickness */ // if(current_path!=null && CTM[0][0]==1 && CTM[1][1]==-1 && current_path.getBounds().height==1 && thickness>10 ){ // // Rectangle currentBounds=current_path.getBounds(); // current_path = new GeneralPath( winding_rule ); // current_path.moveTo(currentBounds.x,currentBounds.y-thickness/2); // current_path.lineTo(currentBounds.x,currentBounds.y+thickness/2); // // current_path.closePath(); // // } } ////////////////////////////////////////////////////////////////////////// /** * add a rectangle to set of shapes */ @Override public final void appendRectangle( final float x, final float y, final float w, final float h ) { moveTo( x, y ); lineTo( x + w, y ); lineTo( x + w, y + h ); lineTo( x, y + h ); lineTo( x, y ); closeShape(); } ////////////////////////////////////////////////////////////////////////// /** * start a shape by creating a shape object */ @Override public final void moveTo( final float x, final float y ) { elements.add(new MoveTo(x,y)); currentPos[0] = x; currentPos[1] = y; } /** * add a curve to the shape */ @Override public final void addBezierCurveY( final float x, final float y, final float x3, final float y3 ) { elements.add(new QuadCurveTo(x,y,x3,y3)); currentPos[0] = x3; currentPos[1] = y3; } /** * reset path to empty */ @Override public final void resetPath() { path = new Path(); elements = path.getElements(); windingRule = FillRule.NON_ZERO; } /////////////////////////////////////////////////////////////////////////// /** * set winding rule - even odd */ @Override public final void setEVENODDWindingRule() { setWindingRule(FillRule.EVEN_ODD); } public final void setWindingRule(final FillRule rule){ windingRule = rule; path.setFillRule(windingRule); } /** * show the shape segments for debugging * static final private void showShape( Shape current_shape ) { PathIterator xx = current_shape.getPathIterator( null ); double[] coords = new double[6]; while( xx.isDone() == false ) { int type = xx.currentSegment( coords ); xx.next(); switch( type ) { case PathIterator.SEG_MOVETO: LogWriter.writeLog( "MoveTo" + coords[0] + ' ' + coords[1] ); if( ( coords[0] == 0 ) & ( coords[1] == 0 ) ) LogWriter.writeLog( "xxx" ); break; case PathIterator.SEG_LINETO: LogWriter.writeLog( "LineTo" + coords[0] + ' ' + coords[1] ); if( ( coords[0] == 0 ) & ( coords[1] == 0 ) ) LogWriter.writeLog( "xxx" ); break; case PathIterator.SEG_CLOSE: LogWriter.writeLog( "CLOSE" ); break; default: LogWriter.writeLog( "Other" + coords[0] + ' ' + coords[1] ); break; } } }/**/ /** * number of segments in current shape (0 if no shape or none) */ @Override public int getSegmentCount() { if(path == null){ return 0; }else { return elements.size(); } } @Override public void setClip(final boolean b) { this.isClip=b; } @Override public boolean isClip() { return isClip; } @Override public int getComplexClipCount() { return complexClipCount; } @Override public Path getPath() { // if(DEBUG) // showPath(); return path; } @Override public boolean adjustLineWidth() { throw new RuntimeException("JavaFX should not call JavaFXShape.adjustLineWidth()");//Not required in JavaFXShape (SwingShape only) } @Override public boolean isClosed() { return isClosed; } /** * ==== DEBUG CODE ==== * Prints out all the draw commands in the path */ // public void showPath(){ // System.out.println("==== Printing Path ===="); // System.out.println("Elements: " + path.getElements().size()); // System.out.println("isClip: " + isClip); // for(PathElement p: path.getElements()){ // // if(p.getClass().getCanonicalName().toLowerCase().equals("javafx.scene.shape.moveto")){ // System.out.println("MoveTo: " + Math.round(((MoveTo)p).getX()) + ", " + Math.round(((MoveTo)p).getY())); // }else if( p.getClass().getCanonicalName().toLowerCase().equals("javafx.scene.shape.lineto")){ // System.out.println("LineTo: " + Math.round(((LineTo)p).getX()) + ", " + Math.round(((LineTo)p).getX())); // }else if( p.getClass().getCanonicalName().toLowerCase().equals("javafx.scene.shape.cubiccurveto")){ // System.out.println("CubicCurveTo: " + Math.round(((CubicCurveTo)p).getX())+ ", " +Math.round(((CubicCurveTo)p).getY())+ ": x1 " + Math.round(((CubicCurveTo)p).getControlX1())+ ", y1 " // +Math.round(((CubicCurveTo)p).getControlY1())+ ", x2 " + Math.round(((CubicCurveTo)p).getControlX2())+ ", y2 " + + Math.round(((CubicCurveTo)p).getControlY2())); // }else if( p.getClass().getCanonicalName().toLowerCase().equals("javafx.scene.shape.closepath")){ // System.out.println("ClosePath"); // } // } // System.out.println("========="); // } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy