Home » pdfbox-1.1.0-src » org.apache.pdfbox.util » [javadoc | source]

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   package org.apache.pdfbox.util;
   18   
   19   import java.awt.geom.AffineTransform;
   20   
   21   /**
   22    * This class will be used for matrix manipulation.
   23    *
   24    * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
   25    * @version $Revision: 1.14 $
   26    */
   27   public class Matrix implements Cloneable
   28   {
   29       private float[] single =
   30       {
   31           1,0,0,
   32           0,1,0,
   33           0,0,1
   34       };
   35   
   36       /**
   37        * Constructor.
   38        */
   39       public Matrix()
   40       {
   41           //default constructor
   42       }
   43   
   44       /**
   45        * Create an affine transform from this matrix's values.
   46        *
   47        * @return An affine transform with this matrix's values.
   48        */
   49       public AffineTransform createAffineTransform()
   50       {
   51           AffineTransform retval = new AffineTransform(
   52               single[0], single[1],
   53               single[3], single[4],
   54               single[6], single[7] );
   55           return retval;
   56       }
   57   
   58       /**
   59        * Set the values of the matrix from the AffineTransform.
   60        *
   61        * @param af The transform to get the values from.
   62        */
   63       public void setFromAffineTransform( AffineTransform af )
   64       {
   65           single[0] = (float)af.getScaleX();
   66           single[1] = (float)af.getShearY();
   67           single[3] = (float)af.getShearX();
   68           single[4] = (float)af.getScaleY();
   69           single[6] = (float)af.getTranslateX();
   70           single[7] = (float)af.getTranslateY();
   71       }
   72   
   73       /**
   74        * This will get a matrix value at some point.
   75        *
   76        * @param row The row to get the value from.
   77        * @param column The column to get the value from.
   78        *
   79        * @return The value at the row/column position.
   80        */
   81       public float getValue( int row, int column )
   82       {
   83           return single[row*3+column];
   84       }
   85   
   86       /**
   87        * This will set a value at a position.
   88        *
   89        * @param row The row to set the value at.
   90        * @param column the column to set the value at.
   91        * @param value The value to set at the position.
   92        */
   93       public void setValue( int row, int column, float value )
   94       {
   95           single[row*3+column] = value;
   96       }
   97   
   98       /**
   99        * Return a single dimension array of all values in the matrix.
  100        *
  101        * @return The values ot this matrix.
  102        */
  103       public float[][] getValues()
  104       {
  105           float[][] retval = new float[3][3];
  106           retval[0][0] = single[0];
  107           retval[0][1] = single[1];
  108           retval[0][2] = single[2];
  109           retval[1][0] = single[3];
  110           retval[1][1] = single[4];
  111           retval[1][2] = single[5];
  112           retval[2][0] = single[6];
  113           retval[2][1] = single[7];
  114           retval[2][2] = single[8];
  115           return retval;
  116       }
  117   
  118       /**
  119        * Return a single dimension array of all values in the matrix.
  120        *
  121        * @return The values ot this matrix.
  122        */
  123       public double[][] getValuesAsDouble()
  124       {
  125           double[][] retval = new double[3][3];
  126           retval[0][0] = single[0];
  127           retval[0][1] = single[1];
  128           retval[0][2] = single[2];
  129           retval[1][0] = single[3];
  130           retval[1][1] = single[4];
  131           retval[1][2] = single[5];
  132           retval[2][0] = single[6];
  133           retval[2][1] = single[7];
  134           retval[2][2] = single[8];
  135           return retval;
  136       }
  137   
  138       /**
  139        * This will take the current matrix and multipy it with a matrix that is passed in.
  140        *
  141        * @param b The matrix to multiply by.
  142        *
  143        * @return The result of the two multiplied matrices.
  144        */
  145       public Matrix multiply( Matrix b )
  146       {
  147           Matrix result = new Matrix();
  148   
  149           if (b != null && b.single != null) 
  150           {
  151               float[] bMatrix = b.single;
  152               float[] resultMatrix = result.single;
  153               resultMatrix[0] = single[0] * bMatrix[0] + single[1] * bMatrix[3] + single[2] * bMatrix[6];
  154               resultMatrix[1] = single[0] * bMatrix[1] + single[1] * bMatrix[4] + single[2] * bMatrix[7];
  155               resultMatrix[2] = single[0] * bMatrix[2] + single[1] * bMatrix[5] + single[2] * bMatrix[8];
  156               resultMatrix[3] = single[3] * bMatrix[0] + single[4] * bMatrix[3] + single[5] * bMatrix[6];
  157               resultMatrix[4] = single[3] * bMatrix[1] + single[4] * bMatrix[4] + single[5] * bMatrix[7];
  158               resultMatrix[5] = single[3] * bMatrix[2] + single[4] * bMatrix[5] + single[5] * bMatrix[8];
  159               resultMatrix[6] = single[6] * bMatrix[0] + single[7] * bMatrix[3] + single[8] * bMatrix[6];
  160               resultMatrix[7] = single[6] * bMatrix[1] + single[7] * bMatrix[4] + single[8] * bMatrix[7];
  161               resultMatrix[8] = single[6] * bMatrix[2] + single[7] * bMatrix[5] + single[8] * bMatrix[8];
  162           }
  163           return result;
  164       }
  165   
  166       /**
  167        * Create a new matrix with just the scaling operators.
  168        *
  169        * @return A new matrix with just the scaling operators.
  170        */
  171       public Matrix extractScaling()
  172       {
  173           Matrix retval = new Matrix();
  174   
  175           retval.single[0] = this.single[0];
  176           retval.single[4] = this.single[4];
  177   
  178           return retval;
  179       }
  180   
  181       /**
  182        * Convenience method to create a scaled instance.
  183        *
  184        * @param x The xscale operator.
  185        * @param y The yscale operator.
  186        * @return A new matrix with just the x/y scaling
  187        */
  188       public static Matrix getScaleInstance( float x, float y)
  189       {
  190           Matrix retval = new Matrix();
  191   
  192           retval.single[0] = x;
  193           retval.single[4] = y;
  194   
  195           return retval;
  196       }
  197   
  198       /**
  199        * Create a new matrix with just the translating operators.
  200        *
  201        * @return A new matrix with just the translating operators.
  202        */
  203       public Matrix extractTranslating()
  204       {
  205           Matrix retval = new Matrix();
  206   
  207           retval.single[6] = this.single[6];
  208           retval.single[7] = this.single[7];
  209   
  210           return retval;
  211       }
  212   
  213       /**
  214        * Convenience method to create a translating instance.
  215        *
  216        * @param x The x translating operator.
  217        * @param y The y translating operator.
  218        * @return A new matrix with just the x/y translating.
  219        */
  220       public static Matrix getTranslatingInstance( float x, float y)
  221       {
  222           Matrix retval = new Matrix();
  223   
  224           retval.single[6] = x;
  225           retval.single[7] = y;
  226   
  227           return retval;
  228       }
  229   
  230       /**
  231        * Clones this object.
  232        * @return cloned matrix as an object.
  233        */
  234       public Object clone()
  235       {
  236           Matrix clone = new Matrix();
  237           System.arraycopy( single, 0, clone.single, 0, 9 );
  238           return clone;
  239       }
  240   
  241       /**
  242        * This will copy the text matrix data.
  243        *
  244        * @return a matrix that matches this one.
  245        */
  246       public Matrix copy()
  247       {
  248           return (Matrix) clone();
  249       }
  250   
  251       /**
  252        * This will return a string representation of the matrix.
  253        *
  254        * @return The matrix as a string.
  255        */
  256       public String toString()
  257       {
  258           StringBuffer result = new StringBuffer( "" );
  259           result.append( "[[" );
  260           result.append( single[0] + "," );
  261           result.append( single[1] + "," );
  262           result.append( single[2] + "][");
  263           result.append( single[3] + "," );
  264           result.append( single[4] + "," );
  265           result.append( single[5] + "][");
  266           result.append( single[6] + "," );
  267           result.append( single[7] + "," );
  268           result.append( single[8] + "]]");
  269   
  270           return result.toString();
  271       }
  272   
  273       /**
  274        * Get the xscaling factor of this matrix.
  275        * @return The x-scale.
  276        */
  277       public float getXScale()
  278       {
  279           float xScale = single[0];
  280   
  281           /**
  282            * BM: if the trm is rotated, the calculation is a little more complicated
  283            *
  284            * The rotation matrix multiplied with the scaling matrix is:
  285            * (   x   0   0)    ( cos  sin  0)    ( x*cos x*sin   0)
  286            * (   0   y   0) *  (-sin  cos  0)  = (-y*sin y*cos   0)
  287            * (   0   0   1)    (   0    0  1)    (     0     0   1)
  288            *
  289            * So, if you want to deduce x from the matrix you take
  290            * M(0,0) = x*cos and M(0,1) = x*sin and use the theorem of Pythagoras
  291            *
  292            * sqrt(M(0,0)^2+M(0,1)^2) =
  293            * sqrt(x2*cos2+x2*sin2) =
  294            * sqrt(x2*(cos2+sin2)) = <- here is the trick cos2+sin2 is one
  295            * sqrt(x2) =
  296            * abs(x)
  297            */
  298           if( !(single[1]==0.0f && single[3]==0.0f) )
  299           {
  300               xScale = (float)Math.sqrt(Math.pow(single[0], 2)+
  301                                         Math.pow(single[1], 2));
  302           }
  303           return xScale;
  304       }
  305   
  306       /**
  307        * Get the y scaling factor of this matrix.
  308        * @return The y-scale factor.
  309        */
  310       public float getYScale()
  311       {
  312           float yScale = single[4];
  313           if( !(single[1]==0.0f && single[3]==0.0f) )
  314           {
  315               yScale = (float)Math.sqrt(Math.pow(single[3], 2)+
  316                                         Math.pow(single[4], 2));
  317           }
  318           return yScale;
  319       }
  320   
  321       /**
  322        * Get the x position in the matrix.
  323        * @return The x-position.
  324        */
  325       public float getXPosition()
  326       {
  327           return single[6];
  328       }
  329   
  330       /**
  331        * Get the y position.
  332        * @return The y position.
  333        */
  334       public float getYPosition()
  335       {
  336           return single[7];
  337       }
  338   }

Home » pdfbox-1.1.0-src » org.apache.pdfbox.util » [javadoc | source]