Home » pdfbox-1.1.0-src » org.apache.pdfbox.pdmodel.graphics.color » [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.pdmodel.graphics.color;
   18   
   19   import java.awt.Color;
   20   import java.awt.color.ColorSpace;
   21   import java.awt.color.ICC_ColorSpace;
   22   import java.io.IOException;
   23   import java.util.Arrays;
   24   
   25   import org.apache.commons.logging.Log;
   26   import org.apache.commons.logging.LogFactory;
   27   import org.apache.pdfbox.cos.COSArray;
   28   
   29   /**
   30    * This class represents a color space and the color value for that colorspace.
   31    *
   32    * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
   33    * @version $Revision: 1.7 $
   34    */
   35   public class PDColorState implements Cloneable
   36   {
   37   
   38       /**
   39        * Log instance.
   40        */
   41       private static final Log log = LogFactory.getLog(PDColorState.class);
   42   
   43       /**
   44        * The default color that can be set to replace all colors in
   45        * {@link ICC_ColorSpace ICC color spaces}.
   46        *
   47        * @see #setIccOverrideColor(Color)
   48        */
   49       private static volatile Color iccOverrideColor =
   50           Color.getColor("org.apache.pdfbox.ICC_override_color");
   51   
   52       /**
   53        * Sets the default color to replace all colors in
   54        * {@link ICC_ColorSpace ICC color spaces}. This will work around
   55        * a potential JVM crash caused by broken native ICC color manipulation
   56        * code in the Sun class libraries.
   57        * <p>
   58        * The default override can be specified by setting the color code in
   59        * <code>org.apache.pdfbox.ICC_override_color</code> system property
   60        * (see {@link Color#getColor(String)}. If this system property is not
   61        * specified, then the override is not enabled unless this method is
   62        * explicitly called.
   63        *
   64        * @param color ICC override color,
   65        *              or <code>null</code> to disable the override
   66        * @see <a href="https://issues.apache.org/jira/browse/PDFBOX-511">PDFBOX-511</a>
   67        * @since Apache PDFBox 0.8.1
   68        */
   69       public static void setIccOverrideColor(Color color) {
   70           iccOverrideColor = color;
   71       }
   72   
   73       private PDColorSpace colorSpace = new PDDeviceGray();
   74       private COSArray colorSpaceValue = new COSArray();
   75   
   76       /**
   77        * Cached Java AWT color based on the current color space and value.
   78        * The value is cleared whenever the color space or value is set.
   79        *
   80        * @see #getJavaColor()
   81        */
   82       private Color color = null;
   83   
   84       /**
   85        * Default constructor.
   86        *
   87        */
   88       public PDColorState()
   89       {
   90           setColorSpaceValue( new float[] {0});
   91       }
   92   
   93       /**
   94        * {@inheritDoc}
   95        */
   96       public Object clone()
   97       {
   98           PDColorState retval = new PDColorState();
   99           retval.colorSpace = this.colorSpace;
  100           retval.colorSpaceValue.clear();
  101           retval.colorSpaceValue.addAll( this.colorSpaceValue );
  102           return retval;
  103       }
  104   
  105       /**
  106        * Returns the Java AWT color based on the current color space and value.
  107        *
  108        * @return current Java AWT color
  109        * @throws IOException if the current color can not be created
  110        */
  111       public Color getJavaColor() throws IOException {
  112           if (color == null) {
  113               color = createColor();
  114           }
  115           return color;
  116       }
  117   
  118       /**
  119        * Create the current color from the colorspace and values.
  120        * @return The current awt color.
  121        * @throws IOException If there is an error creating the color.
  122        */
  123       private Color createColor() throws IOException
  124       {
  125           float[] components = colorSpaceValue.toFloatArray();
  126           try
  127           {
  128               if( colorSpace.getName().equals(PDDeviceRGB.NAME) && components.length == 3 )
  129               {
  130                   //for some reason, when using RGB and the RGB colorspace
  131                   //the new Color doesn't maintain exactly the same values
  132                   //I think some color conversion needs to take place first
  133                   //for now we will just make rgb a special case.
  134                   return new Color( components[0], components[1], components[2] );
  135               }
  136               else
  137               {
  138                   Color override = iccOverrideColor;
  139                   ColorSpace cs = colorSpace.getJavaColorSpace();
  140                   if (colorSpace.getName().equals(PDSeparation.NAME) && components.length == 1)
  141                   {
  142                       //Use that component as a single-integer RGB value
  143                       return new Color((int)components[0]);
  144                   }
  145                   else if (cs instanceof ICC_ColorSpace && override != null)
  146                   {
  147                       log.warn(
  148                               "Using an ICC override color to avoid a potential"
  149                               + " JVM crash (see PDFBOX-511)");
  150                       return override;
  151                   }
  152                   else
  153                   {
  154                       return new Color( cs, components, 1f );
  155                   }
  156               }
  157           }
  158           // Catch IOExceptions from PDColorSpace.getJavaColorSpace(), but
  159           // possibly also IllegalArgumentExceptions or other RuntimeExceptions
  160           // from the potentially complex color management code.
  161           catch (Exception e)
  162           {
  163               log.warn("Unable to create the color instance "
  164                       + Arrays.toString(components) + " in color space "
  165                       + colorSpace + "; using black instead", e);
  166               return Color.BLACK;
  167           }
  168       }
  169   
  170       /**
  171        * Constructor with an existing color set.  Default colorspace is PDDeviceGray.
  172        *
  173        * @param csValues The color space values.
  174        */
  175       public PDColorState( COSArray csValues )
  176       {
  177           colorSpaceValue = csValues;
  178       }
  179   
  180   
  181       /**
  182        * This will get the current colorspace.
  183        *
  184        * @return The current colorspace.
  185        */
  186       public PDColorSpace getColorSpace()
  187       {
  188           return colorSpace;
  189       }
  190   
  191       /**
  192        * This will set the current colorspace.
  193        *
  194        * @param value The new colorspace.
  195        */
  196       public void setColorSpace(PDColorSpace value)
  197       {
  198           colorSpace = value;
  199           // Clear color cache
  200           color = null;
  201       }
  202   
  203       /**
  204        * This will get the color space values.  Either 1 for gray or 3 for RGB.
  205        *
  206        * @return The colorspace values.
  207        */
  208       public float[] getColorSpaceValue()
  209       {
  210           return colorSpaceValue.toFloatArray();
  211       }
  212   
  213       /**
  214        * This will get the color space values.  Either 1 for gray or 3 for RGB.
  215        *
  216        * @return The colorspace values.
  217        */
  218       public COSArray getCOSColorSpaceValue()
  219       {
  220           return colorSpaceValue;
  221       }
  222   
  223       /**
  224        * This will update the colorspace values.
  225        *
  226        * @param value The new colorspace values.
  227        */
  228       public void setColorSpaceValue(float[] value)
  229       {
  230           colorSpaceValue.setFloatArray( value );
  231           // Clear color cache
  232           color = null;
  233       }
  234   }

Home » pdfbox-1.1.0-src » org.apache.pdfbox.pdmodel.graphics.color » [javadoc | source]