summaryrefslogtreecommitdiff
path: root/gnu/java/awt/java2d
diff options
context:
space:
mode:
authorRoman Kennke <roman@kennke.org>2006-04-24 14:37:22 +0000
committerRoman Kennke <roman@kennke.org>2006-04-24 14:37:22 +0000
commit636bbf05cb4b7dc32558741e4191a96bb89bdb81 (patch)
tree14a4c9a672ec05b8483d1cc83c572be260d2291b /gnu/java/awt/java2d
parentb42c3f3f0bff030ba4d109fa70597807e4ad1ecf (diff)
downloadclasspath-636bbf05cb4b7dc32558741e4191a96bb89bdb81.tar.gz
2006-04-24 Sven de Marothy <sven@physto.se>
* gnu/java/awt/java2d/Segment.java: New file. * gnu/java/awt/java2d/CubicSegment.java: New file. * gnu/java/awt/java2d/QuadSegment.java: New file. * gnu/java/awt/java2d/LineSegment.java: New file. * java/awt/BasicStroke.java (start): New field. (end): New field. (createStrokedShape): Implemented. (solidStroke): New method. (dashedStroke): New method. (capEnds): New method. (convertPath): New method. (addSegments): New method. (capEnd): New method. (lineIntersection): New method. (joinSegments): New method.
Diffstat (limited to 'gnu/java/awt/java2d')
-rw-r--r--gnu/java/awt/java2d/CubicSegment.java128
-rw-r--r--gnu/java/awt/java2d/LineSegment.java103
-rw-r--r--gnu/java/awt/java2d/QuadSegment.java213
-rw-r--r--gnu/java/awt/java2d/Segment.java131
4 files changed, 575 insertions, 0 deletions
diff --git a/gnu/java/awt/java2d/CubicSegment.java b/gnu/java/awt/java2d/CubicSegment.java
new file mode 100644
index 000000000..1e568f722
--- /dev/null
+++ b/gnu/java/awt/java2d/CubicSegment.java
@@ -0,0 +1,128 @@
+/* CubicSegment.java -- Cubic segment used for BasicStroke
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.java2d;
+
+
+import java.awt.geom.Point2D;
+
+/**
+ * Cubic Bezier curve segment
+ */
+public class CubicSegment extends Segment
+{
+ public Point2D cp1; // control points
+ public Point2D cp2; // control points
+
+ /**
+ * Constructor - takes coordinates of the starting point,
+ * first control point, second control point and end point,
+ * respecively.
+ */
+ public CubicSegment(double x1, double y1, double c1x, double c1y,
+ double c2x, double c2y, double x2, double y2)
+ {
+ super();
+ P1 = new Point2D.Double(x1, y1);
+ P2 = new Point2D.Double(x2, y2);
+ cp1 = new Point2D.Double(c1x, c1y);
+ cp2 = new Point2D.Double(c2x, c2y);
+ }
+
+ public CubicSegment(Point2D p1, Point2D cp1, Point2D cp2, Point2D p2)
+ {
+ super();
+ P1 = p1;
+ P2 = p2;
+ this.cp1 = cp1;
+ this.cp2 = cp2;
+ }
+
+ /**
+ * Clones this segment
+ */
+ public Object clone()
+ {
+ return new CubicSegment(P1.getX(), P1.getY(), cp1.getX(), cp1.getY(),
+ cp2.getX(), cp2.getY(), P2.getX(), P2.getY());
+ }
+
+ /**
+ * Get the "top" and "bottom" segments of this segment.
+ * First array element is p0 + normal, second is p0 - normal.
+ */
+ public Segment[] getDisplacedSegments(double radius)
+ {
+ this.radius = radius;
+ double x0 = P1.getX();
+ double y0 = P1.getY();
+ double x1 = cp1.getX();
+ double y1 = cp1.getY();
+ double x2 = cp2.getX();
+ double y2 = cp2.getY();
+ double x3 = P2.getX();
+ double y3 = P2.getY();
+ double[] p1 = normal(x0, y0, x1, y1);
+ double[] p2 = normal(x2, y2, x3, y3);
+
+
+ // FIXME: Doesn't compile.
+ // return new Segment[]{s1, s2};
+ return new Segment[0];
+ }
+
+ public void reverse()
+ {
+ Point2D temp = P1;
+ P1 = P2;
+ P2 = temp;
+ temp = cp1;
+ cp1 = cp2;
+ cp2 = temp;
+ }
+
+ public double[] first()
+ {
+ return new double[]{cp1.getX(), cp1.getY()};
+ }
+
+ public double[] last()
+ {
+ return new double[]{cp2.getX(), cp2.getY()};
+ }
+} // class CubicSegment
diff --git a/gnu/java/awt/java2d/LineSegment.java b/gnu/java/awt/java2d/LineSegment.java
new file mode 100644
index 000000000..9c0bcc7ea
--- /dev/null
+++ b/gnu/java/awt/java2d/LineSegment.java
@@ -0,0 +1,103 @@
+/* LineSegment.java -- Line segment used for BasicStroke
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.java2d;
+
+
+import java.awt.geom.Point2D;
+
+public class LineSegment extends Segment
+{
+ public LineSegment(double x1, double y1, double x2, double y2)
+ {
+ super();
+ P1 = new Point2D.Double(x1, y1);
+ P2 = new Point2D.Double(x2, y2);
+ }
+
+ public LineSegment(Point2D p1, Point2D p2)
+ {
+ super();
+ P1 = (Point2D) p1.clone();
+ P2 = (Point2D) p2.clone();
+ }
+
+ /**
+ * Clones this segment
+ */
+ public Object clone()
+ {
+ return new LineSegment(P1, P2);
+ }
+
+ /**
+ * Get the "top" and "bottom" segments of this segment.
+ * First array element is p0 + normal, second is p0 - normal.
+ */
+ public Segment[] getDisplacedSegments(double radius)
+ {
+ this.radius = radius;
+ double x0 = P1.getX();
+ double y0 = P1.getY();
+ double x1 = P2.getX();
+ double y1 = P2.getY();
+ double[] p = normal(x0, y0, x1, y1);
+ Segment s1 = (new LineSegment(x0 + p[0], y0 + p[1],
+ x1 + p[0], y1 + p[1] ));
+ Segment s2 = (new LineSegment(x0 - p[0], y0 - p[1],
+ x1 - p[0], y1 - p[1] ));
+ return new Segment[]{s1, s2};
+ }
+
+ public void reverse()
+ {
+ Point2D p = P1;
+ P1 = P2;
+ P2 = p;
+ }
+
+ public double[] first()
+ {
+ return new double[]{P2.getX(), P2.getY()};
+ }
+
+ public double[] last()
+ {
+ return new double[]{P1.getX(), P1.getY()};
+ }
+} // class LineSegment
diff --git a/gnu/java/awt/java2d/QuadSegment.java b/gnu/java/awt/java2d/QuadSegment.java
new file mode 100644
index 000000000..9c15a8cfd
--- /dev/null
+++ b/gnu/java/awt/java2d/QuadSegment.java
@@ -0,0 +1,213 @@
+/* QuadSegment.java -- QuadCurve segment used for BasicStroke
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.java2d;
+
+
+import java.awt.geom.Point2D;
+import java.awt.geom.QuadCurve2D;
+
+/**
+ * Quadratic Bezier curve segment
+ *
+ * Note: Most peers don't support quadratics directly, so it might make
+ * sense to represent them as cubics internally and just be done with it.
+ * I think we should be peer-agnostic, however, and stay faithful to the
+ * input geometry types as far as possible.
+ */
+public class QuadSegment extends Segment
+{
+ public Point2D cp; // control point
+
+ /**
+ * Constructor, takes the coordinates of the start, control,
+ * and end point, respectively.
+ */
+ public QuadSegment(double x1, double y1, double cx, double cy, double x2,
+ double y2)
+ {
+ super();
+ P1 = new Point2D.Double(x1, y1);
+ P2 = new Point2D.Double(x2, y2);
+ cp = new Point2D.Double(cx, cy);
+ }
+
+ public QuadSegment(Point2D p1, Point2D cp, Point2D p2)
+ {
+ super();
+ P1 = p1;
+ P2 = p2;
+ this.cp = cp;
+ }
+
+ public QuadSegment(QuadCurve2D curve)
+ {
+ super();
+ P1 = curve.getP1();
+ P2 = curve.getP2();
+ this.cp = curve.getCtrlPt();
+ }
+
+ /**
+ * Clones this segment
+ */
+ public Object clone()
+ {
+ return new QuadSegment(P1.getX(), P1.getY(), cp.getX(), cp.getY(),
+ P2.getX(), P2.getY());
+ }
+
+ /**
+ * Get the "top" and "bottom" segments of a given segment.
+ * First array element is p0 + normal, second is p0 - normal.
+ */
+ public Segment[] getDisplacedSegments(double radius)
+ {
+ this.radius = radius;
+ double x0 = P1.getX();
+ double y0 = P1.getY();
+ double x1 = cp.getX();
+ double y1 = cp.getY();
+ double x2 = P2.getX();
+ double y2 = P2.getY();
+
+ QuadCurve2D left = new QuadCurve2D.Double();
+ QuadCurve2D right = new QuadCurve2D.Double();
+ QuadCurve2D orig = new QuadCurve2D.Double(x0, y0, x1, y1, x2, y2);
+ orig.subdivide(left, right);
+
+ QuadSegment s1 = offsetSubdivided(left, true);
+ QuadSegment s2 = offsetSubdivided(left, false);
+
+ s1.add( offsetSubdivided(right, true) );
+ s2.add( offsetSubdivided(right, false) );
+
+ return new Segment[]{s1, s2};
+ }
+
+ private QuadSegment offsetSubdivided(QuadCurve2D curve, boolean plus)
+ {
+ double[] n1 = normal(curve.getX1(), curve.getY1(),
+ curve.getCtrlX(), curve.getCtrlY());
+ double[] n2 = normal(curve.getCtrlX(), curve.getCtrlY(),
+ curve.getX2(), curve.getY2());
+
+ Point2D cp;
+ QuadSegment s;
+ if( plus )
+ {
+ cp = lineIntersection(curve.getX1() + n1[0],
+ curve.getY1() + n1[1],
+ curve.getCtrlX() + n1[0],
+ curve.getCtrlY() + n1[1],
+ curve.getCtrlX() + n2[0],
+ curve.getCtrlY() + n2[1],
+ curve.getX2() + n2[0],
+ curve.getY2() + n2[1], true);
+ s = new QuadSegment(curve.getX1() + n1[0], curve.getY1() + n1[1],
+ cp.getX(), cp.getY(),
+ curve.getX2() + n2[0], curve.getY2() + n2[1]);
+ }
+ else
+ {
+ cp = lineIntersection(curve.getX1() - n1[0],
+ curve.getY1() - n1[1],
+ curve.getCtrlX() - n1[0],
+ curve.getCtrlY() - n1[1],
+ curve.getCtrlX() - n2[0],
+ curve.getCtrlY() - n2[1],
+ curve.getX2() - n2[0],
+ curve.getY2() - n2[1], true);
+
+ s = new QuadSegment(curve.getX1() - n1[0], curve.getY1() - n1[1],
+ cp.getX(), cp.getY(),
+ curve.getX2() - n2[0], curve.getY2() - n2[1]);
+ }
+
+ return s;
+ }
+
+ private Point2D lineIntersection(double X1, double Y1,
+ double X2, double Y2,
+ double X3, double Y3,
+ double X4, double Y4,
+ boolean infinite)
+ {
+ double x1 = X1;
+ double y1 = Y1;
+ double rx = X2 - x1;
+ double ry = Y2 - y1;
+
+ double x2 = X3;
+ double y2 = Y3;
+ double sx = X4 - x2;
+ double sy = Y4 - y2;
+
+ double determinant = sx * ry - sy * rx;
+ double nom = (sx * (y2 - y1) + sy * (x1 - x2));
+
+ // lines can be considered parallel.
+ if (Math.abs(determinant) < 1E-6)
+ return null;
+
+ nom = nom / determinant;
+
+ // check if lines are within the bounds
+ if(!infinite && (nom > 1.0 || nom < 0.0))
+ return null;
+
+ return new Point2D.Double(x1 + nom * rx, y1 + nom * ry);
+ }
+
+ public void reverse()
+ {
+ Point2D p = P1;
+ P1 = P2;
+ P2 = p;
+ }
+
+ public double[] first()
+ {
+ return new double[]{cp.getX(), cp.getY()};
+ }
+
+ public double[] last()
+ {
+ return new double[]{cp.getX(), cp.getY()};
+ }
+}
diff --git a/gnu/java/awt/java2d/Segment.java b/gnu/java/awt/java2d/Segment.java
new file mode 100644
index 000000000..9a985f696
--- /dev/null
+++ b/gnu/java/awt/java2d/Segment.java
@@ -0,0 +1,131 @@
+/* Segment.java -- Abstract segment used for BasicStroke
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.java2d;
+
+import java.awt.geom.Point2D;
+
+public abstract class Segment implements Cloneable
+{
+ // segment type, PathIterator segment types are used.
+ public Point2D P1;
+ public Point2D P2;
+ public Segment next;
+ public Segment last;
+ protected double radius;
+
+ public Segment()
+ {
+ P1 = P2 = null;
+ next = null;
+ last = this;
+ }
+
+ public void add(Segment newsegment)
+ {
+ last.next = newsegment;
+ last = last.next;
+ }
+
+ /**
+ * Reverses the orientation of the whole polygon
+ */
+ public void reverseAll()
+ {
+ reverse();
+ Segment v = next;
+ Segment former = this;
+ next = null;
+
+ while (v != null)
+ {
+ v.reverse();
+ v.last = this;
+ Segment oldnext = v.next;
+ v.next = former;
+
+ former = v;
+ v = oldnext; // move to the next in list
+ }
+ }
+
+ public String toString()
+ {
+ return "Segment:"+P1+", "+P2;
+ }
+
+ /**
+ * Get the normal vector to the slope of the line.
+ * Returns: 0.5*width*(norm of derivative of the (x0,y0)-(x1,y1) vector)
+ */
+ protected double[] normal(double x0, double y0, double x1, double y1)
+ {
+ double dx = (x1 - x0);
+ double dy = (y1 - y0);
+ if( dy == 0 )
+ {
+ dy = radius * ((dx > 0)?1:-1);
+ dx = 0;
+ }
+ else if( dx == 0 )
+ {
+ dx = radius * ((dy > 0)?-1:1);
+ dy = 0;
+ }
+ else
+ {
+ double N = Math.sqrt(dx * dx + dy * dy);
+ double odx = dx;
+ dx = -radius * dy / N;
+ dy = radius * odx / N;
+ }
+ return new double[]{ dx, dy };
+ }
+
+ public abstract void reverse();
+
+ /**
+ * Get the "top" and "bottom" segments of a segment.
+ * First array element is p0 + normal, second is p0 - normal.
+ */
+ public abstract Segment[] getDisplacedSegments(double radius);
+
+ public abstract double[] first();
+ public abstract double[] last();
+
+}