2222
2323package processing .javafx ;
2424
25+ import com .sun .javafx .geom .Path2D ;
26+ import com .sun .javafx .geom .PathIterator ;
27+ import com .sun .javafx .geom .Shape ;
28+
2529import java .nio .IntBuffer ;
2630
2731import javafx .scene .SnapshotParameters ;
3539import javafx .scene .paint .Color ;
3640import javafx .scene .paint .Paint ;
3741import javafx .scene .shape .ArcType ;
38- import javafx .scene .shape .ClosePath ;
39- import javafx .scene .shape .Path ;
4042import javafx .scene .shape .StrokeLineCap ;
4143import javafx .scene .shape .StrokeLineJoin ;
4244import javafx .scene .transform .Affine ;
@@ -53,12 +55,14 @@ public class PGraphicsFX2D extends PGraphics {
5355
5456 WritableImage snapshotImage ;
5557
56- Path workPath ;
57- Path auxPath ;
58+ Path2D workPath = new Path2D () ;
59+ Path2D auxPath = new Path2D () ;
5860 boolean openContour ;
5961 /// break the shape at the next vertex (next vertex() call is a moveto())
6062 boolean breakShape ;
6163
64+ private float pathCoordsBuffer [] = new float [6 ];
65+
6266 /// coordinates for internal curve calculation
6367 float [] curveCoordX ;
6468 float [] curveCoordY ;
@@ -197,15 +201,14 @@ public void endDraw() {
197201 public void beginShape (int kind ) {
198202 shape = kind ;
199203 vertexCount = 0 ;
200- curveVertexCount = 0 ;
201204
202- // set gpath to null, because when mixing curves and straight
203- // lines, vertexCount will be set back to zero, so vertexCount == 1
204- // is no longer a good indicator of whether the shape is new.
205- // this way, just check to see if gpath is null, and if it isn't
206- // then just use it to continue the shape.
207- workPath = null ;
208- auxPath = null ;
205+ workPath . reset ();
206+ auxPath . reset ();
207+
208+ if ( drawingThinLines ()) {
209+ pushMatrix ();
210+ translate ( 0.5f , 0.5f ) ;
211+ }
209212 }
210213
211214
@@ -226,9 +229,6 @@ public void texture(PImage image) {
226229
227230 @ Override
228231 public void vertex (float x , float y ) {
229- curveVertexCount = 0 ;
230- //float vertex[];
231-
232232 if (vertexCount == vertices .length ) {
233233 float temp [][] = new float [vertexCount <<1 ][VERTEX_FIELD_COUNT ];
234234 System .arraycopy (vertices , 0 , temp , 0 , vertexCount );
@@ -322,13 +322,11 @@ public void vertex(float x, float y) {
322322 break ;
323323
324324 case POLYGON :
325- if (workPath == null ) {
326- context .moveTo (x , y );
327- } else if (breakShape ) {
328- context .moveTo (x , y );
325+ if (workPath .getNumCommands () == 0 || breakShape ) {
326+ workPath .moveTo (x , y );
329327 breakShape = false ;
330328 } else {
331- context .lineTo (x , y );
329+ workPath .lineTo (x , y );
332330 }
333331 break ;
334332 }
@@ -367,16 +365,14 @@ public void beginContour() {
367365 }
368366
369367 // draw contours to auxiliary path so main path can be closed later
370- Path temp = auxPath ;
368+ Path2D contourPath = auxPath ;
371369 auxPath = workPath ;
372- workPath = temp ;
370+ workPath = contourPath ;
373371
374- // if (auxPath != null) { // first contour does not break
375- breakShape = true ;
376- auxPath = new Path ();
377- // }
372+ if (contourPath .getNumCommands () > 0 ) { // first contour does not break
373+ breakShape = true ;
374+ }
378375
379- breakShape = true ;
380376 openContour = true ;
381377 }
382378
@@ -388,15 +384,9 @@ public void endContour() {
388384 return ;
389385 }
390386
391- // close this contour
392- if (workPath != null ) {
393- //gpath.closePath();
394- auxPath .getElements ().addAll (workPath .getElements ());
395- auxPath .getElements ().add (new ClosePath ());
396- }
387+ if (workPath .getNumCommands () > 0 ) workPath .closePath ();
397388
398- // switch back to main path
399- Path temp = workPath ;
389+ Path2D temp = workPath ;
400390 workPath = auxPath ;
401391 auxPath = temp ;
402392
@@ -410,21 +400,56 @@ public void endShape(int mode) {
410400 endContour ();
411401 PGraphics .showWarning ("Missing endContour() before endShape()" );
412402 }
413- if (workPath != null ) { // make sure something has been drawn
403+ if (workPath . getNumCommands () > 0 ) {
414404 if (shape == POLYGON ) {
415405 if (mode == CLOSE ) {
416- //gpath.closePath();
417- workPath .getElements ().add (new ClosePath ());
406+ workPath .closePath ();
418407 }
419- if (auxPath != null ) {
420- //gpath.append(auxPath, false);
421- workPath .getElements ().addAll (auxPath .getElements ());
408+ if (auxPath .getNumCommands () > 0 ) {
409+ workPath .append (auxPath , false );
422410 }
423- //drawShape(gpath);
424- // TODO argh, can't go this route
411+ drawShape (workPath );
425412 }
426413 }
427414 shape = 0 ;
415+
416+ if (drawingThinLines ()) {
417+ popMatrix ();
418+ }
419+ }
420+
421+
422+ private void drawShape (Shape s ) {
423+ context .beginPath ();
424+ PathIterator pi = s .getPathIterator (null );
425+ while (!pi .isDone ()) {
426+ int pitype = pi .currentSegment (pathCoordsBuffer );
427+ switch (pitype ) {
428+ case PathIterator .SEG_MOVETO :
429+ context .moveTo (pathCoordsBuffer [0 ], pathCoordsBuffer [1 ]);
430+ break ;
431+ case PathIterator .SEG_LINETO :
432+ context .lineTo (pathCoordsBuffer [0 ], pathCoordsBuffer [1 ]);
433+ break ;
434+ case PathIterator .SEG_QUADTO :
435+ context .quadraticCurveTo (pathCoordsBuffer [0 ], pathCoordsBuffer [1 ],
436+ pathCoordsBuffer [2 ], pathCoordsBuffer [3 ]);
437+ break ;
438+ case PathIterator .SEG_CUBICTO :
439+ context .bezierCurveTo (pathCoordsBuffer [0 ], pathCoordsBuffer [1 ],
440+ pathCoordsBuffer [2 ], pathCoordsBuffer [3 ],
441+ pathCoordsBuffer [4 ], pathCoordsBuffer [5 ]);
442+ break ;
443+ case PathIterator .SEG_CLOSE :
444+ context .closePath ();
445+ break ;
446+ default :
447+ showWarning ("Unknown segment type " + pitype );
448+ }
449+ pi .next ();
450+ }
451+ if (fill ) context .fill ();
452+ if (stroke ) context .stroke ();
428453 }
429454
430455
@@ -484,13 +509,24 @@ protected void blendModeImpl() {
484509 // BEZIER VERTICES
485510
486511
512+ @ Override
513+ protected void bezierVertexCheck () {
514+ if (shape == 0 || shape != POLYGON ) {
515+ throw new RuntimeException ("beginShape() or beginShape(POLYGON) " +
516+ "must be used before bezierVertex() or quadraticVertex()" );
517+ }
518+ if (workPath .getNumCommands () == 0 ) {
519+ throw new RuntimeException ("vertex() must be used at least once " +
520+ "before bezierVertex() or quadraticVertex()" );
521+ }
522+ }
523+
487524 @ Override
488525 public void bezierVertex (float x1 , float y1 ,
489526 float x2 , float y2 ,
490527 float x3 , float y3 ) {
491528 bezierVertexCheck ();
492- context .bezierCurveTo (x1 , y1 , x2 , y2 , x3 , y3 );
493-
529+ workPath .curveTo (x1 , y1 , x2 , y2 , x3 , y3 );
494530 }
495531
496532
@@ -511,7 +547,8 @@ public void bezierVertex(float x2, float y2, float z2,
511547 @ Override
512548 public void quadraticVertex (float ctrlX , float ctrlY ,
513549 float endX , float endY ) {
514- context .quadraticCurveTo (ctrlX , ctrlY , endX , endY );
550+ bezierVertexCheck ();
551+ workPath .quadTo (ctrlX , ctrlY , endX , endY );
515552 }
516553
517554
@@ -530,7 +567,12 @@ public void quadraticVertex(float x2, float y2, float z2,
530567
531568 @ Override
532569 protected void curveVertexCheck () {
533- super .curveVertexCheck ();
570+ if (shape != POLYGON ) {
571+ throw new RuntimeException ("You must use beginShape() or " +
572+ "beginShape(POLYGON) before curveVertex()" );
573+ }
574+
575+ curveInitCheck ();
534576
535577 if (curveCoordX == null ) {
536578 curveCoordX = new float [4 ];
@@ -563,14 +605,14 @@ protected void curveVertexSegment(float x1, float y1,
563605
564606 // since the paths are continuous,
565607 // only the first point needs the actual moveto
566- if (workPath == null ) {
567- // gpath = new GeneralPath( );
568- context . moveTo ( curveDrawX [ 0 ], curveDrawY [ 0 ]) ;
608+ if (workPath . getNumCommands () == 0 ) {
609+ workPath . moveTo ( curveDrawX [ 0 ], curveDrawY [ 0 ] );
610+ breakShape = false ;
569611 }
570612
571- context . bezierCurveTo (curveDrawX [1 ], curveDrawY [1 ],
572- curveDrawX [2 ], curveDrawY [2 ],
573- curveDrawX [3 ], curveDrawY [3 ]);
613+ workPath . curveTo (curveDrawX [1 ], curveDrawY [1 ],
614+ curveDrawX [2 ], curveDrawY [2 ],
615+ curveDrawX [3 ], curveDrawY [3 ]);
574616 }
575617
576618
0 commit comments