break PShape into AWT and non-AWT code

This commit is contained in:
Ben Fry
2015-06-21 22:58:41 -04:00
parent ef9d4c4d2f
commit bf05f41bb9
3 changed files with 391 additions and 332 deletions

View File

@@ -40,9 +40,11 @@ import processing.core.*;
* <p>
* To get access to the Java 2D "Graphics2D" object for the default
* renderer, use:
* <PRE>Graphics2D g2 = ((PGraphicsJava2D)g).g2;</PRE>
* This will let you do Java 2D stuff directly, but is not supported in
* any way shape or form. Which just means "have fun, but don't complain
* <PRE>
* Graphics2D g2 = (Graphics2D) g.getNative();
* </PRE>
* This will let you do Graphics2D calls directly, but is not supported
* in any way shape or form. Which just means "have fun, but don't complain
* if it breaks."
* <p>
* Advanced <a href="http://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-Desktop/html/java2d.html">debugging notes</a> for Java2D.
@@ -1822,7 +1824,7 @@ public class PGraphicsJava2D extends PGraphics {
public PShape loadShape(String filename, String options) {
String extension = PApplet.getExtension(filename);
if (extension.equals("svg") || extension.equals("svgz")) {
return new PShapeSVG(parent.loadXML(filename));
return new PShapeJava2D(parent.loadXML(filename));
}
PGraphics.showWarning("Unsupported format: " + filename);
return null;

View File

@@ -0,0 +1,346 @@
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
Part of the Processing project - http://processing.org
Copyright (c) 2015 The Processing Foundation
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License version 2.1 as published by the Free Software Foundation.
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
*/
package processing.awt;
import java.awt.Paint;
import java.awt.PaintContext;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import processing.core.PApplet;
import processing.core.PGraphics;
import processing.core.PShapeSVG;
import processing.data.*;
/**
* Implements features for PShape that are specific to AWT and Java2D.
* At the moment, this is gradients and java.awt.Paint handling.
*/
public class PShapeJava2D extends PShapeSVG {
Paint strokeGradientPaint;
Paint fillGradientPaint;
public PShapeJava2D(XML svg) {
super(svg);
}
@Override
protected void setParent(PShapeSVG parent) {
if (parent instanceof PShapeJava2D) {
PShapeJava2D pj = (PShapeJava2D) parent;
fillGradientPaint = pj.fillGradientPaint;
strokeGradientPaint = pj.strokeGradientPaint;
} else { // parent is null or not Java2D
fillGradientPaint = null;
strokeGradientPaint = null;
}
}
static class LinearGradientPaint implements Paint {
float x1, y1, x2, y2;
float[] offset;
int[] color;
int count;
float opacity;
public LinearGradientPaint(float x1, float y1, float x2, float y2,
float[] offset, int[] color, int count,
float opacity) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.offset = offset;
this.color = color;
this.count = count;
this.opacity = opacity;
}
public PaintContext createContext(ColorModel cm,
Rectangle deviceBounds, Rectangle2D userBounds,
AffineTransform xform, RenderingHints hints) {
Point2D t1 = xform.transform(new Point2D.Float(x1, y1), null);
Point2D t2 = xform.transform(new Point2D.Float(x2, y2), null);
return new LinearGradientContext((float) t1.getX(), (float) t1.getY(),
(float) t2.getX(), (float) t2.getY());
}
public int getTransparency() {
return TRANSLUCENT; // why not.. rather than checking each color
}
public class LinearGradientContext implements PaintContext {
int ACCURACY = 2;
float tx1, ty1, tx2, ty2;
public LinearGradientContext(float tx1, float ty1, float tx2, float ty2) {
this.tx1 = tx1;
this.ty1 = ty1;
this.tx2 = tx2;
this.ty2 = ty2;
}
public void dispose() { }
public ColorModel getColorModel() { return ColorModel.getRGBdefault(); }
public Raster getRaster(int x, int y, int w, int h) {
WritableRaster raster =
getColorModel().createCompatibleWritableRaster(w, h);
int[] data = new int[w * h * 4];
// make normalized version of base vector
float nx = tx2 - tx1;
float ny = ty2 - ty1;
float len = (float) Math.sqrt(nx*nx + ny*ny);
if (len != 0) {
nx /= len;
ny /= len;
}
int span = (int) PApplet.dist(tx1, ty1, tx2, ty2) * ACCURACY;
if (span <= 0) {
//System.err.println("span is too small");
// annoying edge case where the gradient isn't legit
int index = 0;
for (int j = 0; j < h; j++) {
for (int i = 0; i < w; i++) {
data[index++] = 0;
data[index++] = 0;
data[index++] = 0;
data[index++] = 255;
}
}
} else {
int[][] interp = new int[span][4];
int prev = 0;
for (int i = 1; i < count; i++) {
int c0 = color[i-1];
int c1 = color[i];
int last = (int) (offset[i] * (span-1));
//System.out.println("last is " + last);
for (int j = prev; j <= last; j++) {
float btwn = PApplet.norm(j, prev, last);
interp[j][0] = (int) PApplet.lerp((c0 >> 16) & 0xff, (c1 >> 16) & 0xff, btwn);
interp[j][1] = (int) PApplet.lerp((c0 >> 8) & 0xff, (c1 >> 8) & 0xff, btwn);
interp[j][2] = (int) PApplet.lerp(c0 & 0xff, c1 & 0xff, btwn);
interp[j][3] = (int) (PApplet.lerp((c0 >> 24) & 0xff, (c1 >> 24) & 0xff, btwn) * opacity);
//System.out.println(j + " " + interp[j][0] + " " + interp[j][1] + " " + interp[j][2]);
}
prev = last;
}
int index = 0;
for (int j = 0; j < h; j++) {
for (int i = 0; i < w; i++) {
//float distance = 0; //PApplet.dist(cx, cy, x + i, y + j);
//int which = PApplet.min((int) (distance * ACCURACY), interp.length-1);
float px = (x + i) - tx1;
float py = (y + j) - ty1;
// distance up the line is the dot product of the normalized
// vector of the gradient start/stop by the point being tested
int which = (int) ((px*nx + py*ny) * ACCURACY);
if (which < 0) which = 0;
if (which > interp.length-1) which = interp.length-1;
//if (which > 138) System.out.println("grabbing " + which);
data[index++] = interp[which][0];
data[index++] = interp[which][1];
data[index++] = interp[which][2];
data[index++] = interp[which][3];
}
}
}
raster.setPixels(0, 0, w, h, data);
return raster;
}
}
}
static class RadialGradientPaint implements Paint {
float cx, cy, radius;
float[] offset;
int[] color;
int count;
float opacity;
public RadialGradientPaint(float cx, float cy, float radius,
float[] offset, int[] color, int count,
float opacity) {
this.cx = cx;
this.cy = cy;
this.radius = radius;
this.offset = offset;
this.color = color;
this.count = count;
this.opacity = opacity;
}
public PaintContext createContext(ColorModel cm,
Rectangle deviceBounds, Rectangle2D userBounds,
AffineTransform xform, RenderingHints hints) {
return new RadialGradientContext();
}
public int getTransparency() {
return TRANSLUCENT;
}
public class RadialGradientContext implements PaintContext {
int ACCURACY = 5;
public void dispose() {}
public ColorModel getColorModel() { return ColorModel.getRGBdefault(); }
public Raster getRaster(int x, int y, int w, int h) {
WritableRaster raster =
getColorModel().createCompatibleWritableRaster(w, h);
int span = (int) radius * ACCURACY;
int[][] interp = new int[span][4];
int prev = 0;
for (int i = 1; i < count; i++) {
int c0 = color[i-1];
int c1 = color[i];
int last = (int) (offset[i] * (span - 1));
for (int j = prev; j <= last; j++) {
float btwn = PApplet.norm(j, prev, last);
interp[j][0] = (int) PApplet.lerp((c0 >> 16) & 0xff, (c1 >> 16) & 0xff, btwn);
interp[j][1] = (int) PApplet.lerp((c0 >> 8) & 0xff, (c1 >> 8) & 0xff, btwn);
interp[j][2] = (int) PApplet.lerp(c0 & 0xff, c1 & 0xff, btwn);
interp[j][3] = (int) (PApplet.lerp((c0 >> 24) & 0xff, (c1 >> 24) & 0xff, btwn) * opacity);
}
prev = last;
}
int[] data = new int[w * h * 4];
int index = 0;
for (int j = 0; j < h; j++) {
for (int i = 0; i < w; i++) {
float distance = PApplet.dist(cx, cy, x + i, y + j);
int which = PApplet.min((int) (distance * ACCURACY), interp.length-1);
data[index++] = interp[which][0];
data[index++] = interp[which][1];
data[index++] = interp[which][2];
data[index++] = interp[which][3];
}
}
raster.setPixels(0, 0, w, h, data);
return raster;
}
}
}
protected Paint calcGradientPaint(Gradient gradient) {
if (gradient instanceof LinearGradient) {
LinearGradient grad = (LinearGradient) gradient;
return new LinearGradientPaint(grad.x1, grad.y1, grad.x2, grad.y2,
grad.offset, grad.color, grad.count,
opacity);
} else if (gradient instanceof RadialGradient) {
RadialGradient grad = (RadialGradient) gradient;
return new RadialGradientPaint(grad.cx, grad.cy, grad.r,
grad.offset, grad.color, grad.count,
opacity);
}
return null;
}
// protected Paint calcGradientPaint(Gradient gradient,
// float x1, float y1, float x2, float y2) {
// if (gradient instanceof LinearGradient) {
// LinearGradient grad = (LinearGradient) gradient;
// return new LinearGradientPaint(x1, y1, x2, y2,
// grad.offset, grad.color, grad.count,
// opacity);
// }
// throw new RuntimeException("Not a linear gradient.");
// }
// protected Paint calcGradientPaint(Gradient gradient,
// float cx, float cy, float r) {
// if (gradient instanceof RadialGradient) {
// RadialGradient grad = (RadialGradient) gradient;
// return new RadialGradientPaint(cx, cy, r,
// grad.offset, grad.color, grad.count,
// opacity);
// }
// throw new RuntimeException("Not a radial gradient.");
// }
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
@Override
protected void styles(PGraphics g) {
super.styles(g);
//if (g instanceof PGraphicsJava2D) {
PGraphicsJava2D p2d = (PGraphicsJava2D) g;
if (strokeGradient != null) {
p2d.strokeGradient = true;
if (strokeGradientPaint == null) {
strokeGradientPaint = calcGradientPaint(strokeGradient);
}
p2d.strokeGradientObject = strokeGradientPaint;
} else {
// need to shut off, in case parent object has a gradient applied
//p2d.strokeGradient = false;
}
if (fillGradient != null) {
p2d.fillGradient = true;
if (fillGradientPaint == null) {
fillGradientPaint = calcGradientPaint(fillGradient);
}
p2d.fillGradientObject = fillGradientPaint;
} else {
// need to shut off, in case parent object has a gradient applied
//p2d.fillGradient = false;
}
//}
}
}

View File

@@ -3,7 +3,8 @@
/*
Part of the Processing project - http://processing.org
Copyright (c) 2006-11 Ben Fry and Casey Reas
Copyright (c) 2012-15 The Processing Foundation
Copyright (c) 2006-12 Ben Fry and Casey Reas
Copyright (c) 2004-06 Michael Chang
This library is free software; you can redistribute it and/or
@@ -23,19 +24,12 @@
package processing.core;
import processing.awt.PGraphicsJava2D;
import processing.data.*;
import java.awt.Paint;
import java.awt.PaintContext;
import java.awt.Rectangle;
import java.awt.RenderingHints;
// TODO replace these with PMatrix2D
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.util.Map;
import java.util.HashMap;
@@ -95,30 +89,23 @@ public class PShapeSVG extends PShape {
XML element;
/// Values between 0 and 1.
float opacity;
protected float opacity;
float strokeOpacity;
float fillOpacity;
/**
* Used for percentages. Width of containing SVG.
*/
/** Width of containing SVG (used for percentages). */
protected float svgWidth;
/**
* Used for percentages. Height of containing SVG.
*/
/** Height of containing SVG (used for percentages). */
protected float svgHeight;
/**
* Used for percentages. √((w² + h²)/2) of containing SVG.
*/
/** √((w² + h²)/2) of containing SVG (used for percentages). */
protected float svgXYSize;
Gradient strokeGradient;
Paint strokeGradientPaint;
protected Gradient strokeGradient;
String strokeName; // id of another object, gradients only?
Gradient fillGradient;
Paint fillGradientPaint;
protected Gradient fillGradient;
String fillName; // id of another object
@@ -150,7 +137,9 @@ public class PShapeSVG extends PShape {
}
protected PShapeSVG(PShapeSVG parent, XML properties, boolean parseKids) {
// Broken out so that subclasses can copy any additional variables
// (i.e. fillGradientPaint and strokeGradientPaint)
protected void setParent(PShapeSVG parent) {
// Need to set this so that findChild() works.
// Otherwise 'parent' is null until addChild() is called later.
this.parent = parent;
@@ -163,13 +152,13 @@ public class PShapeSVG extends PShape {
strokeCap = PConstants.SQUARE; // equivalent to BUTT in svg spec
strokeJoin = PConstants.MITER;
strokeGradient = null;
strokeGradientPaint = null;
// strokeGradientPaint = null;
strokeName = null;
fill = true;
fillColor = 0xff000000;
fillGradient = null;
fillGradientPaint = null;
// fillGradientPaint = null;
fillName = null;
//hasTransform = false;
@@ -188,24 +177,26 @@ public class PShapeSVG extends PShape {
strokeCap = parent.strokeCap;
strokeJoin = parent.strokeJoin;
strokeGradient = parent.strokeGradient;
strokeGradientPaint = parent.strokeGradientPaint;
// strokeGradientPaint = parent.strokeGradientPaint;
strokeName = parent.strokeName;
fill = parent.fill;
fillColor = parent.fillColor;
fillGradient = parent.fillGradient;
fillGradientPaint = parent.fillGradientPaint;
// fillGradientPaint = parent.fillGradientPaint;
fillName = parent.fillName;
//hasTransform = parent.hasTransform;
//transformation = parent.transformation;
svgWidth = parent.svgWidth;
svgHeight = parent.svgHeight;
svgXYSize = parent.svgXYSize;
opacity = parent.opacity;
}
}
protected PShapeSVG(PShapeSVG parent, XML properties, boolean parseKids) {
setParent(parent);
// Need to get width/height in early.
if (properties.getName().equals("svg")) {
@@ -1256,7 +1247,7 @@ public class PShapeSVG extends PShape {
String name = "";
// String lColorText = colorText.toLowerCase();
Gradient gradient = null;
Paint paint = null;
// Object paint = null;
if (colorText.equals("none")) {
visible = false;
} else if (colorText.startsWith("url(#")) {
@@ -1264,7 +1255,8 @@ public class PShapeSVG extends PShape {
Object object = findChild(name);
if (object instanceof Gradient) {
gradient = (Gradient) object;
paint = calcGradientPaint(gradient); //, opacity);
// in 3.0a11, do this on first draw inside PShapeJava2D
// paint = calcGradientPaint(gradient); //, opacity);
} else {
// visible = false;
System.err.println("url " + name + " refers to unexpected data: " + object);
@@ -1278,13 +1270,13 @@ public class PShapeSVG extends PShape {
fillColor = color;
fillName = name;
fillGradient = gradient;
fillGradientPaint = paint;
// fillGradientPaint = paint;
} else {
stroke = visible;
strokeColor = color;
strokeName = name;
strokeGradient = gradient;
strokeGradientPaint = paint;
// strokeGradientPaint = paint;
}
}
@@ -1316,8 +1308,8 @@ public class PShapeSVG extends PShape {
/**
* Deliberately conforms to HTML 4.01 color spec + en-gb grey,
* not SVG's 147-color system.
* Deliberately conforms to the HTML 4.01 color spec + en-gb grey, rather
* than the (unlikely to be useful) entire 147-color system used in SVG.
*/
static protected IntDict colorNames = new IntDict(new Object[][] {
{ "aqua", 0x00ffff },
@@ -1469,12 +1461,12 @@ public class PShapeSVG extends PShape {
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
static class Gradient extends PShapeSVG {
static public class Gradient extends PShapeSVG {
AffineTransform transform;
float[] offset;
int[] color;
int count;
public float[] offset;
public int[] color;
public int count;
public Gradient(PShapeSVG parent, XML properties) {
super(parent, properties, true);
@@ -1517,8 +1509,8 @@ public class PShapeSVG extends PShape {
}
static class LinearGradient extends Gradient {
float x1, y1, x2, y2;
public class LinearGradient extends Gradient {
public float x1, y1, x2, y2;
public LinearGradient(PShapeSVG parent, XML properties) {
super(parent, properties);
@@ -1547,8 +1539,8 @@ public class PShapeSVG extends PShape {
}
static class RadialGradient extends Gradient {
float cx, cy, r;
public class RadialGradient extends Gradient {
public float cx, cy, r;
public RadialGradient(PShapeSVG parent, XML properties) {
super(parent, properties);
@@ -1575,287 +1567,6 @@ public class PShapeSVG extends PShape {
}
static class LinearGradientPaint implements Paint {
float x1, y1, x2, y2;
float[] offset;
int[] color;
int count;
float opacity;
public LinearGradientPaint(float x1, float y1, float x2, float y2,
float[] offset, int[] color, int count,
float opacity) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.offset = offset;
this.color = color;
this.count = count;
this.opacity = opacity;
}
public PaintContext createContext(ColorModel cm,
Rectangle deviceBounds, Rectangle2D userBounds,
AffineTransform xform, RenderingHints hints) {
Point2D t1 = xform.transform(new Point2D.Float(x1, y1), null);
Point2D t2 = xform.transform(new Point2D.Float(x2, y2), null);
return new LinearGradientContext((float) t1.getX(), (float) t1.getY(),
(float) t2.getX(), (float) t2.getY());
}
public int getTransparency() {
return TRANSLUCENT; // why not.. rather than checking each color
}
public class LinearGradientContext implements PaintContext {
int ACCURACY = 2;
float tx1, ty1, tx2, ty2;
public LinearGradientContext(float tx1, float ty1, float tx2, float ty2) {
this.tx1 = tx1;
this.ty1 = ty1;
this.tx2 = tx2;
this.ty2 = ty2;
}
public void dispose() { }
public ColorModel getColorModel() { return ColorModel.getRGBdefault(); }
public Raster getRaster(int x, int y, int w, int h) {
WritableRaster raster =
getColorModel().createCompatibleWritableRaster(w, h);
int[] data = new int[w * h * 4];
// make normalized version of base vector
float nx = tx2 - tx1;
float ny = ty2 - ty1;
float len = (float) Math.sqrt(nx*nx + ny*ny);
if (len != 0) {
nx /= len;
ny /= len;
}
int span = (int) PApplet.dist(tx1, ty1, tx2, ty2) * ACCURACY;
if (span <= 0) {
//System.err.println("span is too small");
// annoying edge case where the gradient isn't legit
int index = 0;
for (int j = 0; j < h; j++) {
for (int i = 0; i < w; i++) {
data[index++] = 0;
data[index++] = 0;
data[index++] = 0;
data[index++] = 255;
}
}
} else {
int[][] interp = new int[span][4];
int prev = 0;
for (int i = 1; i < count; i++) {
int c0 = color[i-1];
int c1 = color[i];
int last = (int) (offset[i] * (span-1));
//System.out.println("last is " + last);
for (int j = prev; j <= last; j++) {
float btwn = PApplet.norm(j, prev, last);
interp[j][0] = (int) PApplet.lerp((c0 >> 16) & 0xff, (c1 >> 16) & 0xff, btwn);
interp[j][1] = (int) PApplet.lerp((c0 >> 8) & 0xff, (c1 >> 8) & 0xff, btwn);
interp[j][2] = (int) PApplet.lerp(c0 & 0xff, c1 & 0xff, btwn);
interp[j][3] = (int) (PApplet.lerp((c0 >> 24) & 0xff, (c1 >> 24) & 0xff, btwn) * opacity);
//System.out.println(j + " " + interp[j][0] + " " + interp[j][1] + " " + interp[j][2]);
}
prev = last;
}
int index = 0;
for (int j = 0; j < h; j++) {
for (int i = 0; i < w; i++) {
//float distance = 0; //PApplet.dist(cx, cy, x + i, y + j);
//int which = PApplet.min((int) (distance * ACCURACY), interp.length-1);
float px = (x + i) - tx1;
float py = (y + j) - ty1;
// distance up the line is the dot product of the normalized
// vector of the gradient start/stop by the point being tested
int which = (int) ((px*nx + py*ny) * ACCURACY);
if (which < 0) which = 0;
if (which > interp.length-1) which = interp.length-1;
//if (which > 138) System.out.println("grabbing " + which);
data[index++] = interp[which][0];
data[index++] = interp[which][1];
data[index++] = interp[which][2];
data[index++] = interp[which][3];
}
}
}
raster.setPixels(0, 0, w, h, data);
return raster;
}
}
}
static class RadialGradientPaint implements Paint {
float cx, cy, radius;
float[] offset;
int[] color;
int count;
float opacity;
public RadialGradientPaint(float cx, float cy, float radius,
float[] offset, int[] color, int count,
float opacity) {
this.cx = cx;
this.cy = cy;
this.radius = radius;
this.offset = offset;
this.color = color;
this.count = count;
this.opacity = opacity;
}
public PaintContext createContext(ColorModel cm,
Rectangle deviceBounds, Rectangle2D userBounds,
AffineTransform xform, RenderingHints hints) {
return new RadialGradientContext();
}
public int getTransparency() {
return TRANSLUCENT;
}
public class RadialGradientContext implements PaintContext {
int ACCURACY = 5;
public void dispose() {}
public ColorModel getColorModel() { return ColorModel.getRGBdefault(); }
public Raster getRaster(int x, int y, int w, int h) {
WritableRaster raster =
getColorModel().createCompatibleWritableRaster(w, h);
int span = (int) radius * ACCURACY;
int[][] interp = new int[span][4];
int prev = 0;
for (int i = 1; i < count; i++) {
int c0 = color[i-1];
int c1 = color[i];
int last = (int) (offset[i] * (span - 1));
for (int j = prev; j <= last; j++) {
float btwn = PApplet.norm(j, prev, last);
interp[j][0] = (int) PApplet.lerp((c0 >> 16) & 0xff, (c1 >> 16) & 0xff, btwn);
interp[j][1] = (int) PApplet.lerp((c0 >> 8) & 0xff, (c1 >> 8) & 0xff, btwn);
interp[j][2] = (int) PApplet.lerp(c0 & 0xff, c1 & 0xff, btwn);
interp[j][3] = (int) (PApplet.lerp((c0 >> 24) & 0xff, (c1 >> 24) & 0xff, btwn) * opacity);
}
prev = last;
}
int[] data = new int[w * h * 4];
int index = 0;
for (int j = 0; j < h; j++) {
for (int i = 0; i < w; i++) {
float distance = PApplet.dist(cx, cy, x + i, y + j);
int which = PApplet.min((int) (distance * ACCURACY), interp.length-1);
data[index++] = interp[which][0];
data[index++] = interp[which][1];
data[index++] = interp[which][2];
data[index++] = interp[which][3];
}
}
raster.setPixels(0, 0, w, h, data);
return raster;
}
}
}
protected Paint calcGradientPaint(Gradient gradient) {
if (gradient instanceof LinearGradient) {
LinearGradient grad = (LinearGradient) gradient;
return new LinearGradientPaint(grad.x1, grad.y1, grad.x2, grad.y2,
grad.offset, grad.color, grad.count,
opacity);
} else if (gradient instanceof RadialGradient) {
RadialGradient grad = (RadialGradient) gradient;
return new RadialGradientPaint(grad.cx, grad.cy, grad.r,
grad.offset, grad.color, grad.count,
opacity);
}
return null;
}
// protected Paint calcGradientPaint(Gradient gradient,
// float x1, float y1, float x2, float y2) {
// if (gradient instanceof LinearGradient) {
// LinearGradient grad = (LinearGradient) gradient;
// return new LinearGradientPaint(x1, y1, x2, y2,
// grad.offset, grad.color, grad.count,
// opacity);
// }
// throw new RuntimeException("Not a linear gradient.");
// }
// protected Paint calcGradientPaint(Gradient gradient,
// float cx, float cy, float r) {
// if (gradient instanceof RadialGradient) {
// RadialGradient grad = (RadialGradient) gradient;
// return new RadialGradientPaint(cx, cy, r,
// grad.offset, grad.color, grad.count,
// opacity);
// }
// throw new RuntimeException("Not a radial gradient.");
// }
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
@Override
protected void styles(PGraphics g) {
super.styles(g);
if (g instanceof PGraphicsJava2D) {
PGraphicsJava2D p2d = (PGraphicsJava2D) g;
if (strokeGradient != null) {
p2d.strokeGradient = true;
p2d.strokeGradientObject = strokeGradientPaint;
} else {
// need to shut off, in case parent object has a gradient applied
//p2d.strokeGradient = false;
}
if (fillGradient != null) {
p2d.fillGradient = true;
p2d.fillGradientObject = fillGradientPaint;
} else {
// need to shut off, in case parent object has a gradient applied
//p2d.fillGradient = false;
}
}
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
//public void drawImpl(PGraphics g) {
// do nothing
//}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .