|
1 /* |
|
2 * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. |
|
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 |
|
7 * published by the Free Software Foundation. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
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 * |
|
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. |
|
24 */ |
|
25 |
|
26 package sun.java2d.marlin; |
|
27 |
|
28 import java.awt.geom.AffineTransform; |
|
29 import java.awt.geom.Path2D; |
|
30 |
|
31 final class DTransformingPathConsumer2D { |
|
32 |
|
33 DTransformingPathConsumer2D() { |
|
34 // used by DRendererContext |
|
35 } |
|
36 |
|
37 // recycled DPathConsumer2D instance from wrapPath2d() |
|
38 private final Path2DWrapper wp_Path2DWrapper = new Path2DWrapper(); |
|
39 |
|
40 DPathConsumer2D wrapPath2d(Path2D.Double p2d) |
|
41 { |
|
42 return wp_Path2DWrapper.init(p2d); |
|
43 } |
|
44 |
|
45 // recycled DPathConsumer2D instances from deltaTransformConsumer() |
|
46 private final DeltaScaleFilter dt_DeltaScaleFilter = new DeltaScaleFilter(); |
|
47 private final DeltaTransformFilter dt_DeltaTransformFilter = new DeltaTransformFilter(); |
|
48 |
|
49 DPathConsumer2D deltaTransformConsumer(DPathConsumer2D out, |
|
50 AffineTransform at) |
|
51 { |
|
52 if (at == null) { |
|
53 return out; |
|
54 } |
|
55 double mxx = at.getScaleX(); |
|
56 double mxy = at.getShearX(); |
|
57 double myx = at.getShearY(); |
|
58 double myy = at.getScaleY(); |
|
59 |
|
60 if (mxy == 0.0d && myx == 0.0d) { |
|
61 if (mxx == 1.0d && myy == 1.0d) { |
|
62 return out; |
|
63 } else { |
|
64 return dt_DeltaScaleFilter.init(out, mxx, myy); |
|
65 } |
|
66 } else { |
|
67 return dt_DeltaTransformFilter.init(out, mxx, mxy, myx, myy); |
|
68 } |
|
69 } |
|
70 |
|
71 // recycled DPathConsumer2D instances from inverseDeltaTransformConsumer() |
|
72 private final DeltaScaleFilter iv_DeltaScaleFilter = new DeltaScaleFilter(); |
|
73 private final DeltaTransformFilter iv_DeltaTransformFilter = new DeltaTransformFilter(); |
|
74 |
|
75 DPathConsumer2D inverseDeltaTransformConsumer(DPathConsumer2D out, |
|
76 AffineTransform at) |
|
77 { |
|
78 if (at == null) { |
|
79 return out; |
|
80 } |
|
81 double mxx = at.getScaleX(); |
|
82 double mxy = at.getShearX(); |
|
83 double myx = at.getShearY(); |
|
84 double myy = at.getScaleY(); |
|
85 |
|
86 if (mxy == 0.0d && myx == 0.0d) { |
|
87 if (mxx == 1.0d && myy == 1.0d) { |
|
88 return out; |
|
89 } else { |
|
90 return iv_DeltaScaleFilter.init(out, 1.0d/mxx, 1.0d/myy); |
|
91 } |
|
92 } else { |
|
93 double det = mxx * myy - mxy * myx; |
|
94 return iv_DeltaTransformFilter.init(out, |
|
95 myy / det, |
|
96 -mxy / det, |
|
97 -myx / det, |
|
98 mxx / det); |
|
99 } |
|
100 } |
|
101 |
|
102 |
|
103 static final class DeltaScaleFilter implements DPathConsumer2D { |
|
104 private DPathConsumer2D out; |
|
105 private double sx, sy; |
|
106 |
|
107 DeltaScaleFilter() {} |
|
108 |
|
109 DeltaScaleFilter init(DPathConsumer2D out, |
|
110 double mxx, double myy) |
|
111 { |
|
112 this.out = out; |
|
113 sx = mxx; |
|
114 sy = myy; |
|
115 return this; // fluent API |
|
116 } |
|
117 |
|
118 @Override |
|
119 public void moveTo(double x0, double y0) { |
|
120 out.moveTo(x0 * sx, y0 * sy); |
|
121 } |
|
122 |
|
123 @Override |
|
124 public void lineTo(double x1, double y1) { |
|
125 out.lineTo(x1 * sx, y1 * sy); |
|
126 } |
|
127 |
|
128 @Override |
|
129 public void quadTo(double x1, double y1, |
|
130 double x2, double y2) |
|
131 { |
|
132 out.quadTo(x1 * sx, y1 * sy, |
|
133 x2 * sx, y2 * sy); |
|
134 } |
|
135 |
|
136 @Override |
|
137 public void curveTo(double x1, double y1, |
|
138 double x2, double y2, |
|
139 double x3, double y3) |
|
140 { |
|
141 out.curveTo(x1 * sx, y1 * sy, |
|
142 x2 * sx, y2 * sy, |
|
143 x3 * sx, y3 * sy); |
|
144 } |
|
145 |
|
146 @Override |
|
147 public void closePath() { |
|
148 out.closePath(); |
|
149 } |
|
150 |
|
151 @Override |
|
152 public void pathDone() { |
|
153 out.pathDone(); |
|
154 } |
|
155 |
|
156 @Override |
|
157 public long getNativeConsumer() { |
|
158 return 0; |
|
159 } |
|
160 } |
|
161 |
|
162 static final class DeltaTransformFilter implements DPathConsumer2D { |
|
163 private DPathConsumer2D out; |
|
164 private double mxx, mxy, myx, myy; |
|
165 |
|
166 DeltaTransformFilter() {} |
|
167 |
|
168 DeltaTransformFilter init(DPathConsumer2D out, |
|
169 double mxx, double mxy, |
|
170 double myx, double myy) |
|
171 { |
|
172 this.out = out; |
|
173 this.mxx = mxx; |
|
174 this.mxy = mxy; |
|
175 this.myx = myx; |
|
176 this.myy = myy; |
|
177 return this; // fluent API |
|
178 } |
|
179 |
|
180 @Override |
|
181 public void moveTo(double x0, double y0) { |
|
182 out.moveTo(x0 * mxx + y0 * mxy, |
|
183 x0 * myx + y0 * myy); |
|
184 } |
|
185 |
|
186 @Override |
|
187 public void lineTo(double x1, double y1) { |
|
188 out.lineTo(x1 * mxx + y1 * mxy, |
|
189 x1 * myx + y1 * myy); |
|
190 } |
|
191 |
|
192 @Override |
|
193 public void quadTo(double x1, double y1, |
|
194 double x2, double y2) |
|
195 { |
|
196 out.quadTo(x1 * mxx + y1 * mxy, |
|
197 x1 * myx + y1 * myy, |
|
198 x2 * mxx + y2 * mxy, |
|
199 x2 * myx + y2 * myy); |
|
200 } |
|
201 |
|
202 @Override |
|
203 public void curveTo(double x1, double y1, |
|
204 double x2, double y2, |
|
205 double x3, double y3) |
|
206 { |
|
207 out.curveTo(x1 * mxx + y1 * mxy, |
|
208 x1 * myx + y1 * myy, |
|
209 x2 * mxx + y2 * mxy, |
|
210 x2 * myx + y2 * myy, |
|
211 x3 * mxx + y3 * mxy, |
|
212 x3 * myx + y3 * myy); |
|
213 } |
|
214 |
|
215 @Override |
|
216 public void closePath() { |
|
217 out.closePath(); |
|
218 } |
|
219 |
|
220 @Override |
|
221 public void pathDone() { |
|
222 out.pathDone(); |
|
223 } |
|
224 |
|
225 @Override |
|
226 public long getNativeConsumer() { |
|
227 return 0; |
|
228 } |
|
229 } |
|
230 |
|
231 static final class Path2DWrapper implements DPathConsumer2D { |
|
232 private Path2D.Double p2d; |
|
233 |
|
234 Path2DWrapper() {} |
|
235 |
|
236 Path2DWrapper init(Path2D.Double p2d) { |
|
237 this.p2d = p2d; |
|
238 return this; |
|
239 } |
|
240 |
|
241 @Override |
|
242 public void moveTo(double x0, double y0) { |
|
243 p2d.moveTo(x0, y0); |
|
244 } |
|
245 |
|
246 @Override |
|
247 public void lineTo(double x1, double y1) { |
|
248 p2d.lineTo(x1, y1); |
|
249 } |
|
250 |
|
251 @Override |
|
252 public void closePath() { |
|
253 p2d.closePath(); |
|
254 } |
|
255 |
|
256 @Override |
|
257 public void pathDone() {} |
|
258 |
|
259 @Override |
|
260 public void curveTo(double x1, double y1, |
|
261 double x2, double y2, |
|
262 double x3, double y3) |
|
263 { |
|
264 p2d.curveTo(x1, y1, x2, y2, x3, y3); |
|
265 } |
|
266 |
|
267 @Override |
|
268 public void quadTo(double x1, double y1, double x2, double y2) { |
|
269 p2d.quadTo(x1, y1, x2, y2); |
|
270 } |
|
271 |
|
272 @Override |
|
273 public long getNativeConsumer() { |
|
274 throw new InternalError("Not using a native peer"); |
|
275 } |
|
276 } |
|
277 } |