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 com.sun.marlin; 27 28 import com.sun.javafx.geom.Path2D; 29 import com.sun.javafx.geom.PathConsumer2D; 30 import com.sun.javafx.geom.transform.BaseTransform; 31 32 public 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 // recycled PathConsumer2D instances from deltaTransformConsumer() 42 private final DeltaScaleFilter dt_DeltaScaleFilter = new DeltaScaleFilter(); 43 private final DeltaTransformFilter dt_DeltaTransformFilter = new DeltaTransformFilter(); 44 45 public PathConsumer2D wrapPath2d(Path2D p2d) 46 { 47 return wp_Path2DWrapper.init(p2d); 48 } 49 50 public PathConsumer2D deltaTransformConsumer(PathConsumer2D out, 51 BaseTransform at) 52 { 53 if (at == null) { 54 return out; 55 } 56 float mxx = (float) at.getMxx(); 57 float mxy = (float) at.getMxy(); 58 float myx = (float) at.getMyx(); 59 float myy = (float) at.getMyy(); 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 public PathConsumer2D inverseDeltaTransformConsumer(PathConsumer2D out, 77 BaseTransform at) 78 { 79 if (at == null) { 80 return out; 81 } 82 float mxx = (float) at.getMxx(); 83 float mxy = (float) at.getMxy(); 84 float myx = (float) at.getMyx(); 85 float myy = (float) at.getMyy(); 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 static final class DeltaScaleFilter implements PathConsumer2D { 104 private PathConsumer2D out; 105 private float sx, sy; 106 107 DeltaScaleFilter() {} 108 109 DeltaScaleFilter init(PathConsumer2D out, 110 float mxx, float 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(float x0, float y0) { 120 out.moveTo(x0 * sx, y0 * sy); 121 } 122 123 @Override 124 public void lineTo(float x1, float y1) { 125 out.lineTo(x1 * sx, y1 * sy); 126 } 127 128 @Override 129 public void quadTo(float x1, float y1, 130 float x2, float y2) 131 { 132 out.quadTo(x1 * sx, y1 * sy, 133 x2 * sx, y2 * sy); 134 } 135 136 @Override 137 public void curveTo(float x1, float y1, 138 float x2, float y2, 139 float x3, float 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 157 static final class DeltaTransformFilter implements PathConsumer2D { 158 private PathConsumer2D out; 159 private float mxx, mxy, myx, myy; 160 161 DeltaTransformFilter() {} 162 163 DeltaTransformFilter init(PathConsumer2D out, 164 float mxx, float mxy, 165 float myx, float myy) 166 { 167 this.out = out; 168 this.mxx = mxx; 169 this.mxy = mxy; 170 this.myx = myx; 171 this.myy = myy; 172 return this; // fluent API 173 } 174 175 @Override 176 public void moveTo(float x0, float y0) { 177 out.moveTo(x0 * mxx + y0 * mxy, 178 x0 * myx + y0 * myy); 179 } 180 181 @Override 182 public void lineTo(float x1, float y1) { 183 out.lineTo(x1 * mxx + y1 * mxy, 184 x1 * myx + y1 * myy); 185 } 186 187 @Override 188 public void quadTo(float x1, float y1, 189 float x2, float y2) 190 { 191 out.quadTo(x1 * mxx + y1 * mxy, 192 x1 * myx + y1 * myy, 193 x2 * mxx + y2 * mxy, 194 x2 * myx + y2 * myy); 195 } 196 197 @Override 198 public void curveTo(float x1, float y1, 199 float x2, float y2, 200 float x3, float y3) 201 { 202 out.curveTo(x1 * mxx + y1 * mxy, 203 x1 * myx + y1 * myy, 204 x2 * mxx + y2 * mxy, 205 x2 * myx + y2 * myy, 206 x3 * mxx + y3 * mxy, 207 x3 * myx + y3 * myy); 208 } 209 210 @Override 211 public void closePath() { 212 out.closePath(); 213 } 214 215 @Override 216 public void pathDone() { 217 out.pathDone(); 218 } 219 } 220 221 static final class Path2DWrapper implements PathConsumer2D { 222 private Path2D p2d; 223 224 Path2DWrapper() {} 225 226 Path2DWrapper init(Path2D p2d) { 227 this.p2d = p2d; 228 return this; 229 } 230 231 @Override 232 public void moveTo(float x0, float y0) { 233 p2d.moveTo(x0, y0); 234 } 235 236 @Override 237 public void lineTo(float x1, float y1) { 238 p2d.lineTo(x1, y1); 239 } 240 241 @Override 242 public void closePath() { 243 p2d.closePath(); 244 } 245 246 @Override 247 public void pathDone() {} 248 249 @Override 250 public void curveTo(float x1, float y1, 251 float x2, float y2, 252 float x3, float y3) 253 { 254 p2d.curveTo(x1, y1, x2, y2, x3, y3); 255 } 256 257 @Override 258 public void quadTo(float x1, float y1, float x2, float y2) { 259 p2d.quadTo(x1, y1, x2, y2); 260 } 261 } 262 }