/* * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.flex.compiler.internal.fxg.types; import org.apache.flex.compiler.internal.fxg.dom.transforms.MatrixNode; import org.apache.flex.swf.ISWFConstants; import org.apache.flex.swf.types.Matrix; /** * Utility class to help with matrix transformation for coordinate transformation. */ public class FXGMatrix { public double a; //x-axis scaling public double b; //x-axis skew public double c; //y-axis skew public double d; //y-axis scaling public double tx; //x-axis translation public double ty; //y-axis translation //constructor public FXGMatrix(double a, double b, double c, double d, double tx, double ty) { this.a = a; this.b = b; this.c = c; this.d = d; this.tx = tx; this.ty = ty; } //constructor - intializes matrix to identity matrix public FXGMatrix() { this.identity(); } public FXGMatrix(MatrixNode m) { this.a = m.a; this.b = m.b; this.c = m.c; this.d = m.d; this.tx = m.tx; this.ty = m.ty; } public void identity() { this.a = 1; this.b = 0; this.c = 0; this.d = 1; this.tx = 0; this.ty = 0; } //concatenates matrix m to the current matrix public void concat(FXGMatrix m) { // Matrix multiplication double new_a = a * m.a + b * m.c; double new_b = a * m.b + b * m.d; double new_c = c * m.a + d * m.c; double new_d = c * m.b + d * m.d; double new_tx = tx * m.a + ty * m.c + m.tx; double new_ty = tx * m.b + ty * m.d + m.ty; a = new_a; b = new_b; c = new_c; d = new_d; tx = new_tx; ty = new_ty; } //concatenates a rotation matrix with rotation angle to the current matrix public void rotate(double angle) { double cos = Math.cos(angle*Math.PI/180.0); double sin = Math.sin(angle*Math.PI/180.0); FXGMatrix newM = new FXGMatrix(cos, sin, -sin, cos, 0, 0); this.concat (newM); } //concatenates a scaling matrix with scale factors scaleX and scaleY to the current matrix public void scale(double scaleX, double scaleY) { FXGMatrix newM = new FXGMatrix(scaleX, 0, 0, scaleY, 0, 0); this.concat (newM); } //concatenates a transaltion matrix with translations (dx, dy) to the current matrix public void translate(double dx, double dy) { tx += dx; ty += dy; } //creates a matrix from the discrete transform parameters public static FXGMatrix convertToMatrix(double scaleX, double scaleY, double rotation, double tx, double ty) { FXGMatrix m = new FXGMatrix(); m.scale (scaleX, scaleY); m.rotate (rotation); m.translate(tx, ty); return m; } //returns a SWF Matrix data type that is equivalent to the current matrix public Matrix toSWFMatrix() { /*SWF matrices need to be invertible - check if it is invertible * disabled it for now - other apps seem to allow it FXGMatrix newm = new FXGMatrix(a, b, c, d, tx, ty); if (!newm.invert()) throw new FXGException("MatrixNotInvertible"); */ Matrix sm = new Matrix(); if (b != 0 || c != 0) sm.setRotate(b, c); if (a != 0 || d != 0) sm.setScale(a, d); sm.setTranslate((int)(tx*ISWFConstants.TWIPS_PER_PIXEL), (int)(ty*ISWFConstants.TWIPS_PER_PIXEL)); return sm; } /** * Set matrix attribute values with values in this FXGMatrix object. * @param node - the matrix node whose attribute values will be updated. */ public void setMatrixNodeValue(MatrixNode node) { node.a = this.a; node.b = this.b; node.c = this.c; node.d = this.d; node.tx = this.tx; node.ty = this.ty; } }