forked from pranjalbajaj/java7-sourcecode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRoundRectIterator.java
More file actions
189 lines (178 loc) · 5.51 KB
/
Copy pathRoundRectIterator.java
File metadata and controls
189 lines (178 loc) · 5.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*
* Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package java.awt.geom;
import java.util.*;
/**
* A utility class to iterate over the path segments of an rounded rectangle
* through the PathIterator interface.
*
* @author Jim Graham
*/
class RoundRectIterator implements PathIterator {
double x, y, w, h, aw, ah;
AffineTransform affine;
int index;
RoundRectIterator(RoundRectangle2D rr, AffineTransform at) {
this.x = rr.getX();
this.y = rr.getY();
this.w = rr.getWidth();
this.h = rr.getHeight();
this.aw = Math.min(w, Math.abs(rr.getArcWidth()));
this.ah = Math.min(h, Math.abs(rr.getArcHeight()));
this.affine = at;
if (aw < 0 || ah < 0) {
// Don't draw anything...
index = ctrlpts.length;
}
}
/**
* Return the winding rule for determining the insideness of the
* path.
* @see #WIND_EVEN_ODD
* @see #WIND_NON_ZERO
*/
public int getWindingRule() {
return WIND_NON_ZERO;
}
/**
* Tests if there are more points to read.
* @return true if there are more points to read
*/
public boolean isDone() {
return index >= ctrlpts.length;
}
/**
* Moves the iterator to the next segment of the path forwards
* along the primary direction of traversal as long as there are
* more points in that direction.
*/
public void next() {
index++;
}
private static final double angle = Math.PI / 4.0;
private static final double a = 1.0 - Math.cos(angle);
private static final double b = Math.tan(angle);
private static final double c = Math.sqrt(1.0 + b * b) - 1 + a;
private static final double cv = 4.0 / 3.0 * a * b / c;
private static final double acv = (1.0 - cv) / 2.0;
// For each array:
// 4 values for each point {v0, v1, v2, v3}:
// point = (x + v0 * w + v1 * arcWidth,
// y + v2 * h + v3 * arcHeight);
private static double ctrlpts[][] = {
{ 0.0, 0.0, 0.0, 0.5 },
{ 0.0, 0.0, 1.0, -0.5 },
{ 0.0, 0.0, 1.0, -acv,
0.0, acv, 1.0, 0.0,
0.0, 0.5, 1.0, 0.0 },
{ 1.0, -0.5, 1.0, 0.0 },
{ 1.0, -acv, 1.0, 0.0,
1.0, 0.0, 1.0, -acv,
1.0, 0.0, 1.0, -0.5 },
{ 1.0, 0.0, 0.0, 0.5 },
{ 1.0, 0.0, 0.0, acv,
1.0, -acv, 0.0, 0.0,
1.0, -0.5, 0.0, 0.0 },
{ 0.0, 0.5, 0.0, 0.0 },
{ 0.0, acv, 0.0, 0.0,
0.0, 0.0, 0.0, acv,
0.0, 0.0, 0.0, 0.5 },
{},
};
private static int types[] = {
SEG_MOVETO,
SEG_LINETO, SEG_CUBICTO,
SEG_LINETO, SEG_CUBICTO,
SEG_LINETO, SEG_CUBICTO,
SEG_LINETO, SEG_CUBICTO,
SEG_CLOSE,
};
/**
* Returns the coordinates and type of the current path segment in
* the iteration.
* The return value is the path segment type:
* SEG_MOVETO, SEG_LINETO, SEG_QUADTO, SEG_CUBICTO, or SEG_CLOSE.
* A float array of length 6 must be passed in and may be used to
* store the coordinates of the point(s).
* Each point is stored as a pair of float x,y coordinates.
* SEG_MOVETO and SEG_LINETO types will return one point,
* SEG_QUADTO will return two points,
* SEG_CUBICTO will return 3 points
* and SEG_CLOSE will not return any points.
* @see #SEG_MOVETO
* @see #SEG_LINETO
* @see #SEG_QUADTO
* @see #SEG_CUBICTO
* @see #SEG_CLOSE
*/
public int currentSegment(float[] coords) {
if (isDone()) {
throw new NoSuchElementException("roundrect iterator out of bounds");
}
double ctrls[] = ctrlpts[index];
int nc = 0;
for (int i = 0; i < ctrls.length; i += 4) {
coords[nc++] = (float) (x + ctrls[i + 0] * w + ctrls[i + 1] * aw);
coords[nc++] = (float) (y + ctrls[i + 2] * h + ctrls[i + 3] * ah);
}
if (affine != null) {
affine.transform(coords, 0, coords, 0, nc / 2);
}
return types[index];
}
/**
* Returns the coordinates and type of the current path segment in
* the iteration.
* The return value is the path segment type:
* SEG_MOVETO, SEG_LINETO, SEG_QUADTO, SEG_CUBICTO, or SEG_CLOSE.
* A double array of length 6 must be passed in and may be used to
* store the coordinates of the point(s).
* Each point is stored as a pair of double x,y coordinates.
* SEG_MOVETO and SEG_LINETO types will return one point,
* SEG_QUADTO will return two points,
* SEG_CUBICTO will return 3 points
* and SEG_CLOSE will not return any points.
* @see #SEG_MOVETO
* @see #SEG_LINETO
* @see #SEG_QUADTO
* @see #SEG_CUBICTO
* @see #SEG_CLOSE
*/
public int currentSegment(double[] coords) {
if (isDone()) {
throw new NoSuchElementException("roundrect iterator out of bounds");
}
double ctrls[] = ctrlpts[index];
int nc = 0;
for (int i = 0; i < ctrls.length; i += 4) {
coords[nc++] = (x + ctrls[i + 0] * w + ctrls[i + 1] * aw);
coords[nc++] = (y + ctrls[i + 2] * h + ctrls[i + 3] * ah);
}
if (affine != null) {
affine.transform(coords, 0, coords, 0, nc / 2);
}
return types[index];
}
}