1 17 18 19 20 package org.apache.fop.area; 21 22 import java.awt.Rectangle ; 23 import java.awt.geom.Rectangle2D ; 24 import java.io.Serializable ; 25 26 import org.apache.fop.datatypes.FODimension; 27 import org.apache.fop.fo.Constants; 28 29 34 public class CTM implements Serializable { 35 36 private double a, b, c, d, e, f; 37 38 private static final CTM CTM_LRTB = new CTM(1, 0, 0, 1, 0, 0); 39 private static final CTM CTM_RLTB = new CTM(-1, 0, 0, 1, 0, 0); 40 private static final CTM CTM_TBRL = new CTM(0, 1, -1, 0, 0, 0); 41 42 45 public CTM() { 46 a = 1; 47 b = 0; 48 c = 0; 49 d = 1; 50 e = 0; 51 f = 0; 52 } 53 54 64 public CTM(double a, double b, double c, double d, double e, double f) { 65 this.a = a; 66 this.b = b; 67 this.c = c; 68 this.d = d; 69 this.e = e; 70 this.f = f; 71 } 72 73 80 public CTM(double x, double y) { 81 this.a = 1; 82 this.b = 0; 83 this.c = 0; 84 this.d = 1; 85 this.e = x; 86 this.f = y; 87 } 88 89 94 protected CTM(CTM ctm) { 95 this.a = ctm.a; 96 this.b = ctm.b; 97 this.c = ctm.c; 98 this.d = ctm.d; 99 this.e = ctm.e; 100 this.f = ctm.f; 101 } 102 103 114 public static CTM getWMctm(int wm, int ipd, int bpd) { 115 CTM wmctm; 116 switch (wm) { 117 case Constants.EN_LR_TB: 118 return new CTM(CTM_LRTB); 119 case Constants.EN_RL_TB: 120 wmctm = new CTM(CTM_RLTB); 121 wmctm.e = ipd; 122 return wmctm; 123 case Constants.EN_TB_RL: wmctm = new CTM(CTM_TBRL); 126 wmctm.e = bpd; 127 return wmctm; 128 default: 130 return null; 131 } 132 } 133 134 140 public CTM multiply(CTM premult) { 141 CTM result = new CTM ((premult.a * a) + (premult.b * c), 142 (premult.a * b) + (premult.b * d), 143 (premult.c * a) + (premult.d * c), 144 (premult.c * b) + (premult.d * d), 145 (premult.e * a) + (premult.f * c) + e, 146 (premult.e * b) + (premult.f * d) + f); 147 return result; 148 } 149 150 157 public CTM rotate(double angle) { 158 double cos, sin; 159 if (angle == 90.0 || angle == -270.0) { 160 cos = 0.0; 161 sin = 1.0; 162 } else if (angle == 270.0 || angle == -90.0) { 163 cos = 0.0; 164 sin = -1.0; 165 } else if (angle == 180.0 || angle == -180.0) { 166 cos = -1.0; 167 sin = 0.0; 168 } else { 169 double rad = Math.toRadians(angle); 170 cos = Math.cos(rad); 171 sin = Math.sin(rad); 172 } 173 CTM rotate = new CTM(cos, -sin, sin, cos, 0, 0); 174 return multiply(rotate); 175 } 176 177 183 public CTM translate(double x, double y) { 184 CTM translate = new CTM(1, 0, 0, 1, x, y); 185 return multiply(translate); 186 } 187 188 194 public CTM scale(double x, double y) { 195 CTM scale = new CTM(x, 0, 0, y, 0, 0); 196 return multiply(scale); 197 } 198 199 205 public Rectangle2D transform(Rectangle2D inRect) { 206 int x1t = (int)(inRect.getX() * a + inRect.getY() * c + e); 209 int y1t = (int)(inRect.getX() * b + inRect.getY() * d + f); 210 int x2t = (int)((inRect.getX() + inRect.getWidth()) * a 211 + (inRect.getY() + inRect.getHeight()) * c + e); 212 int y2t = (int)((inRect.getX() + inRect.getWidth()) * b 213 + (inRect.getY() + inRect.getHeight()) * d + f); 214 if (x1t > x2t) { 216 int tmp = x2t; 217 x2t = x1t; 218 x1t = tmp; 219 } 220 if (y1t > y2t) { 221 int tmp = y2t; 222 y2t = y1t; 223 y1t = tmp; 224 } 225 return new Rectangle (x1t, y1t, x2t - x1t, y2t - y1t); 226 } 227 228 233 public String toString() { 234 return "[" + a + " " + b + " " + c + " " + d + " " + e + " " 235 + f + "]"; 236 } 237 238 244 public double[] toArray() { 245 return new double[]{a, b, c, d, e, f}; 246 } 247 248 256 public static CTM getCTMandRelDims(int absRefOrient, 257 int writingMode, 258 Rectangle2D absVPrect, 259 FODimension reldims) { 260 int width, height; 261 if (absRefOrient % 180 == 0) { 264 width = (int) absVPrect.getWidth(); 265 height = (int) absVPrect.getHeight(); 266 } else { 267 height = (int) absVPrect.getWidth(); 269 width = (int) absVPrect.getHeight(); 270 } 271 279 CTM ctm = new CTM(absVPrect.getX(), absVPrect.getY()); 280 281 if (absRefOrient != 0) { 283 switch (absRefOrient) { 286 case 90: 287 case -270: 288 ctm = ctm.translate(0, width); break; 290 case 180: 291 case -180: 292 ctm = ctm.translate(width, height); 293 break; 294 case 270: 295 case -90: 296 ctm = ctm.translate(height, 0); break; 298 default: 299 throw new RuntimeException (); 300 } 301 ctm = ctm.rotate(absRefOrient); 302 } 303 307 308 if (writingMode == Constants.EN_LR_TB || writingMode == Constants.EN_RL_TB) { 309 reldims.ipd = width; 310 reldims.bpd = height; 311 } else { 312 reldims.ipd = height; 313 reldims.bpd = width; 314 } 315 return ctm.multiply(CTM.getWMctm(writingMode, reldims.ipd, reldims.bpd)); 318 } 319 320 } 321 | Popular Tags |