You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2013/08/25 15:45:34 UTC

svn commit: r1517288 - /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/edit/PDPageContentStream.java

Author: lehmi
Date: Sun Aug 25 13:45:33 2013
New Revision: 1517288

URL: http://svn.apache.org/r1517288
Log:
PDFBOX-1702: added some improvements based on a proposal by Philip Helger

Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/edit/PDPageContentStream.java

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/edit/PDPageContentStream.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/edit/PDPageContentStream.java?rev=1517288&r1=1517287&r2=1517288&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/edit/PDPageContentStream.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/edit/PDPageContentStream.java Sun Aug 25 13:45:33 2013
@@ -23,6 +23,7 @@ import java.awt.geom.PathIterator;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
 import java.text.NumberFormat;
 import java.util.ArrayList;
 import java.util.List;
@@ -51,13 +52,12 @@ import org.apache.pdfbox.pdmodel.graphic
 import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObject;
 import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage;
 
-
 /**
  * This class is a convenience for creating page content streams.  You MUST
  * call close() when you are finished with this object.
  *
  * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
- * @version $Revision: 1.19 $
+ * 
  */
 public class PDPageContentStream
 {
@@ -74,64 +74,78 @@ public class PDPageContentStream
     private PDColorSpace currentStrokingColorSpace = new PDDeviceGray();
     private PDColorSpace currentNonStrokingColorSpace = new PDDeviceGray();
 
-    //cached storage component for getting color values
+    // cached storage component for getting color values
     private float[] colorComponents = new float[4];
 
-    private NumberFormat formatDecimal = NumberFormat.getNumberInstance( Locale.US );
+    private NumberFormat formatDecimal = NumberFormat.getNumberInstance(Locale.US);
 
-    private static final String BEGIN_TEXT = "BT\n";
-    private static final String END_TEXT = "ET\n";
-    private static final String SET_FONT = "Tf\n";
-    private static final String MOVE_TEXT_POSITION = "Td\n";
-    private static final String SET_TEXT_MATRIX = "Tm\n";
-    private static final String SHOW_TEXT = "Tj\n";
-
-    private static final String SAVE_GRAPHICS_STATE = "q\n";
-    private static final String RESTORE_GRAPHICS_STATE = "Q\n";
-    private static final String CONCATENATE_MATRIX = "cm\n";
-    private static final String XOBJECT_DO = "Do\n";
-    private static final String RG_STROKING = "RG\n";
-    private static final String RG_NON_STROKING = "rg\n";
-    private static final String K_STROKING = "K\n";
-    private static final String K_NON_STROKING = "k\n";
-    private static final String G_STROKING = "G\n";
-    private static final String G_NON_STROKING = "g\n";
-    private static final String RECTANGLE = "re\n";
-    private static final String FILL_NON_ZERO = "f\n";
-    private static final String FILL_EVEN_ODD = "f*\n";
-    private static final String LINE_TO = "l\n";
-    private static final String MOVE_TO = "m\n";
-    private static final String CLOSE_STROKE = "s\n";
-    private static final String STROKE = "S\n";
-    private static final String LINE_WIDTH = "w\n";
-    private static final String LINE_JOIN_STYLE = "j\n";
-    private static final String LINE_CAP_STYLE = "J\n";
-    private static final String LINE_DASH_PATTERN = "d\n";
-    private static final String CLOSE_SUBPATH = "h\n";
-    private static final String CLIP_PATH_NON_ZERO = "W\n";
-    private static final String CLIP_PATH_EVEN_ODD = "W*\n";
-    private static final String NOP = "n\n";
-    private static final String BEZIER_312 = "c\n";
-    private static final String BEZIER_32 = "v\n";
-    private static final String BEZIER_313 = "y\n";
-
-    private static final String BMC = "BMC\n";
-    private static final String BDC = "BDC\n";
-    private static final String EMC = "EMC\n";
-
-    private static final String SET_STROKING_COLORSPACE = "CS\n";
-    private static final String SET_NON_STROKING_COLORSPACE = "cs\n";
-
-    private static final String SET_STROKING_COLOR_SIMPLE="SC\n";
-    private static final String SET_STROKING_COLOR_COMPLEX="SCN\n";
-    private static final String SET_NON_STROKING_COLOR_SIMPLE="sc\n";
-    private static final String SET_NON_STROKING_COLOR_COMPLEX="scn\n";
+    private static final String ISO8859 = "ISO-8859-1";
 
+    private static byte[] getISOBytes(final String s)
+    {
+        try
+        {
+            return s.getBytes(ISO8859);
+        }
+        catch (final UnsupportedEncodingException ex)
+        {
+            throw new IllegalStateException(ex);
+        }
+    }
+
+    private static final byte[] BEGIN_TEXT = getISOBytes("BT\n");
+    private static final byte[] END_TEXT = getISOBytes("ET\n");
+    private static final byte[] SET_FONT = getISOBytes("Tf\n");
+    private static final byte[] MOVE_TEXT_POSITION = getISOBytes("Td\n");
+    private static final byte[] SET_TEXT_MATRIX = getISOBytes("Tm\n");
+    private static final byte[] SHOW_TEXT = getISOBytes("Tj\n");
+
+    private static final byte[] SAVE_GRAPHICS_STATE = getISOBytes("q\n");
+    private static final byte[] RESTORE_GRAPHICS_STATE = getISOBytes("Q\n");
+    private static final byte[] CONCATENATE_MATRIX = getISOBytes("cm\n");
+    private static final byte[] XOBJECT_DO = getISOBytes("Do\n");
+    private static final byte[] RG_STROKING = getISOBytes("RG\n");
+    private static final byte[] RG_NON_STROKING = getISOBytes("rg\n");
+    private static final byte[] K_STROKING = getISOBytes("K\n");
+    private static final byte[] K_NON_STROKING = getISOBytes("k\n");
+    private static final byte[] G_STROKING = getISOBytes("G\n");
+    private static final byte[] G_NON_STROKING = getISOBytes("g\n");
+    private static final byte[] RECTANGLE = getISOBytes("re\n");
+    private static final byte[] FILL_NON_ZERO = getISOBytes("f\n");
+    private static final byte[] FILL_EVEN_ODD = getISOBytes("f*\n");
+    private static final byte[] LINE_TO = getISOBytes("l\n");
+    private static final byte[] MOVE_TO = getISOBytes("m\n");
+    private static final byte[] CLOSE_STROKE = getISOBytes("s\n");
+    private static final byte[] STROKE = getISOBytes("S\n");
+    private static final byte[] LINE_WIDTH = getISOBytes("w\n");
+    private static final byte[] LINE_JOIN_STYLE = getISOBytes("j\n");
+    private static final byte[] LINE_CAP_STYLE = getISOBytes("J\n");
+    private static final byte[] LINE_DASH_PATTERN = getISOBytes("d\n");
+    private static final byte[] CLOSE_SUBPATH = getISOBytes("h\n");
+    private static final byte[] CLIP_PATH_NON_ZERO = getISOBytes("W\n");
+    private static final byte[] CLIP_PATH_EVEN_ODD = getISOBytes("W*\n");
+    private static final byte[] NOP = getISOBytes("n\n");
+    private static final byte[] BEZIER_312 = getISOBytes("c\n");
+    private static final byte[] BEZIER_32 = getISOBytes("v\n");
+    private static final byte[] BEZIER_313 = getISOBytes("y\n");
+
+    private static final byte[] BMC = getISOBytes("BMC\n");
+    private static final byte[] BDC = getISOBytes("BDC\n");
+    private static final byte[] EMC = getISOBytes("EMC\n");
+
+    private static final byte[] SET_STROKING_COLORSPACE = getISOBytes("CS\n");
+    private static final byte[] SET_NON_STROKING_COLORSPACE = getISOBytes("cs\n");
+
+    private static final byte[] SET_STROKING_COLOR_SIMPLE = getISOBytes("SC\n");
+    private static final byte[] SET_STROKING_COLOR_COMPLEX = getISOBytes("SCN\n");
+    private static final byte[] SET_NON_STROKING_COLOR_SIMPLE = getISOBytes("sc\n");
+    private static final byte[] SET_NON_STROKING_COLOR_COMPLEX = getISOBytes("scn\n");
 
+    private static final byte[] OPENING_BRACKET = getISOBytes("[");
+    private static final byte[] CLOSING_BRACKET = getISOBytes("]");
 
     private static final int SPACE = 32;
 
-
     /**
      * Create a new PDPage content stream.
      *
@@ -139,9 +153,9 @@ public class PDPageContentStream
      * @param sourcePage The page to write the contents to.
      * @throws IOException If there is an error writing to the page contents.
      */
-    public PDPageContentStream( PDDocument document, PDPage sourcePage ) throws IOException
+    public PDPageContentStream(PDDocument document, PDPage sourcePage) throws IOException
     {
-        this(document,sourcePage,false,true);
+        this(document, sourcePage, false, true);
     }
 
     /**
@@ -153,11 +167,12 @@ public class PDPageContentStream
      * @param compress Tell if the content stream should compress the page contents.
      * @throws IOException If there is an error writing to the page contents.
      */
-    public PDPageContentStream( PDDocument document, PDPage sourcePage, boolean appendContent, boolean compress )
-        throws IOException
+    public PDPageContentStream(PDDocument document, PDPage sourcePage, boolean appendContent, boolean compress)
+            throws IOException
     {
-        this(document,sourcePage,appendContent,compress,false);
+        this(document, sourcePage, appendContent, compress, false);
     }
+
     /**
      * Create a new PDPage content stream.
      *
@@ -168,17 +183,16 @@ public class PDPageContentStream
      * @param resetContext Tell if the graphic context should be reseted.
      * @throws IOException If there is an error writing to the page contents.
      */
-    public PDPageContentStream( PDDocument document, PDPage sourcePage, boolean appendContent, 
-            boolean compress, boolean resetContext )
-            throws IOException
+    public PDPageContentStream(PDDocument document, PDPage sourcePage, boolean appendContent, boolean compress,
+            boolean resetContext) throws IOException
     {
-        
+
         page = sourcePage;
         resources = page.getResources();
-        if( resources == null )
+        if (resources == null)
         {
             resources = new PDResources();
-            page.setResources( resources );
+            page.setResources(resources);
         }
 
         // Get the pdstream from the source page instead of creating a new one
@@ -186,20 +200,20 @@ public class PDPageContentStream
         boolean hasContent = contents != null;
 
         // If request specifies the need to append to the document
-        if(appendContent && hasContent)
+        if (appendContent && hasContent)
         {
-            
+
             // Create a pdstream to append new content
-            PDStream contentsToAppend = new PDStream( document );
+            PDStream contentsToAppend = new PDStream(document);
 
             // This will be the resulting COSStreamArray after existing and new streams are merged
             COSStreamArray compoundStream = null;
 
             // If contents is already an array, a new stream is simply appended to it
-            if(contents.getStream() instanceof COSStreamArray)
+            if (contents.getStream() instanceof COSStreamArray)
             {
-                compoundStream = (COSStreamArray)contents.getStream();
-                compoundStream.appendStream( contentsToAppend.getStream());
+                compoundStream = (COSStreamArray) contents.getStream();
+                compoundStream.appendStream(contentsToAppend.getStream());
             }
             else
             {
@@ -210,33 +224,33 @@ public class PDPageContentStream
                 compoundStream = new COSStreamArray(newArray);
             }
 
-            if( compress )
+            if (compress)
             {
                 List<COSName> filters = new ArrayList<COSName>();
-                filters.add( COSName.FLATE_DECODE );
-                contentsToAppend.setFilters( filters );
+                filters.add(COSName.FLATE_DECODE);
+                contentsToAppend.setFilters(filters);
             }
 
             if (resetContext)
             {
-                // create a new stream to encapsulate the existing stream 
-                PDStream saveGraphics = new PDStream( document );
+                // create a new stream to encapsulate the existing stream
+                PDStream saveGraphics = new PDStream(document);
                 output = saveGraphics.createOutputStream();
                 // save the initial/unmodified graphics context
                 saveGraphicsState();
                 close();
-                if( compress )
+                if (compress)
                 {
                     List<COSName> filters = new ArrayList<COSName>();
-                    filters.add( COSName.FLATE_DECODE );
-                    saveGraphics.setFilters( filters );
+                    filters.add(COSName.FLATE_DECODE);
+                    saveGraphics.setFilters(filters);
                 }
                 // insert the new stream at the beginning
                 compoundStream.insertCOSStream(saveGraphics);
             }
 
             // Sets the compoundStream as page contents
-            sourcePage.setContents( new PDStream(compoundStream) );
+            sourcePage.setContents(new PDStream(compoundStream));
             output = contentsToAppend.createOutputStream();
             if (resetContext)
             {
@@ -250,18 +264,18 @@ public class PDPageContentStream
             {
                 LOG.warn("You are overwriting an existing content, you should use the append mode");
             }
-            contents = new PDStream( document );
-            if( compress )
+            contents = new PDStream(document);
+            if (compress)
             {
                 List<COSName> filters = new ArrayList<COSName>();
-                filters.add( COSName.FLATE_DECODE );
-                contents.setFilters( filters );
+                filters.add(COSName.FLATE_DECODE);
+                contents.setFilters(filters);
             }
-            sourcePage.setContents( contents );
+            sourcePage.setContents(contents);
             output = contents.createOutputStream();
         }
-        formatDecimal.setMaximumFractionDigits( 10 );
-        formatDecimal.setGroupingUsed( false );
+        formatDecimal.setMaximumFractionDigits(10);
+        formatDecimal.setGroupingUsed(false);
     }
 
     /**
@@ -272,11 +286,11 @@ public class PDPageContentStream
      */
     public void beginText() throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: Nested beginText() calls are not allowed." );
+            throw new IOException("Error: Nested beginText() calls are not allowed.");
         }
-        appendRawCommands( BEGIN_TEXT );
+        appendRawCommands(BEGIN_TEXT);
         inTextMode = true;
     }
 
@@ -288,11 +302,11 @@ public class PDPageContentStream
      */
     public void endText() throws IOException
     {
-        if( !inTextMode )
+        if (!inTextMode)
         {
-            throw new IOException( "Error: You must call beginText() before calling endText." );
+            throw new IOException("Error: You must call beginText() before calling endText.");
         }
-        appendRawCommands( END_TEXT );
+        appendRawCommands(END_TEXT);
         inTextMode = false;
     }
 
@@ -303,15 +317,15 @@ public class PDPageContentStream
      * @param fontSize The font size to draw the text.
      * @throws IOException If there is an error writing the font information.
      */
-    public void setFont( PDFont font, float fontSize ) throws IOException
+    public void setFont(PDFont font, float fontSize) throws IOException
     {
         String fontMapping = resources.addFont(font);
-        appendRawCommands( "/");
-        appendRawCommands( fontMapping );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( fontSize ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( SET_FONT );
+        appendRawCommands("/");
+        appendRawCommands(fontMapping);
+        appendRawCommands(SPACE);
+        appendRawCommands(fontSize);
+        appendRawCommands(SPACE);
+        appendRawCommands(SET_FONT);
     }
 
     /**
@@ -323,9 +337,9 @@ public class PDPageContentStream
      *
      * @throws IOException If there is an error writing to the stream.
      */
-    public void drawImage( PDXObjectImage image, float x, float y ) throws IOException
+    public void drawImage(PDXObjectImage image, float x, float y) throws IOException
     {
-        drawXObject( image, x, y, image.getWidth(), image.getHeight() );
+        drawXObject(image, x, y, image.getWidth(), image.getHeight());
     }
 
     /**
@@ -339,7 +353,7 @@ public class PDPageContentStream
      *
      * @throws IOException If there is an error writing to the stream.
      */
-    public void drawXObject( PDXObject xobject, float x, float y, float width, float height ) throws IOException
+    public void drawXObject(PDXObject xobject, float x, float y, float width, float height) throws IOException
     {
         AffineTransform transform = new AffineTransform(width, 0, 0, height, x, y);
         drawXObject(xobject, transform);
@@ -353,14 +367,14 @@ public class PDPageContentStream
      * @param transform the transformation matrix
      * @throws IOException If there is an error writing to the stream.
      */
-    public void drawXObject( PDXObject xobject, AffineTransform transform ) throws IOException
+    public void drawXObject(PDXObject xobject, AffineTransform transform) throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: drawXObject is not allowed within a text block." );
+            throw new IOException("Error: drawXObject is not allowed within a text block.");
         }
         String xObjectPrefix = null;
-        if( xobject instanceof PDXObjectImage )
+        if (xobject instanceof PDXObjectImage)
         {
             xObjectPrefix = "Im";
         }
@@ -370,17 +384,16 @@ public class PDPageContentStream
         }
         String objMapping = resources.addXObject(xobject, xObjectPrefix);
         saveGraphicsState();
-        appendRawCommands( SPACE );
+        appendRawCommands(SPACE);
         concatenate2CTM(transform);
-        appendRawCommands( SPACE );
-        appendRawCommands( "/" );
-        appendRawCommands( objMapping );
-        appendRawCommands( SPACE );
-        appendRawCommands( XOBJECT_DO );
+        appendRawCommands(SPACE);
+        appendRawCommands("/");
+        appendRawCommands(objMapping);
+        appendRawCommands(SPACE);
+        appendRawCommands(XOBJECT_DO);
         restoreGraphicsState();
     }
 
-
     /**
      * The Td operator.
      * A current text matrix will be replaced with a new one (1 0 0 1 x y).
@@ -388,17 +401,17 @@ public class PDPageContentStream
      * @param y The y coordinate.
      * @throws IOException If there is an error writing to the stream.
      */
-    public void moveTextPositionByAmount( float x, float y ) throws IOException
+    public void moveTextPositionByAmount(float x, float y) throws IOException
     {
-        if( !inTextMode )
+        if (!inTextMode)
         {
-            throw new IOException( "Error: must call beginText() before moveTextPositionByAmount");
+            throw new IOException("Error: must call beginText() before moveTextPositionByAmount");
         }
-        appendRawCommands( formatDecimal.format( x ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( y ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( MOVE_TEXT_POSITION );
+        appendRawCommands(x);
+        appendRawCommands(SPACE);
+        appendRawCommands(y);
+        appendRawCommands(SPACE);
+        appendRawCommands(MOVE_TEXT_POSITION);
     }
 
     /**
@@ -412,25 +425,25 @@ public class PDPageContentStream
      * @param f The f value of the matrix.
      * @throws IOException If there is an error writing to the stream.
      */
-    public void setTextMatrix( double a, double b, double c, double d, double e, double f ) throws IOException
+    public void setTextMatrix(double a, double b, double c, double d, double e, double f) throws IOException
     {
-        if( !inTextMode )
+        if (!inTextMode)
         {
-            throw new IOException( "Error: must call beginText() before setTextMatrix");
+            throw new IOException("Error: must call beginText() before setTextMatrix");
         }
-        appendRawCommands( formatDecimal.format( a ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( b ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( c ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( d ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( e ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( f ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( SET_TEXT_MATRIX );
+        appendRawCommands(a);
+        appendRawCommands(SPACE);
+        appendRawCommands(b);
+        appendRawCommands(SPACE);
+        appendRawCommands(c);
+        appendRawCommands(SPACE);
+        appendRawCommands(d);
+        appendRawCommands(SPACE);
+        appendRawCommands(e);
+        appendRawCommands(SPACE);
+        appendRawCommands(f);
+        appendRawCommands(SPACE);
+        appendRawCommands(SET_TEXT_MATRIX);
     }
 
     /**
@@ -441,9 +454,9 @@ public class PDPageContentStream
     */
     public void setTextMatrix(AffineTransform matrix) throws IOException
     {
-        if( !inTextMode )
+        if (!inTextMode)
         {
-            throw new IOException( "Error: must call beginText() before setTextMatrix");
+            throw new IOException("Error: must call beginText() before setTextMatrix");
         }
         appendMatrix(matrix);
         appendRawCommands(SET_TEXT_MATRIX);
@@ -458,7 +471,7 @@ public class PDPageContentStream
      * @param ty The translation value in y-direction.
      * @throws IOException If there is an error writing to the stream.
      */
-    public void setTextScaling( double sx, double sy, double tx, double ty ) throws IOException
+    public void setTextScaling(double sx, double sy, double tx, double ty) throws IOException
     {
         setTextMatrix(sx, 0, 0, sy, tx, ty);
     }
@@ -470,7 +483,7 @@ public class PDPageContentStream
      * @param ty The translation value in y-direction.
      * @throws IOException If there is an error writing to the stream.
      */
-    public void setTextTranslation( double tx, double ty ) throws IOException
+    public void setTextTranslation(double tx, double ty) throws IOException
     {
         setTextMatrix(1, 0, 0, 1, tx, ty);
     }
@@ -483,11 +496,11 @@ public class PDPageContentStream
      * @param ty The translation value in y-direction.
      * @throws IOException If there is an error writing to the stream.
      */
-    public void setTextRotation( double angle, double tx, double ty ) throws IOException
+    public void setTextRotation(double angle, double tx, double ty) throws IOException
     {
         double angleCos = Math.cos(angle);
         double angleSin = Math.sin(angle);
-        setTextMatrix( angleCos, angleSin, -angleSin, angleCos, tx, ty);
+        setTextMatrix(angleCos, angleSin, -angleSin, angleCos, tx, ty);
     }
 
     /**
@@ -500,21 +513,21 @@ public class PDPageContentStream
      * @param f The f value of the matrix.
      * @throws IOException If there is an error writing to the stream.
      */
-    public void concatenate2CTM( double a, double b, double c, double d, double e, double f ) throws IOException
+    public void concatenate2CTM(double a, double b, double c, double d, double e, double f) throws IOException
     {
-        appendRawCommands( formatDecimal.format( a ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( b ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( c ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( d ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( e ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( f ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( CONCATENATE_MATRIX );
+        appendRawCommands(a);
+        appendRawCommands(SPACE);
+        appendRawCommands(b);
+        appendRawCommands(SPACE);
+        appendRawCommands(c);
+        appendRawCommands(SPACE);
+        appendRawCommands(d);
+        appendRawCommands(SPACE);
+        appendRawCommands(e);
+        appendRawCommands(SPACE);
+        appendRawCommands(f);
+        appendRawCommands(SPACE);
+        appendRawCommands(CONCATENATE_MATRIX);
     }
 
     /**
@@ -535,18 +548,18 @@ public class PDPageContentStream
      * @param text The text to draw.
      * @throws IOException If an io exception occurs.
      */
-    public void drawString( String text ) throws IOException
+    public void drawString(String text) throws IOException
     {
-        if( !inTextMode )
+        if (!inTextMode)
         {
-            throw new IOException( "Error: must call beginText() before drawString");
+            throw new IOException("Error: must call beginText() before drawString");
         }
-        COSString string = new COSString( text );
+        COSString string = new COSString(text);
         ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-        string.writePDF( buffer );
-        appendRawCommands( new String( buffer.toByteArray(), "ISO-8859-1"));
-        appendRawCommands( SPACE );
-        appendRawCommands( SHOW_TEXT );
+        string.writePDF(buffer);
+        appendRawCommands(buffer.toByteArray());
+        appendRawCommands(SPACE);
+        appendRawCommands(SHOW_TEXT);
     }
 
     /**
@@ -556,11 +569,11 @@ public class PDPageContentStream
      * @param colorSpace The colorspace to write.
      * @throws IOException If there is an error writing the colorspace.
      */
-    public void setStrokingColorSpace( PDColorSpace colorSpace ) throws IOException
+    public void setStrokingColorSpace(PDColorSpace colorSpace) throws IOException
     {
         currentStrokingColorSpace = colorSpace;
-        writeColorSpace( colorSpace );
-        appendRawCommands( SET_STROKING_COLORSPACE );
+        writeColorSpace(colorSpace);
+        appendRawCommands(SET_STROKING_COLORSPACE);
     }
 
     /**
@@ -570,47 +583,46 @@ public class PDPageContentStream
      * @param colorSpace The colorspace to write.
      * @throws IOException If there is an error writing the colorspace.
      */
-    public void setNonStrokingColorSpace( PDColorSpace colorSpace ) throws IOException
+    public void setNonStrokingColorSpace(PDColorSpace colorSpace) throws IOException
     {
         currentNonStrokingColorSpace = colorSpace;
-        writeColorSpace( colorSpace );
-        appendRawCommands( SET_NON_STROKING_COLORSPACE );
+        writeColorSpace(colorSpace);
+        appendRawCommands(SET_NON_STROKING_COLORSPACE);
     }
 
-    private void writeColorSpace( PDColorSpace colorSpace ) throws IOException
+    private void writeColorSpace(PDColorSpace colorSpace) throws IOException
     {
         COSName key = null;
-        if( colorSpace instanceof PDDeviceGray ||
-            colorSpace instanceof PDDeviceRGB ||
-            colorSpace instanceof PDDeviceCMYK )
+        if (colorSpace instanceof PDDeviceGray || colorSpace instanceof PDDeviceRGB
+                || colorSpace instanceof PDDeviceCMYK)
         {
-            key = COSName.getPDFName( colorSpace.getName() );
+            key = COSName.getPDFName(colorSpace.getName());
         }
         else
         {
-            COSDictionary colorSpaces =
-                (COSDictionary)resources.getCOSDictionary().getDictionaryObject(COSName.COLORSPACE);
-            if( colorSpaces == null )
+            COSDictionary colorSpaces = (COSDictionary) resources.getCOSDictionary().getDictionaryObject(
+                    COSName.COLORSPACE);
+            if (colorSpaces == null)
             {
                 colorSpaces = new COSDictionary();
-                resources.getCOSDictionary().setItem( COSName.COLORSPACE, colorSpaces );
+                resources.getCOSDictionary().setItem(COSName.COLORSPACE, colorSpaces);
             }
-            key = colorSpaces.getKeyForValue( colorSpace.getCOSObject() );
+            key = colorSpaces.getKeyForValue(colorSpace.getCOSObject());
 
-            if( key == null )
+            if (key == null)
             {
                 int counter = 0;
                 String csName = "CS";
-                while( colorSpaces.containsValue( csName + counter ) )
+                while (colorSpaces.containsValue(csName + counter))
                 {
                     counter++;
                 }
-                key = COSName.getPDFName( csName + counter );
-                colorSpaces.setItem( key, colorSpace );
+                key = COSName.getPDFName(csName + counter);
+                colorSpaces.setItem(key, colorSpace);
             }
         }
-        key.writePDF( output );
-        appendRawCommands( SPACE );
+        key.writePDF(output);
+        appendRawCommands(SPACE);
     }
 
     /**
@@ -619,23 +631,21 @@ public class PDPageContentStream
      * @param components The components to set for the current color.
      * @throws IOException If there is an error while writing to the stream.
      */
-    public void setStrokingColor( float[] components ) throws IOException
+    public void setStrokingColor(float[] components) throws IOException
     {
-        for( int i=0; i< components.length; i++ )
+        for (int i = 0; i < components.length; i++)
         {
-            appendRawCommands( formatDecimal.format( components[i] ) );
-            appendRawCommands( SPACE );
+            appendRawCommands(components[i]);
+            appendRawCommands(SPACE);
         }
-        if( currentStrokingColorSpace instanceof PDSeparation ||
-            currentStrokingColorSpace instanceof PDPattern ||
-            currentStrokingColorSpace instanceof PDDeviceN ||
-            currentStrokingColorSpace instanceof PDICCBased )
+        if (currentStrokingColorSpace instanceof PDSeparation || currentStrokingColorSpace instanceof PDPattern
+                || currentStrokingColorSpace instanceof PDDeviceN || currentStrokingColorSpace instanceof PDICCBased)
         {
-            appendRawCommands( SET_STROKING_COLOR_COMPLEX );
+            appendRawCommands(SET_STROKING_COLOR_COMPLEX);
         }
         else
         {
-            appendRawCommands( SET_STROKING_COLOR_SIMPLE );
+            appendRawCommands(SET_STROKING_COLOR_SIMPLE);
         }
     }
 
@@ -645,26 +655,26 @@ public class PDPageContentStream
      * @param color The color to set.
      * @throws IOException If an IO error occurs while writing to the stream.
      */
-    public void setStrokingColor( Color color ) throws IOException
+    public void setStrokingColor(Color color) throws IOException
     {
         ColorSpace colorSpace = color.getColorSpace();
-        if( colorSpace.getType() == ColorSpace.TYPE_RGB )
+        if (colorSpace.getType() == ColorSpace.TYPE_RGB)
         {
-            setStrokingColor( color.getRed(), color.getGreen(), color.getBlue() );
+            setStrokingColor(color.getRed(), color.getGreen(), color.getBlue());
         }
-        else if( colorSpace.getType() == ColorSpace.TYPE_GRAY )
+        else if (colorSpace.getType() == ColorSpace.TYPE_GRAY)
         {
-            color.getColorComponents( colorComponents );
-            setStrokingColor( colorComponents[0] );
+            color.getColorComponents(colorComponents);
+            setStrokingColor(colorComponents[0]);
         }
-        else if( colorSpace.getType() == ColorSpace.TYPE_CMYK )
+        else if (colorSpace.getType() == ColorSpace.TYPE_CMYK)
         {
-            color.getColorComponents( colorComponents );
-            setStrokingColor( colorComponents[0], colorComponents[1], colorComponents[2], colorComponents[3] );
+            color.getColorComponents(colorComponents);
+            setStrokingColor(colorComponents[0], colorComponents[1], colorComponents[2], colorComponents[3]);
         }
         else
         {
-            throw new IOException( "Error: unknown colorspace:" + colorSpace );
+            throw new IOException("Error: unknown colorspace:" + colorSpace);
         }
     }
 
@@ -674,26 +684,26 @@ public class PDPageContentStream
      * @param color The color to set.
      * @throws IOException If an IO error occurs while writing to the stream.
      */
-    public void setNonStrokingColor( Color color ) throws IOException
+    public void setNonStrokingColor(Color color) throws IOException
     {
         ColorSpace colorSpace = color.getColorSpace();
-        if( colorSpace.getType() == ColorSpace.TYPE_RGB )
+        if (colorSpace.getType() == ColorSpace.TYPE_RGB)
         {
-            setNonStrokingColor( color.getRed(), color.getGreen(), color.getBlue() );
+            setNonStrokingColor(color.getRed(), color.getGreen(), color.getBlue());
         }
-        else if( colorSpace.getType() == ColorSpace.TYPE_GRAY )
+        else if (colorSpace.getType() == ColorSpace.TYPE_GRAY)
         {
-            color.getColorComponents( colorComponents );
-            setNonStrokingColor( colorComponents[0] );
+            color.getColorComponents(colorComponents);
+            setNonStrokingColor(colorComponents[0]);
         }
-        else if( colorSpace.getType() == ColorSpace.TYPE_CMYK )
+        else if (colorSpace.getType() == ColorSpace.TYPE_CMYK)
         {
-            color.getColorComponents( colorComponents );
-            setNonStrokingColor( colorComponents[0], colorComponents[1], colorComponents[2], colorComponents[3] );
+            color.getColorComponents(colorComponents);
+            setNonStrokingColor(colorComponents[0], colorComponents[1], colorComponents[2], colorComponents[3]);
         }
         else
         {
-            throw new IOException( "Error: unknown colorspace:" + colorSpace );
+            throw new IOException("Error: unknown colorspace:" + colorSpace);
         }
     }
 
@@ -705,15 +715,15 @@ public class PDPageContentStream
      * @param b The blue value.
      * @throws IOException If an IO error occurs while writing to the stream.
      */
-    public void setStrokingColor( int r, int g, int b ) throws IOException
+    public void setStrokingColor(int r, int g, int b) throws IOException
     {
-        appendRawCommands( formatDecimal.format( r/255d ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( g/255d ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( b/255d ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( RG_STROKING );
+        appendRawCommands(r / 255d);
+        appendRawCommands(SPACE);
+        appendRawCommands(g / 255d);
+        appendRawCommands(SPACE);
+        appendRawCommands(b / 255d);
+        appendRawCommands(SPACE);
+        appendRawCommands(RG_STROKING);
     }
 
     /**
@@ -725,17 +735,17 @@ public class PDPageContentStream
      * @param k The black value.
      * @throws IOException If an IO error occurs while writing to the stream.
      */
-    public void setStrokingColor( int c, int m, int y, int k) throws IOException
+    public void setStrokingColor(int c, int m, int y, int k) throws IOException
     {
-        appendRawCommands( formatDecimal.format( c/255d ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( m/255d ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( y/255d ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( k/255d ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( K_STROKING );
+        appendRawCommands(c / 255d);
+        appendRawCommands(SPACE);
+        appendRawCommands(m / 255d);
+        appendRawCommands(SPACE);
+        appendRawCommands(y / 255d);
+        appendRawCommands(SPACE);
+        appendRawCommands(k / 255d);
+        appendRawCommands(SPACE);
+        appendRawCommands(K_STROKING);
     }
 
     /**
@@ -747,17 +757,17 @@ public class PDPageContentStream
      * @param k The black value.
      * @throws IOException If an IO error occurs while writing to the stream.
      */
-    public void setStrokingColor( double c, double m, double y, double k) throws IOException
+    public void setStrokingColor(double c, double m, double y, double k) throws IOException
     {
-        appendRawCommands( formatDecimal.format( c ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( m ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( y ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( k ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( K_STROKING );
+        appendRawCommands(c);
+        appendRawCommands(SPACE);
+        appendRawCommands(m);
+        appendRawCommands(SPACE);
+        appendRawCommands(y);
+        appendRawCommands(SPACE);
+        appendRawCommands(k);
+        appendRawCommands(SPACE);
+        appendRawCommands(K_STROKING);
     }
 
     /**
@@ -766,11 +776,11 @@ public class PDPageContentStream
      * @param g The gray value.
      * @throws IOException If an IO error occurs while writing to the stream.
      */
-    public void setStrokingColor( int g ) throws IOException
+    public void setStrokingColor(int g) throws IOException
     {
-        appendRawCommands( formatDecimal.format( g/255d ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( G_STROKING );
+        appendRawCommands(g / 255d);
+        appendRawCommands(SPACE);
+        appendRawCommands(G_STROKING);
     }
 
     /**
@@ -779,11 +789,11 @@ public class PDPageContentStream
      * @param g The gray value.
      * @throws IOException If an IO error occurs while writing to the stream.
      */
-    public void setStrokingColor( double g ) throws IOException
+    public void setStrokingColor(double g) throws IOException
     {
-        appendRawCommands( formatDecimal.format( g ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( G_STROKING );
+        appendRawCommands(g);
+        appendRawCommands(SPACE);
+        appendRawCommands(G_STROKING);
     }
 
     /**
@@ -792,23 +802,22 @@ public class PDPageContentStream
      * @param components The components to set for the current color.
      * @throws IOException If there is an error while writing to the stream.
      */
-    public void setNonStrokingColor( float[] components ) throws IOException
+    public void setNonStrokingColor(float[] components) throws IOException
     {
-        for( int i=0; i< components.length; i++ )
+        for (int i = 0; i < components.length; i++)
         {
-            appendRawCommands( formatDecimal.format( components[i] ) );
-            appendRawCommands( SPACE );
+            appendRawCommands(components[i]);
+            appendRawCommands(SPACE);
         }
-        if( currentNonStrokingColorSpace instanceof PDSeparation ||
-            currentNonStrokingColorSpace instanceof PDPattern ||
-            currentNonStrokingColorSpace instanceof PDDeviceN ||
-            currentNonStrokingColorSpace instanceof PDICCBased )
+        if (currentNonStrokingColorSpace instanceof PDSeparation || currentNonStrokingColorSpace instanceof PDPattern
+                || currentNonStrokingColorSpace instanceof PDDeviceN
+                || currentNonStrokingColorSpace instanceof PDICCBased)
         {
-            appendRawCommands( SET_NON_STROKING_COLOR_COMPLEX );
+            appendRawCommands(SET_NON_STROKING_COLOR_COMPLEX);
         }
         else
         {
-            appendRawCommands( SET_NON_STROKING_COLOR_SIMPLE );
+            appendRawCommands(SET_NON_STROKING_COLOR_SIMPLE);
         }
     }
 
@@ -820,15 +829,15 @@ public class PDPageContentStream
      * @param b The blue value.
      * @throws IOException If an IO error occurs while writing to the stream.
      */
-    public void setNonStrokingColor( int r, int g, int b ) throws IOException
+    public void setNonStrokingColor(int r, int g, int b) throws IOException
     {
-        appendRawCommands( formatDecimal.format( r/255d ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( g/255d ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( b/255d ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( RG_NON_STROKING );
+        appendRawCommands(r / 255d);
+        appendRawCommands(SPACE);
+        appendRawCommands(g / 255d);
+        appendRawCommands(SPACE);
+        appendRawCommands(b / 255d);
+        appendRawCommands(SPACE);
+        appendRawCommands(RG_NON_STROKING);
     }
 
     /**
@@ -840,17 +849,17 @@ public class PDPageContentStream
      * @param k The black value.
      * @throws IOException If an IO error occurs while writing to the stream.
      */
-    public void setNonStrokingColor( int c, int m, int y, int k) throws IOException
+    public void setNonStrokingColor(int c, int m, int y, int k) throws IOException
     {
-        appendRawCommands( formatDecimal.format( c/255d ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( m/255d ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( y/255d ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( k/255d ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( K_NON_STROKING );
+        appendRawCommands(c / 255d);
+        appendRawCommands(SPACE);
+        appendRawCommands(m / 255d);
+        appendRawCommands(SPACE);
+        appendRawCommands(y / 255d);
+        appendRawCommands(SPACE);
+        appendRawCommands(k / 255d);
+        appendRawCommands(SPACE);
+        appendRawCommands(K_NON_STROKING);
     }
 
     /**
@@ -862,17 +871,17 @@ public class PDPageContentStream
      * @param k The black value.
      * @throws IOException If an IO error occurs while writing to the stream.
      */
-    public void setNonStrokingColor( double c, double m, double y, double k) throws IOException
+    public void setNonStrokingColor(double c, double m, double y, double k) throws IOException
     {
-        appendRawCommands( formatDecimal.format( c ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( m ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( y ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( k ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( K_NON_STROKING );
+        appendRawCommands(c);
+        appendRawCommands(SPACE);
+        appendRawCommands(m);
+        appendRawCommands(SPACE);
+        appendRawCommands(y);
+        appendRawCommands(SPACE);
+        appendRawCommands(k);
+        appendRawCommands(SPACE);
+        appendRawCommands(K_NON_STROKING);
     }
 
     /**
@@ -881,11 +890,11 @@ public class PDPageContentStream
      * @param g The gray value.
      * @throws IOException If an IO error occurs while writing to the stream.
      */
-    public void setNonStrokingColor( int g ) throws IOException
+    public void setNonStrokingColor(int g) throws IOException
     {
-        appendRawCommands( formatDecimal.format( g/255d ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( G_NON_STROKING );
+        appendRawCommands(g / 255d);
+        appendRawCommands(SPACE);
+        appendRawCommands(G_NON_STROKING);
     }
 
     /**
@@ -894,11 +903,11 @@ public class PDPageContentStream
      * @param g The gray value.
      * @throws IOException If an IO error occurs while writing to the stream.
      */
-    public void setNonStrokingColor( double g ) throws IOException
+    public void setNonStrokingColor(double g) throws IOException
     {
-        appendRawCommands( formatDecimal.format( g ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( G_NON_STROKING );
+        appendRawCommands(g);
+        appendRawCommands(SPACE);
+        appendRawCommands(G_NON_STROKING);
     }
 
     /**
@@ -910,21 +919,21 @@ public class PDPageContentStream
      * @param height The height of the rectangle.
      * @throws IOException If there is an error while drawing on the screen.
      */
-    public void addRect( float x, float y, float width, float height ) throws IOException
+    public void addRect(float x, float y, float width, float height) throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: addRect is not allowed within a text block." );
+            throw new IOException("Error: addRect is not allowed within a text block.");
         }
-        appendRawCommands( formatDecimal.format( x ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( y ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( width ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( height ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( RECTANGLE );
+        appendRawCommands(x);
+        appendRawCommands(SPACE);
+        appendRawCommands(y);
+        appendRawCommands(SPACE);
+        appendRawCommands(width);
+        appendRawCommands(SPACE);
+        appendRawCommands(height);
+        appendRawCommands(SPACE);
+        appendRawCommands(RECTANGLE);
     }
 
     /**
@@ -936,11 +945,11 @@ public class PDPageContentStream
      * @param height The height of the rectangle.
      * @throws IOException If there is an error while drawing on the screen.
      */
-    public void fillRect( float x, float y, float width, float height ) throws IOException
+    public void fillRect(float x, float y, float width, float height) throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: fillRect is not allowed within a text block." );
+            throw new IOException("Error: fillRect is not allowed within a text block.");
         }
         addRect(x, y, width, height);
         fill(PathIterator.WIND_NON_ZERO);
@@ -959,23 +968,23 @@ public class PDPageContentStream
      */
     public void addBezier312(float x1, float y1, float x2, float y2, float x3, float y3) throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: addBezier312 is not allowed within a text block." );
+            throw new IOException("Error: addBezier312 is not allowed within a text block.");
         }
-        appendRawCommands( formatDecimal.format( x1) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( y1) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( x2) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( y2) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( x3) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( y3) );
-        appendRawCommands( SPACE );
-        appendRawCommands( BEZIER_312 );
+        appendRawCommands(x1);
+        appendRawCommands(SPACE);
+        appendRawCommands(y1);
+        appendRawCommands(SPACE);
+        appendRawCommands(x2);
+        appendRawCommands(SPACE);
+        appendRawCommands(y2);
+        appendRawCommands(SPACE);
+        appendRawCommands(x3);
+        appendRawCommands(SPACE);
+        appendRawCommands(y3);
+        appendRawCommands(SPACE);
+        appendRawCommands(BEZIER_312);
     }
 
     /**
@@ -989,19 +998,19 @@ public class PDPageContentStream
      */
     public void addBezier32(float x2, float y2, float x3, float y3) throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: addBezier32 is not allowed within a text block." );
+            throw new IOException("Error: addBezier32 is not allowed within a text block.");
         }
-        appendRawCommands( formatDecimal.format( x2) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( y2) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( x3) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( y3) );
-        appendRawCommands( SPACE );
-        appendRawCommands( BEZIER_32 );
+        appendRawCommands(x2);
+        appendRawCommands(SPACE);
+        appendRawCommands(y2);
+        appendRawCommands(SPACE);
+        appendRawCommands(x3);
+        appendRawCommands(SPACE);
+        appendRawCommands(y3);
+        appendRawCommands(SPACE);
+        appendRawCommands(BEZIER_32);
     }
 
     /**
@@ -1015,22 +1024,21 @@ public class PDPageContentStream
      */
     public void addBezier31(float x1, float y1, float x3, float y3) throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: addBezier31 is not allowed within a text block." );
+            throw new IOException("Error: addBezier31 is not allowed within a text block.");
         }
-        appendRawCommands( formatDecimal.format( x1) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( y1) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( x3) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( y3) );
-        appendRawCommands( SPACE );
-        appendRawCommands( BEZIER_313 );
+        appendRawCommands(x1);
+        appendRawCommands(SPACE);
+        appendRawCommands(y1);
+        appendRawCommands(SPACE);
+        appendRawCommands(x3);
+        appendRawCommands(SPACE);
+        appendRawCommands(y3);
+        appendRawCommands(SPACE);
+        appendRawCommands(BEZIER_313);
     }
 
-
     /**
      * Add a line to the given coordinate.
      *
@@ -1038,17 +1046,17 @@ public class PDPageContentStream
      * @param y The y coordinate.
      * @throws IOException If there is an error while adding the line.
      */
-    public void moveTo( float x, float y) throws IOException
+    public void moveTo(float x, float y) throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: moveTo is not allowed within a text block." );
+            throw new IOException("Error: moveTo is not allowed within a text block.");
         }
-        appendRawCommands( formatDecimal.format( x) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( y) );
-        appendRawCommands( SPACE );
-        appendRawCommands( MOVE_TO );
+        appendRawCommands(x);
+        appendRawCommands(SPACE);
+        appendRawCommands(y);
+        appendRawCommands(SPACE);
+        appendRawCommands(MOVE_TO);
     }
 
     /**
@@ -1058,18 +1066,19 @@ public class PDPageContentStream
      * @param y The y coordinate.
      * @throws IOException If there is an error while adding the line.
      */
-    public void lineTo( float x, float y) throws IOException
+    public void lineTo(float x, float y) throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: lineTo is not allowed within a text block." );
+            throw new IOException("Error: lineTo is not allowed within a text block.");
         }
-        appendRawCommands( formatDecimal.format( x) );
-        appendRawCommands( SPACE );
-        appendRawCommands( formatDecimal.format( y) );
-        appendRawCommands( SPACE );
-        appendRawCommands( LINE_TO );
+        appendRawCommands(x);
+        appendRawCommands(SPACE);
+        appendRawCommands(y);
+        appendRawCommands(SPACE);
+        appendRawCommands(LINE_TO);
     }
+
     /**
      * add a line to the current path.
      *
@@ -1079,11 +1088,11 @@ public class PDPageContentStream
      * @param yEnd The end y coordinate.
      * @throws IOException If there is an error while adding the line.
      */
-    public void addLine( float xStart, float yStart, float xEnd, float yEnd ) throws IOException
+    public void addLine(float xStart, float yStart, float xEnd, float yEnd) throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: addLine is not allowed within a text block." );
+            throw new IOException("Error: addLine is not allowed within a text block.");
         }
         // moveTo
         moveTo(xStart, yStart);
@@ -1100,11 +1109,11 @@ public class PDPageContentStream
      * @param yEnd The end y coordinate.
      * @throws IOException If there is an error while drawing on the screen.
      */
-    public void drawLine( float xStart, float yStart, float xEnd, float yEnd ) throws IOException
+    public void drawLine(float xStart, float yStart, float xEnd, float yEnd) throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: drawLine is not allowed within a text block." );
+            throw new IOException("Error: drawLine is not allowed within a text block.");
         }
         addLine(xStart, yStart, xEnd, yEnd);
         // stroke
@@ -1119,13 +1128,13 @@ public class PDPageContentStream
      */
     public void addPolygon(float[] x, float[] y) throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: addPolygon is not allowed within a text block." );
+            throw new IOException("Error: addPolygon is not allowed within a text block.");
         }
         if (x.length != y.length)
         {
-            throw new IOException( "Error: some points are missing coordinate" );
+            throw new IOException("Error: some points are missing coordinate");
         }
         for (int i = 0; i < x.length; i++)
         {
@@ -1149,9 +1158,9 @@ public class PDPageContentStream
      */
     public void drawPolygon(float[] x, float[] y) throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: drawPolygon is not allowed within a text block." );
+            throw new IOException("Error: drawPolygon is not allowed within a text block.");
         }
         addPolygon(x, y);
         stroke();
@@ -1165,9 +1174,9 @@ public class PDPageContentStream
      */
     public void fillPolygon(float[] x, float[] y) throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: fillPolygon is not allowed within a text block." );
+            throw new IOException("Error: fillPolygon is not allowed within a text block.");
         }
         addPolygon(x, y);
         fill(PathIterator.WIND_NON_ZERO);
@@ -1180,11 +1189,11 @@ public class PDPageContentStream
      */
     public void stroke() throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: stroke is not allowed within a text block." );
+            throw new IOException("Error: stroke is not allowed within a text block.");
         }
-        appendRawCommands( STROKE );
+        appendRawCommands(STROKE);
     }
 
     /**
@@ -1194,11 +1203,11 @@ public class PDPageContentStream
      */
     public void closeAndStroke() throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: closeAndStroke is not allowed within a text block." );
+            throw new IOException("Error: closeAndStroke is not allowed within a text block.");
         }
-        appendRawCommands( CLOSE_STROKE );
+        appendRawCommands(CLOSE_STROKE);
     }
 
     /**
@@ -1210,21 +1219,21 @@ public class PDPageContentStream
      */
     public void fill(int windingRule) throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: fill is not allowed within a text block." );
+            throw new IOException("Error: fill is not allowed within a text block.");
         }
         if (windingRule == PathIterator.WIND_NON_ZERO)
         {
-            appendRawCommands( FILL_NON_ZERO );
+            appendRawCommands(FILL_NON_ZERO);
         }
         else if (windingRule == PathIterator.WIND_EVEN_ODD)
         {
-            appendRawCommands( FILL_EVEN_ODD );
+            appendRawCommands(FILL_EVEN_ODD);
         }
         else
         {
-            throw new IOException( "Error: unknown value for winding rule" );
+            throw new IOException("Error: unknown value for winding rule");
         }
 
     }
@@ -1236,11 +1245,11 @@ public class PDPageContentStream
      */
     public void closeSubPath() throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: closeSubPath is not allowed within a text block." );
+            throw new IOException("Error: closeSubPath is not allowed within a text block.");
         }
-        appendRawCommands( CLOSE_SUBPATH );
+        appendRawCommands(CLOSE_SUBPATH);
     }
 
     /**
@@ -1252,23 +1261,23 @@ public class PDPageContentStream
      */
     public void clipPath(int windingRule) throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: clipPath is not allowed within a text block." );
+            throw new IOException("Error: clipPath is not allowed within a text block.");
         }
         if (windingRule == PathIterator.WIND_NON_ZERO)
         {
-            appendRawCommands( CLIP_PATH_NON_ZERO );
-            appendRawCommands( NOP );
+            appendRawCommands(CLIP_PATH_NON_ZERO);
+            appendRawCommands(NOP);
         }
         else if (windingRule == PathIterator.WIND_EVEN_ODD)
         {
-            appendRawCommands( CLIP_PATH_EVEN_ODD );
-            appendRawCommands( NOP );
+            appendRawCommands(CLIP_PATH_EVEN_ODD);
+            appendRawCommands(NOP);
         }
         else
         {
-            throw new IOException( "Error: unknown value for winding rule" );
+            throw new IOException("Error: unknown value for winding rule");
         }
     }
 
@@ -1280,15 +1289,15 @@ public class PDPageContentStream
      */
     public void setLineWidth(float lineWidth) throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: setLineWidth is not allowed within a text block." );
+            throw new IOException("Error: setLineWidth is not allowed within a text block.");
         }
-        appendRawCommands( formatDecimal.format( lineWidth ) );
-        appendRawCommands( SPACE );
-        appendRawCommands( LINE_WIDTH );
+        appendRawCommands(lineWidth);
+        appendRawCommands(SPACE);
+        appendRawCommands(LINE_WIDTH);
     }
-    
+
     /**
      * Set the line join style.
      * @param lineJoinStyle 0 for miter join, 1 for round join, and 2 for bevel join.
@@ -1296,23 +1305,22 @@ public class PDPageContentStream
      */
     public void setLineJoinStyle(int lineJoinStyle) throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: setLineJoinStyle is not allowed within a text block." );
+            throw new IOException("Error: setLineJoinStyle is not allowed within a text block.");
         }
         if (lineJoinStyle >= 0 && lineJoinStyle <= 2)
         {
-            appendRawCommands( Integer.toString( lineJoinStyle ) );
-            appendRawCommands( SPACE );
-            appendRawCommands( LINE_JOIN_STYLE );
+            appendRawCommands(Integer.toString(lineJoinStyle));
+            appendRawCommands(SPACE);
+            appendRawCommands(LINE_JOIN_STYLE);
         }
         else
         {
-            throw new IOException( "Error: unknown value for line join style" );
+            throw new IOException("Error: unknown value for line join style");
         }
     }
-    
-    
+
     /**
      * Set the line cap style.
      * @param lineCapStyle 0 for butt cap, 1 for round cap, and 2 for projecting square cap.
@@ -1320,22 +1328,22 @@ public class PDPageContentStream
      */
     public void setLineCapStyle(int lineCapStyle) throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: setLineCapStyle is not allowed within a text block." );
+            throw new IOException("Error: setLineCapStyle is not allowed within a text block.");
         }
         if (lineCapStyle >= 0 && lineCapStyle <= 2)
         {
-            appendRawCommands( Integer.toString( lineCapStyle ) );
-            appendRawCommands( SPACE );
-            appendRawCommands( LINE_CAP_STYLE );
+            appendRawCommands(Integer.toString(lineCapStyle));
+            appendRawCommands(SPACE);
+            appendRawCommands(LINE_CAP_STYLE);
         }
         else
         {
-            throw new IOException( "Error: unknown value for line cap style" );
+            throw new IOException("Error: unknown value for line cap style");
         }
     }
-    
+
     /**
      * Set the line dash pattern.
      * @param pattern The pattern array
@@ -1344,20 +1352,21 @@ public class PDPageContentStream
      */
     public void setLineDashPattern(float[] pattern, float phase) throws IOException
     {
-        if( inTextMode )
+        if (inTextMode)
         {
-            throw new IOException( "Error: setLineDashPattern is not allowed within a text block." );
+            throw new IOException("Error: setLineDashPattern is not allowed within a text block.");
         }
-        appendRawCommands( "[" );
+        appendRawCommands(OPENING_BRACKET);
         for (float value : pattern)
         {
-            appendRawCommands( formatDecimal.format( value ) );
-            appendRawCommands( SPACE );
+            appendRawCommands(value);
+            appendRawCommands(SPACE);
         }
-        appendRawCommands( "] ");
-        appendRawCommands( formatDecimal.format(phase) );
-        appendRawCommands( SPACE );
-        appendRawCommands( LINE_DASH_PATTERN );
+        appendRawCommands(CLOSING_BRACKET);
+        appendRawCommands(SPACE);
+        appendRawCommands(phase);
+        appendRawCommands(SPACE);
+        appendRawCommands(LINE_DASH_PATTERN);
     }
 
     /**
@@ -1403,7 +1412,7 @@ public class PDPageContentStream
      */
     public void saveGraphicsState() throws IOException
     {
-        appendRawCommands( SAVE_GRAPHICS_STATE);
+        appendRawCommands(SAVE_GRAPHICS_STATE);
     }
 
     /**
@@ -1412,7 +1421,7 @@ public class PDPageContentStream
      */
     public void restoreGraphicsState() throws IOException
     {
-        appendRawCommands( RESTORE_GRAPHICS_STATE );
+        appendRawCommands(RESTORE_GRAPHICS_STATE);
     }
 
     /**
@@ -1421,9 +1430,9 @@ public class PDPageContentStream
      * @param commands The commands to append to the stream.
      * @throws IOException If an error occurs while writing to the stream.
      */
-    public void appendRawCommands( String commands ) throws IOException
+    public void appendRawCommands(String commands) throws IOException
     {
-        appendRawCommands( commands.getBytes( "ISO-8859-1" ) );
+        appendRawCommands(commands.getBytes("ISO-8859-1"));
     }
 
     /**
@@ -1432,9 +1441,9 @@ public class PDPageContentStream
      * @param commands The commands to append to the stream.
      * @throws IOException If an error occurs while writing to the stream.
      */
-    public void appendRawCommands( byte[] commands ) throws IOException
+    public void appendRawCommands(byte[] commands) throws IOException
     {
-        output.write( commands );
+        output.write(commands);
     }
 
     /**
@@ -1444,9 +1453,33 @@ public class PDPageContentStream
      *
      * @throws IOException If an error occurs while writing to the stream.
      */
-    public void appendRawCommands( int data ) throws IOException
+    public void appendRawCommands(int data) throws IOException
+    {
+        output.write(data);
+    }
+
+    /**
+     * This will append raw commands to the content stream.
+     *
+     * @param data Append a formatted double value to the stream.
+     *
+     * @throws IOException If an error occurs while writing to the stream.
+     */
+    public void appendRawCommands(double data) throws IOException
+    {
+        appendRawCommands(formatDecimal.format(data));
+    }
+
+    /**
+     * This will append raw commands to the content stream.
+     *
+     * @param data Append a formatted float value to the stream.
+     *
+     * @throws IOException If an error occurs while writing to the stream.
+     */
+    public void appendRawCommands(float data) throws IOException
     {
-        output.write( data );
+        appendRawCommands(formatDecimal.format(data));
     }
 
     /**
@@ -1465,7 +1498,7 @@ public class PDPageContentStream
         transform.getMatrix(values);
         for (double v : values)
         {
-            appendRawCommands(formatDecimal.format(v));
+            appendRawCommands(v);
             appendRawCommands(SPACE);
         }
     }
@@ -1478,5 +1511,9 @@ public class PDPageContentStream
     public void close() throws IOException
     {
         output.close();
+        currentNonStrokingColorSpace = null;
+        currentStrokingColorSpace = null;
+        page = null;
+        resources = null;
     }
 }