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