/*
 * 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.
 */

/* $Id: TransformStackElement.java 1732018 2016-02-24 04:51:06Z gadams $ */

package org.apache.xmlgraphics.java2d;

import java.awt.geom.AffineTransform;

// CSOFF: EmptyBlock
// CSOFF: NoWhitespaceAfter
// CSOFF: OperatorWrap
// CSOFF: WhitespaceAround

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.
Version:$Id: TransformStackElement.java 1732018 2016-02-24 04:51:06Z gadams $ Originally authored by Vincent Hardy and Paul Evenblij.
/** * 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> * * @version $Id: TransformStackElement.java 1732018 2016-02-24 04:51:06Z gadams $ * * Originally authored by Vincent Hardy and Paul Evenblij. */
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) { throw new AssertionError(); } // 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; } }