author | dlila |
Tue, 10 Aug 2010 13:19:44 -0400 | |
changeset 6284 | 695b3c6241c8 |
parent 5506 | 202f599c92aa |
child 6285 | 96a57de47def |
permissions | -rw-r--r-- |
2 | 1 |
/* |
5506 | 2 |
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
||
26 |
package sun.java2d.pisces; |
|
27 |
||
28 |
import java.awt.Shape; |
|
29 |
import java.awt.BasicStroke; |
|
30 |
import java.awt.geom.Path2D; |
|
31 |
import java.awt.geom.AffineTransform; |
|
32 |
import java.awt.geom.PathIterator; |
|
33 |
||
34 |
import sun.awt.geom.PathConsumer2D; |
|
35 |
import sun.java2d.pipe.Region; |
|
36 |
import sun.java2d.pipe.RenderingEngine; |
|
37 |
import sun.java2d.pipe.AATileGenerator; |
|
38 |
||
39 |
public class PiscesRenderingEngine extends RenderingEngine { |
|
40 |
public static double defaultFlat = 0.1; |
|
41 |
||
42 |
/** |
|
43 |
* Create a widened path as specified by the parameters. |
|
44 |
* <p> |
|
45 |
* The specified {@code src} {@link Shape} is widened according |
|
46 |
* to the specified attribute parameters as per the |
|
47 |
* {@link BasicStroke} specification. |
|
48 |
* |
|
49 |
* @param src the source path to be widened |
|
50 |
* @param width the width of the widened path as per {@code BasicStroke} |
|
51 |
* @param caps the end cap decorations as per {@code BasicStroke} |
|
52 |
* @param join the segment join decorations as per {@code BasicStroke} |
|
53 |
* @param miterlimit the miter limit as per {@code BasicStroke} |
|
54 |
* @param dashes the dash length array as per {@code BasicStroke} |
|
55 |
* @param dashphase the initial dash phase as per {@code BasicStroke} |
|
56 |
* @return the widened path stored in a new {@code Shape} object |
|
57 |
* @since 1.7 |
|
58 |
*/ |
|
59 |
public Shape createStrokedShape(Shape src, |
|
60 |
float width, |
|
61 |
int caps, |
|
62 |
int join, |
|
63 |
float miterlimit, |
|
64 |
float dashes[], |
|
65 |
float dashphase) |
|
66 |
{ |
|
67 |
final Path2D p2d = new Path2D.Float(); |
|
68 |
||
69 |
strokeTo(src, |
|
70 |
null, |
|
71 |
width, |
|
6284 | 72 |
false, |
2 | 73 |
caps, |
74 |
join, |
|
75 |
miterlimit, |
|
76 |
dashes, |
|
77 |
dashphase, |
|
78 |
new LineSink() { |
|
6284 | 79 |
public void moveTo(float x0, float y0) { |
80 |
p2d.moveTo(x0, y0); |
|
2 | 81 |
} |
82 |
public void lineJoin() {} |
|
6284 | 83 |
public void lineTo(float x1, float y1) { |
84 |
p2d.lineTo(x1, y1); |
|
2 | 85 |
} |
86 |
public void close() { |
|
87 |
p2d.closePath(); |
|
88 |
} |
|
89 |
public void end() {} |
|
90 |
}); |
|
91 |
||
92 |
return p2d; |
|
93 |
} |
|
94 |
||
95 |
/** |
|
96 |
* Sends the geometry for a widened path as specified by the parameters |
|
97 |
* to the specified consumer. |
|
98 |
* <p> |
|
99 |
* The specified {@code src} {@link Shape} is widened according |
|
100 |
* to the parameters specified by the {@link BasicStroke} object. |
|
101 |
* Adjustments are made to the path as appropriate for the |
|
102 |
* {@link VALUE_STROKE_NORMALIZE} hint if the {@code normalize} |
|
103 |
* boolean parameter is true. |
|
104 |
* Adjustments are made to the path as appropriate for the |
|
105 |
* {@link VALUE_ANTIALIAS_ON} hint if the {@code antialias} |
|
106 |
* boolean parameter is true. |
|
107 |
* <p> |
|
108 |
* The geometry of the widened path is forwarded to the indicated |
|
109 |
* {@link PathConsumer2D} object as it is calculated. |
|
110 |
* |
|
111 |
* @param src the source path to be widened |
|
112 |
* @param bs the {@code BasicSroke} object specifying the |
|
113 |
* decorations to be applied to the widened path |
|
114 |
* @param normalize indicates whether stroke normalization should |
|
115 |
* be applied |
|
116 |
* @param antialias indicates whether or not adjustments appropriate |
|
117 |
* to antialiased rendering should be applied |
|
118 |
* @param consumer the {@code PathConsumer2D} instance to forward |
|
119 |
* the widened geometry to |
|
120 |
* @since 1.7 |
|
121 |
*/ |
|
122 |
public void strokeTo(Shape src, |
|
123 |
AffineTransform at, |
|
124 |
BasicStroke bs, |
|
125 |
boolean thin, |
|
126 |
boolean normalize, |
|
127 |
boolean antialias, |
|
128 |
final PathConsumer2D consumer) |
|
129 |
{ |
|
130 |
strokeTo(src, at, bs, thin, normalize, antialias, |
|
131 |
new LineSink() { |
|
6284 | 132 |
public void moveTo(float x0, float y0) { |
133 |
consumer.moveTo(x0, y0); |
|
2 | 134 |
} |
135 |
public void lineJoin() {} |
|
6284 | 136 |
public void lineTo(float x1, float y1) { |
137 |
consumer.lineTo(x1, y1); |
|
2 | 138 |
} |
139 |
public void close() { |
|
140 |
consumer.closePath(); |
|
141 |
} |
|
142 |
public void end() { |
|
143 |
consumer.pathDone(); |
|
144 |
} |
|
145 |
}); |
|
146 |
} |
|
147 |
||
148 |
void strokeTo(Shape src, |
|
149 |
AffineTransform at, |
|
150 |
BasicStroke bs, |
|
151 |
boolean thin, |
|
152 |
boolean normalize, |
|
153 |
boolean antialias, |
|
154 |
LineSink lsink) |
|
155 |
{ |
|
156 |
float lw; |
|
157 |
if (thin) { |
|
158 |
if (antialias) { |
|
3927
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
159 |
lw = userSpaceLineWidth(at, 0.5f); |
2 | 160 |
} else { |
3927
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
161 |
lw = userSpaceLineWidth(at, 1.0f); |
2 | 162 |
} |
163 |
} else { |
|
164 |
lw = bs.getLineWidth(); |
|
165 |
} |
|
166 |
strokeTo(src, |
|
167 |
at, |
|
168 |
lw, |
|
6284 | 169 |
normalize, |
2 | 170 |
bs.getEndCap(), |
171 |
bs.getLineJoin(), |
|
172 |
bs.getMiterLimit(), |
|
173 |
bs.getDashArray(), |
|
174 |
bs.getDashPhase(), |
|
175 |
lsink); |
|
176 |
} |
|
177 |
||
3927
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
178 |
private float userSpaceLineWidth(AffineTransform at, float lw) { |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
179 |
|
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
180 |
double widthScale; |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
181 |
|
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
182 |
if ((at.getType() & (AffineTransform.TYPE_GENERAL_TRANSFORM | |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
183 |
AffineTransform.TYPE_GENERAL_SCALE)) != 0) { |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
184 |
widthScale = Math.sqrt(at.getDeterminant()); |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
185 |
} else { |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
186 |
/* First calculate the "maximum scale" of this transform. */ |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
187 |
double A = at.getScaleX(); // m00 |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
188 |
double C = at.getShearX(); // m01 |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
189 |
double B = at.getShearY(); // m10 |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
190 |
double D = at.getScaleY(); // m11 |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
191 |
|
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
192 |
/* |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
193 |
* Given a 2 x 2 affine matrix [ A B ] such that |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
194 |
* [ C D ] |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
195 |
* v' = [x' y'] = [Ax + Cy, Bx + Dy], we want to |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
196 |
* find the maximum magnitude (norm) of the vector v' |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
197 |
* with the constraint (x^2 + y^2 = 1). |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
198 |
* The equation to maximize is |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
199 |
* |v'| = sqrt((Ax+Cy)^2+(Bx+Dy)^2) |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
200 |
* or |v'| = sqrt((AA+BB)x^2 + 2(AC+BD)xy + (CC+DD)y^2). |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
201 |
* Since sqrt is monotonic we can maximize |v'|^2 |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
202 |
* instead and plug in the substitution y = sqrt(1 - x^2). |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
203 |
* Trigonometric equalities can then be used to get |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
204 |
* rid of most of the sqrt terms. |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
205 |
*/ |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
206 |
|
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
207 |
double EA = A*A + B*B; // x^2 coefficient |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
208 |
double EB = 2*(A*C + B*D); // xy coefficient |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
209 |
double EC = C*C + D*D; // y^2 coefficient |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
210 |
|
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
211 |
/* |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
212 |
* There is a lot of calculus omitted here. |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
213 |
* |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
214 |
* Conceptually, in the interests of understanding the |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
215 |
* terms that the calculus produced we can consider |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
216 |
* that EA and EC end up providing the lengths along |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
217 |
* the major axes and the hypot term ends up being an |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
218 |
* adjustment for the additional length along the off-axis |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
219 |
* angle of rotated or sheared ellipses as well as an |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
220 |
* adjustment for the fact that the equation below |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
221 |
* averages the two major axis lengths. (Notice that |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
222 |
* the hypot term contains a part which resolves to the |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
223 |
* difference of these two axis lengths in the absence |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
224 |
* of rotation.) |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
225 |
* |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
226 |
* In the calculus, the ratio of the EB and (EA-EC) terms |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
227 |
* ends up being the tangent of 2*theta where theta is |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
228 |
* the angle that the long axis of the ellipse makes |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
229 |
* with the horizontal axis. Thus, this equation is |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
230 |
* calculating the length of the hypotenuse of a triangle |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
231 |
* along that axis. |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
232 |
*/ |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
233 |
|
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
234 |
double hypot = Math.sqrt(EB*EB + (EA-EC)*(EA-EC)); |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
235 |
/* sqrt omitted, compare to squared limits below. */ |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
236 |
double widthsquared = ((EA + EC + hypot)/2.0); |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
237 |
|
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
238 |
widthScale = Math.sqrt(widthsquared); |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
239 |
} |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
240 |
|
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
241 |
return (float) (lw / widthScale); |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
242 |
} |
d717df90e151
6829673: ThinLineTest: A line < 1 pixel disappears.
jgodinez
parents:
2391
diff
changeset
|
243 |
|
2 | 244 |
void strokeTo(Shape src, |
245 |
AffineTransform at, |
|
246 |
float width, |
|
6284 | 247 |
boolean normalize, |
2 | 248 |
int caps, |
249 |
int join, |
|
250 |
float miterlimit, |
|
251 |
float dashes[], |
|
252 |
float dashphase, |
|
253 |
LineSink lsink) |
|
254 |
{ |
|
6284 | 255 |
float a00 = 1f, a01 = 0f, a10 = 0f, a11 = 1f; |
256 |
if (at != null && !at.isIdentity()) { |
|
257 |
a00 = (float)at.getScaleX(); |
|
258 |
a01 = (float)at.getShearX(); |
|
259 |
a10 = (float)at.getShearY(); |
|
260 |
a11 = (float)at.getScaleY(); |
|
2 | 261 |
} |
6284 | 262 |
lsink = new Stroker(lsink, width, caps, join, miterlimit, a00, a01, a10, a11); |
2 | 263 |
if (dashes != null) { |
6284 | 264 |
lsink = new Dasher(lsink, dashes, dashphase, a00, a01, a10, a11); |
2 | 265 |
} |
266 |
||
267 |
PathIterator pi = src.getPathIterator(at, defaultFlat); |
|
268 |
pathTo(pi, lsink); |
|
269 |
} |
|
270 |
||
271 |
void pathTo(PathIterator pi, LineSink lsink) { |
|
272 |
float coords[] = new float[2]; |
|
273 |
while (!pi.isDone()) { |
|
274 |
switch (pi.currentSegment(coords)) { |
|
275 |
case PathIterator.SEG_MOVETO: |
|
6284 | 276 |
lsink.moveTo(coords[0], coords[1]); |
2 | 277 |
break; |
278 |
case PathIterator.SEG_LINETO: |
|
279 |
lsink.lineJoin(); |
|
6284 | 280 |
lsink.lineTo(coords[0], coords[1]); |
2 | 281 |
break; |
282 |
case PathIterator.SEG_CLOSE: |
|
2391
3397fe90e591
6812600: The miter line join decoration isn't rendered properly
jgodinez
parents:
2
diff
changeset
|
283 |
lsink.lineJoin(); |
2 | 284 |
lsink.close(); |
285 |
break; |
|
286 |
default: |
|
287 |
throw new InternalError("unknown flattened segment type"); |
|
288 |
} |
|
289 |
pi.next(); |
|
290 |
} |
|
291 |
lsink.end(); |
|
292 |
} |
|
293 |
||
294 |
/** |
|
295 |
* Construct an antialiased tile generator for the given shape with |
|
296 |
* the given rendering attributes and store the bounds of the tile |
|
297 |
* iteration in the bbox parameter. |
|
298 |
* The {@code at} parameter specifies a transform that should affect |
|
299 |
* both the shape and the {@code BasicStroke} attributes. |
|
300 |
* The {@code clip} parameter specifies the current clip in effect |
|
301 |
* in device coordinates and can be used to prune the data for the |
|
302 |
* operation, but the renderer is not required to perform any |
|
303 |
* clipping. |
|
304 |
* If the {@code BasicStroke} parameter is null then the shape |
|
305 |
* should be filled as is, otherwise the attributes of the |
|
306 |
* {@code BasicStroke} should be used to specify a draw operation. |
|
307 |
* The {@code thin} parameter indicates whether or not the |
|
308 |
* transformed {@code BasicStroke} represents coordinates smaller |
|
309 |
* than the minimum resolution of the antialiasing rasterizer as |
|
310 |
* specified by the {@code getMinimumAAPenWidth()} method. |
|
311 |
* <p> |
|
312 |
* Upon returning, this method will fill the {@code bbox} parameter |
|
313 |
* with 4 values indicating the bounds of the iteration of the |
|
314 |
* tile generator. |
|
315 |
* The iteration order of the tiles will be as specified by the |
|
316 |
* pseudo-code: |
|
317 |
* <pre> |
|
318 |
* for (y = bbox[1]; y < bbox[3]; y += tileheight) { |
|
319 |
* for (x = bbox[0]; x < bbox[2]; x += tilewidth) { |
|
320 |
* } |
|
321 |
* } |
|
322 |
* </pre> |
|
323 |
* If there is no output to be rendered, this method may return |
|
324 |
* null. |
|
325 |
* |
|
326 |
* @param s the shape to be rendered (fill or draw) |
|
327 |
* @param at the transform to be applied to the shape and the |
|
328 |
* stroke attributes |
|
329 |
* @param clip the current clip in effect in device coordinates |
|
330 |
* @param bs if non-null, a {@code BasicStroke} whose attributes |
|
331 |
* should be applied to this operation |
|
332 |
* @param thin true if the transformed stroke attributes are smaller |
|
333 |
* than the minimum dropout pen width |
|
334 |
* @param normalize true if the {@code VALUE_STROKE_NORMALIZE} |
|
335 |
* {@code RenderingHint} is in effect |
|
336 |
* @param bbox returns the bounds of the iteration |
|
337 |
* @return the {@code AATileGenerator} instance to be consulted |
|
338 |
* for tile coverages, or null if there is no output to render |
|
339 |
* @since 1.7 |
|
340 |
*/ |
|
341 |
public AATileGenerator getAATileGenerator(Shape s, |
|
342 |
AffineTransform at, |
|
343 |
Region clip, |
|
344 |
BasicStroke bs, |
|
345 |
boolean thin, |
|
346 |
boolean normalize, |
|
347 |
int bbox[]) |
|
348 |
{ |
|
349 |
PiscesCache pc = PiscesCache.createInstance(); |
|
6284 | 350 |
Renderer r; |
2 | 351 |
if (bs == null) { |
352 |
PathIterator pi = s.getPathIterator(at, defaultFlat); |
|
6284 | 353 |
r = new Renderer(3, 3, |
354 |
clip.getLoX(), clip.getLoY(), |
|
355 |
clip.getWidth(), clip.getHeight(), |
|
356 |
pi.getWindingRule(), pc); |
|
2 | 357 |
pathTo(pi, r); |
358 |
} else { |
|
6284 | 359 |
r = new Renderer(3, 3, |
360 |
clip.getLoX(), clip.getLoY(), |
|
361 |
clip.getWidth(), clip.getHeight(), |
|
362 |
PathIterator.WIND_NON_ZERO, pc); |
|
2 | 363 |
strokeTo(s, at, bs, thin, normalize, true, r); |
364 |
} |
|
365 |
r.endRendering(); |
|
366 |
PiscesTileGenerator ptg = new PiscesTileGenerator(pc, r.MAX_AA_ALPHA); |
|
367 |
ptg.getBbox(bbox); |
|
368 |
return ptg; |
|
369 |
} |
|
370 |
||
371 |
/** |
|
372 |
* Returns the minimum pen width that the antialiasing rasterizer |
|
373 |
* can represent without dropouts occuring. |
|
374 |
* @since 1.7 |
|
375 |
*/ |
|
376 |
public float getMinimumAAPenSize() { |
|
377 |
return 0.5f; |
|
378 |
} |
|
379 |
||
380 |
static { |
|
381 |
if (PathIterator.WIND_NON_ZERO != Renderer.WIND_NON_ZERO || |
|
382 |
PathIterator.WIND_EVEN_ODD != Renderer.WIND_EVEN_ODD || |
|
383 |
BasicStroke.JOIN_MITER != Stroker.JOIN_MITER || |
|
384 |
BasicStroke.JOIN_ROUND != Stroker.JOIN_ROUND || |
|
385 |
BasicStroke.JOIN_BEVEL != Stroker.JOIN_BEVEL || |
|
386 |
BasicStroke.CAP_BUTT != Stroker.CAP_BUTT || |
|
387 |
BasicStroke.CAP_ROUND != Stroker.CAP_ROUND || |
|
388 |
BasicStroke.CAP_SQUARE != Stroker.CAP_SQUARE) |
|
389 |
{ |
|
390 |
throw new InternalError("mismatched renderer constants"); |
|
391 |
} |
|
392 |
} |
|
393 |
} |