/*
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.batik.ext.awt.g2d;
import java.awt.geom.AffineTransform;
Contains a description of an elementary transform stack element,
such as a rotate or translate. A transform stack element has a
type and a value, which is an array of double values.
Author: Vincent Hardy, Paul Evenblij Version: $Id: TransformStackElement.java 1733416 2016-03-03 07:07:13Z gadams $
/**
* Contains a description of an elementary transform stack element,
* such as a rotate or translate. A transform stack element has a
* type and a value, which is an array of double values.<br>
*
* @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
* @author <a href="mailto:paul_evenblij@compuware.com">Paul Evenblij</a>
* @version $Id: TransformStackElement.java 1733416 2016-03-03 07:07:13Z gadams $
*/
public abstract class TransformStackElement implements Cloneable{
Transform type
/**
* Transform type
*/
private TransformType type;
Value
/**
* Value
*/
private double[] transformParameters;
Params: - type – transform type
- transformParameters – parameters for transform
/**
* @param type transform type
* @param transformParameters parameters for transform
*/
protected TransformStackElement(TransformType type,
double[] transformParameters){
this.type = type;
this.transformParameters = transformParameters;
}
Returns: an object which is a deep copy of this one
/**
* @return an object which is a deep copy of this one
*/
public Object clone() {
TransformStackElement newElement = null;
// start with a shallow copy to get our implementations right
try {
newElement = (TransformStackElement) super.clone();
} catch(java.lang.CloneNotSupportedException ex) {}
// now deep copy the parameter array
double[] transformParameters = new double[this.transformParameters.length];
System.arraycopy(this.transformParameters, 0, transformParameters, 0, transformParameters.length);
newElement.transformParameters = transformParameters;
return newElement;
}
/*
* Factory methods
*/
public static TransformStackElement createTranslateElement(double tx,
double ty){
return new TransformStackElement(TransformType.TRANSLATE,
new double[]{ tx, ty }) {
boolean isIdentity(double[] parameters) {
return parameters[0] == 0 && parameters[1] == 0;
}
};
}
public static TransformStackElement createRotateElement(double theta){
return new TransformStackElement(TransformType.ROTATE,
new double[]{ theta }) {
boolean isIdentity(double[] parameters) {
return Math.cos(parameters[0]) == 1;
}
};
}
public static TransformStackElement createScaleElement(double scaleX,
double scaleY){
return new TransformStackElement(TransformType.SCALE,
new double[]{ scaleX, scaleY }) {
boolean isIdentity(double[] parameters) {
return parameters[0] == 1 && parameters[1] == 1;
}
};
}
public static TransformStackElement createShearElement(double shearX,
double shearY){
return new TransformStackElement(TransformType.SHEAR,
new double[]{ shearX, shearY }) {
boolean isIdentity(double[] parameters) {
return parameters[0] == 0 && parameters[1] == 0;
}
};
}
public static TransformStackElement createGeneralTransformElement
(AffineTransform txf){
double[] matrix = new double[6];
txf.getMatrix(matrix);
return new TransformStackElement(TransformType.GENERAL, matrix) {
boolean isIdentity(double[] m) {
return (m[0] == 1 && m[2] == 0 && m[4] == 0 &&
m[1] == 0 && m[3] == 1 && m[5] == 0);
}
};
}
Implementation should determine if the parameter list represents
an identity transform, for the instance transform type.
/**
* Implementation should determine if the parameter list represents
* an identity transform, for the instance transform type.
*/
abstract boolean isIdentity(double[] parameters);
Returns: true iff this transform is the identity transform
/**
* @return true iff this transform is the identity transform
*/
public boolean isIdentity() {
return isIdentity(transformParameters);
}
Returns: array of values containing this transform element's parameters
/**
* @return array of values containing this transform element's parameters
*/
public double[] getTransformParameters(){
return transformParameters;
}
Returns: this transform type
/**
* @return this transform type
*/
public TransformType getType(){
return type;
}
/*
* Concatenation utility. Requests this transform stack element
* to concatenate with the input stack element. Only elements
* of the same types are concatenated. For example, if this
* element represents a translation, it will concatenate with
* another translation, but not with any other kind of
* stack element.
* @param stackElement element to be concatenated with this one.
* @return true if the input stackElement was concatenated with
* this one. False otherwise.
*/
public boolean concatenate(TransformStackElement stackElement){
boolean canConcatenate = false;
if(type.toInt() == stackElement.type.toInt()){
canConcatenate = true;
switch(type.toInt()){
case TransformType.TRANSFORM_TRANSLATE:
transformParameters[0] += stackElement.transformParameters[0];
transformParameters[1] += stackElement.transformParameters[1];
break;
case TransformType.TRANSFORM_ROTATE:
transformParameters[0] += stackElement.transformParameters[0];
break;
case TransformType.TRANSFORM_SCALE:
transformParameters[0] *= stackElement.transformParameters[0];
transformParameters[1] *= stackElement.transformParameters[1];
break;
case TransformType.TRANSFORM_GENERAL:
transformParameters
= matrixMultiply(transformParameters,
stackElement.transformParameters);
break;
default:
canConcatenate = false;
}
}
return canConcatenate;
}
Multiplies two 2x3 matrices of double precision values
/**
* Multiplies two 2x3 matrices of double precision values
*/
private double[] matrixMultiply(double[] matrix1, double[] matrix2) {
double[] product = new double[6];
AffineTransform transform1 = new AffineTransform(matrix1);
transform1.concatenate(new AffineTransform(matrix2));
transform1.getMatrix(product);
return product;
}
}