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/10/26 13:26:35 UTC

svn commit: r1535966 - in /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox: pdfviewer/PageDrawer.java pdfviewer/font/CFFGlyph2D.java pdfviewer/font/TTFGlyph2D.java util/operator/pagedrawer/Invoke.java

Author: lehmi
Date: Sat Oct 26 11:26:34 2013
New Revision: 1535966

URL: http://svn.apache.org/r1535966
Log:
PDFBOX-1741: take the whole font matrix into account when rendering a font, simplify the calculation of transformed coordinates as proposed by Vincent Hennebert

Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/CFFGlyph2D.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/TTFGlyph2D.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/Invoke.java

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java?rev=1535966&r1=1535965&r2=1535966&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java Sat Oct 26 11:26:34 2013
@@ -142,6 +142,8 @@ public class PageDrawer extends PDFStrea
         pageSize = pageDimension;
         graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
         graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+        graphics.translate(0, pageSize.height);
+        graphics.scale(1, -1);
         // Only if there is some content, we have to process it.
         // Otherwise we are done here and we will produce an empty page
         if (page.getContents() != null)
@@ -259,37 +261,16 @@ public class PageDrawer extends PDFStrea
             graphics.setPaint(paint);
 
             PDFont font = text.getFont();
-            Matrix textPos = text.getTextPos().copy();
-            float x = textPos.getXPosition();
-            // the 0,0-reference has to be moved from the lower left (PDF) to the upper left (AWT-graphics)
-            float y = pageSize.height - textPos.getYPosition();
-
-            // Set translation to 0,0. We only need the scaling and shearing except for type 3 fonts
-            if (!font.isType3Font())
-            {
-                textPos.setValue(2, 0, 0);
-                textPos.setValue(2, 1, 0);
-            }
-            // because of the moved 0,0-reference, we have to shear in the opposite direction
-            textPos.setValue(0, 1, (-1) * textPos.getValue(0, 1));
-            textPos.setValue(1, 0, (-1) * textPos.getValue(1, 0));
-            AffineTransform at = textPos.createAffineTransform();
+            AffineTransform at = text.getTextPos().createAffineTransform();
             PDMatrix fontMatrix = font.getFontMatrix();
-            // Type3 fonts don't use the same units within the font matrix as all the other fonts
-            if (font.isType3Font())
-            {
-                at.scale(fontMatrix.getValue(0, 0), fontMatrix.getValue(1, 1));
-            }
-            else
-            {
-                at.scale(fontMatrix.getValue(0, 0) * 1000f, fontMatrix.getValue(1, 1) * 1000f);
-            }
             // TODO setClip() is a massive performance hot spot. Investigate optimization possibilities
             graphics.setClip(graphicsState.getCurrentClippingPath());
 
             // use different methods to draw the string
             if (font.isType3Font())
             {
+                // Type3 fonts don't use the same units within the font matrix as all the other fonts
+                at.scale(fontMatrix.getValue(0, 0), fontMatrix.getValue(1, 1));
                 // Type3 fonts are using streams for each character
                 drawType3String((PDType3Font) font, text.getCharacter(), at);
             }
@@ -298,14 +279,18 @@ public class PageDrawer extends PDFStrea
                 Glyph2D glyph2D = createGlyph2D(font);
                 if (glyph2D != null)
                 {
+                    AffineTransform fontMatrixAT = new AffineTransform(fontMatrix.getValue(0, 0), fontMatrix.getValue(
+                            0, 1), fontMatrix.getValue(1, 0), fontMatrix.getValue(1, 1), fontMatrix.getValue(2, 0),
+                            fontMatrix.getValue(2, 1));
+                    at.concatenate(fontMatrixAT);
                     // Let PDFBox render the font if supported
-                    drawGlyph2D(glyph2D, text.getCodePoints(), at, x, y);
+                    drawGlyph2D(glyph2D, text.getCodePoints(), at);
                 }
                 else
                 {
                     // Use AWT to render the font (Type1 fonts, standard14 fonts, if the embedded font is substituted)
                     // TODO to be removed in the long run?
-                    drawString((PDSimpleFont) font, text.getCharacter(), at, x, y);
+                    drawString((PDSimpleFont) font, text.getCharacter(), at);
                 }
             }
         }
@@ -321,52 +306,36 @@ public class PageDrawer extends PDFStrea
      * @param glyph2D the Glyph2D implementation provided a GeneralPath for each glyph
      * @param codePoints the string to be rendered
      * @param at the transformation
-     * @param x the x coordinate of the text
-     * @param y the y coordinate of the text
      * @throws IOException if something went wrong
      */
-    private void drawGlyph2D(Glyph2D glyph2D, int[] codePoints, AffineTransform at, float x, float y)
-            throws IOException
+    private void drawGlyph2D(Glyph2D glyph2D, int[] codePoints, AffineTransform at) throws IOException
     {
-        Graphics2D g2d = (Graphics2D) graphics;
-        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
         for (int i = 0; i < codePoints.length; i++)
         {
-            if (!at.isIdentity())
+            GeneralPath path = glyph2D.getPathForCharactercode(codePoints[i]);
+            if (path != null)
             {
-                try
+                AffineTransform atInverse = null;
+                if (!at.isIdentity())
                 {
-                    AffineTransform atInv = at.createInverse();
-                    // do only apply the size of the transform, rotation will be realized by rotating the graphics,
-                    // otherwise the hp printers will not render the font
-                    // apply the transformation to the graphics, which should be the same as applying the
-                    // transformation itself to the text
-                    g2d.transform(at);
-                    // translate the coordinates
-                    Point2D.Float newXy = new Point2D.Float(x, y);
-                    atInv.transform(new Point2D.Float(x, y), newXy);
-
-                    GeneralPath path = glyph2D.getPathForCharactercode(codePoints[i]);
-                    if (path != null)
+                    try
+                    {
+                        atInverse = at.createInverse();
+                    }
+                    catch (NoninvertibleTransformException exception)
                     {
-                        g2d.translate(newXy.getX(), newXy.getY());
-                        g2d.fill(path);
-                        g2d.translate(-newXy.getX(), -newXy.getY());
+                        LOG.error("Can't invert the given affine transformation", exception);
                     }
-                    // restore the original transformation
-                    g2d.transform(atInv);
                 }
-                catch (NoninvertibleTransformException e)
+                if (atInverse != null)
                 {
-                    LOG.error("Error in " + getClass().getName() + ".drawGlyph2D", e);
+                    graphics.transform(at);
                 }
-            }
-            else
-            {
-                GeneralPath path = glyph2D.getPathForCharactercode(codePoints[i]);
-                if (path != null)
+                graphics.fill(path);
+                if (atInverse != null)
                 {
-                    g2d.draw(path);
+                    graphics.transform(atInverse);
                 }
             }
         }
@@ -378,6 +347,7 @@ public class PageDrawer extends PDFStrea
      * @param font the type3 font
      * @param string the string to be rendered
      * @param at the transformation
+     * 
      * @throws IOException if something went wrong
      */
     private void drawType3String(PDType3Font font, String string, AffineTransform at) throws IOException
@@ -413,51 +383,33 @@ public class PageDrawer extends PDFStrea
      * @param string The string to draw.
      * @param g The graphics to draw onto.
      * @param at The transformation matrix with all information for scaling and shearing of the font.
-     * @param x The x coordinate to draw at.
-     * @param y The y coordinate to draw at.
      * 
      * @throws IOException If there is an error drawing the specific string.
      */
-    private void drawString(PDSimpleFont font, String string, AffineTransform at, float x, float y) throws IOException
+    private void drawString(PDSimpleFont font, String string, AffineTransform at) throws IOException
     {
         Font awtFont = createAWTFont(font);
         FontRenderContext frc = new FontRenderContext(new AffineTransform(), true, true);
         GlyphVector glyphs = awtFont.createGlyphVector(frc, string);
+        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+        writeFont(at, glyphs);
+    }
 
-        Graphics2D g2d = (Graphics2D) graphics;
-        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-        writeFont(g2d, at, x, y, glyphs);
-    }
-
-    private void writeFont(final Graphics2D g2d, final AffineTransform at, final float x, final float y,
-            final GlyphVector glyphs)
-    {
-        // check if we have a rotation
-        if (!at.isIdentity())
-        {
-            try
-            {
-                AffineTransform atInv = at.createInverse();
-                // do only apply the size of the transform, rotation will be realized by rotating the graphics,
-                // otherwise the hp printers will not render the font
-                // apply the transformation to the graphics, which should be the same as applying the
-                // transformation itself to the text
-                g2d.transform(at);
-                // translate the coordinates
-                Point2D.Float newXy = new Point2D.Float(x, y);
-                atInv.transform(new Point2D.Float(x, y), newXy);
-                g2d.drawGlyphVector(glyphs, (float) newXy.getX(), (float) newXy.getY());
-                // restore the original transformation
-                g2d.transform(atInv);
-            }
-            catch (NoninvertibleTransformException e)
-            {
-                LOG.error("Error in " + getClass().getName() + ".writeFont", e);
-            }
+    private void writeFont(final AffineTransform at, final GlyphVector glyphs)
+    {
+        try
+        {
+            // Convert from PDF, where glyphs are upright when direction is from
+            // bottom to top, to AWT, where this is the other way around
+            at.scale(1, -1);
+            AffineTransform atInverse = at.createInverse();
+            graphics.transform(at);
+            graphics.drawGlyphVector(glyphs, 0, 0);
+            graphics.transform(atInverse);
         }
-        else
+        catch (NoninvertibleTransformException exception)
         {
-            g2d.drawGlyphVector(glyphs, x, y);
+            LOG.error("Can't invert the given affine transformation", exception);
         }
     }
 
@@ -654,17 +606,6 @@ public class PageDrawer extends PDFStrea
     }
 
     /**
-     * Fix the y coordinate.
-     * 
-     * @param y The y coordinate.
-     * @return The updated y coordinate.
-     */
-    public double fixY(double y)
-    {
-        return pageSize.getHeight() - y;
-    }
-
-    /**
      * Get the current line path to be drawn.
      * 
      * @return The current line path to be drawn.
@@ -794,7 +735,6 @@ public class PageDrawer extends PDFStrea
         double[] position = { x, y };
         getGraphicsState().getCurrentTransformationMatrix().createAffineTransform()
                 .transform(position, 0, position, 0, 1);
-        position[1] = fixY(position[1]);
         return new Point2D.Double(position[0], position[1]);
     }
 
@@ -862,7 +802,12 @@ public class PageDrawer extends PDFStrea
     {
         graphics.setComposite(getGraphicsState().getStrokeJavaComposite());
         graphics.setClip(getGraphicsState().getCurrentClippingPath());
-        graphics.drawImage(awtImage, at, null);
+        int width = awtImage.getWidth(null);
+        int height = awtImage.getHeight(null);
+        AffineTransform imageTransform = new AffineTransform(at);
+        imageTransform.scale(1.0 / width, -1.0 / height);
+        imageTransform.translate(0, -height);
+        graphics.drawImage(awtImage, imageTransform, null);
     }
 
     /**

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/CFFGlyph2D.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/CFFGlyph2D.java?rev=1535966&r1=1535965&r2=1535966&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/CFFGlyph2D.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/CFFGlyph2D.java Sat Oct 26 11:26:34 2013
@@ -18,10 +18,7 @@
  */
 package org.apache.pdfbox.pdfviewer.font;
 
-import java.awt.geom.AffineTransform;
 import java.awt.geom.GeneralPath;
-import java.awt.geom.Path2D;
-import java.awt.geom.PathIterator;
 import java.io.IOException;
 import java.util.Collection;
 import java.util.HashMap;
@@ -46,7 +43,6 @@ public class CFFGlyph2D implements Glyph
      */
     private static final Log LOG = LogFactory.getLog(CFFGlyph2D.class);
 
-    private float scale = 0.001f;
     private HashMap<Integer, GeneralPath> glyphs = new HashMap<Integer, GeneralPath>();
     private HashMap<Integer, Integer> codeToGlyph = new HashMap<Integer, Integer>();
     private String fontname = null;
@@ -81,9 +77,7 @@ public class CFFGlyph2D implements Glyph
             }
             if (glyph != null)
             {
-                AffineTransform atPath = AffineTransform.getScaleInstance(scale, scale);
-                glyph.transform(atPath);
-                glyphs.put(glyphId, transformGlyph(glyph));
+                glyphs.put(glyphId, glyph);
                 int code = mapping.getSID();
                 String name = mapping.getName();
                 if (nameToCode != null && nameToCode.containsKey(name))
@@ -96,48 +90,6 @@ public class CFFGlyph2D implements Glyph
         }
     }
 
-    private GeneralPath transformGlyph(GeneralPath glyph)
-    {
-        // we have to invert all y-coordinates due to the moved 0,0-reference
-        PathIterator iter = glyph.getPathIterator(null);
-        float[] currentSegment = new float[6];
-        Path2D.Float path = new Path2D.Float(iter.getWindingRule());
-        boolean glyphTransformed = false;
-        while (!iter.isDone())
-        {
-            glyphTransformed = true;
-            int type = iter.currentSegment(currentSegment);
-            switch (type)
-            {
-            case PathIterator.SEG_MOVETO:
-                path.moveTo(currentSegment[0], -currentSegment[1]);
-                break;
-            case PathIterator.SEG_LINETO:
-                path.lineTo(currentSegment[0], -currentSegment[1]);
-                break;
-            case PathIterator.SEG_QUADTO:
-                path.quadTo(currentSegment[0], -currentSegment[1], currentSegment[2], -currentSegment[3]);
-                break;
-            case PathIterator.SEG_CUBICTO:
-                path.curveTo(currentSegment[0], -currentSegment[1], currentSegment[2], -currentSegment[3],
-                        currentSegment[4], -currentSegment[5]);
-                break;
-            case PathIterator.SEG_CLOSE:
-                path.closePath();
-                break;
-            }
-            iter.next();
-        }
-        if (glyphTransformed)
-        {
-            return new GeneralPath(path);
-        }
-        else
-        {
-            return glyph;
-        }
-    }
-
     /**
      * {@inheritDoc}
      */

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/TTFGlyph2D.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/TTFGlyph2D.java?rev=1535966&r1=1535965&r2=1535966&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/TTFGlyph2D.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/TTFGlyph2D.java Sat Oct 26 11:26:34 2013
@@ -55,11 +55,6 @@ public class TTFGlyph2D implements Glyph
     private static final Log LOG = LogFactory.getLog(TTFGlyph2D.class);
 
     /**
-     * Default scaling value.
-     */
-    private static final float DEFAULT_SCALING = 0.001f;
-
-    /**
      * Start of coderanges.
      */
     private static final int START_RANGE_F000 = 0xF000;
@@ -69,7 +64,8 @@ public class TTFGlyph2D implements Glyph
     private TrueTypeFont font;
     private PDCIDFontType2Font descendantFont;
     private String name;
-    private float scale;
+    private float scale = 1.0f;
+    private boolean hasScaling = false;
     private CMAPEncodingEntry cmapWinUnicode = null;
     private CMAPEncodingEntry cmapWinSymbol = null;
     private CMAPEncodingEntry cmapMacintoshSymbol = null;
@@ -105,13 +101,12 @@ public class TTFGlyph2D implements Glyph
         font = trueTypeFont;
         // get units per em, which is used as scaling factor
         HeaderTable header = font.getHeader();
-        if (header != null)
-        {
-            scale = 1f / header.getUnitsPerEm();
-        }
-        else
+        if (header != null && header.getUnitsPerEm() != 1000)
         {
-            scale = DEFAULT_SCALING;
+            // in most case the scaling factor is set to 1.0f
+            // due to the fact that units per em is set to 1000
+            scale = 1000f / header.getUnitsPerEm();
+            hasScaling = true;
         }
         extractCMaps();
         extractFontSpecifics(pdFont, descFont);
@@ -191,7 +186,7 @@ public class TTFGlyph2D implements Glyph
             {
                 endPtIndex++;
             }
-            points[i] = new Point(gd.getXCoordinate(i), -gd.getYCoordinate(i),
+            points[i] = new Point(gd.getXCoordinate(i), gd.getYCoordinate(i),
                     (gd.getFlags(i) & GlyfDescript.ON_CURVE) != 0, endPt);
         }
         return points;
@@ -217,8 +212,11 @@ public class TTFGlyph2D implements Glyph
                 GlyphDescription gd = glyph.getDescription();
                 Point[] points = describe(gd);
                 glyphPath = calculatePath(points);
-                AffineTransform atScale = AffineTransform.getScaleInstance(scale, scale);
-                glyphPath.transform(atScale);
+                if (hasScaling)
+                {
+                    AffineTransform atScale = AffineTransform.getScaleInstance(scale, scale);
+                    glyphPath.transform(atScale);
+                }
                 glyphs.put(glyphId, glyphPath);
             }
             else

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/Invoke.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/Invoke.java?rev=1535966&r1=1535965&r2=1535966&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/Invoke.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/Invoke.java Sat Oct 26 11:26:34 2013
@@ -40,9 +40,9 @@ import org.apache.pdfbox.util.operator.O
 
 /**
  * Implementation of content stream operator for page drawer.
- *
+ * 
  * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
- * @version $Revision: 1.4 $
+ * 
  */
 public class Invoke extends OperatorProcessor
 {
@@ -54,24 +54,25 @@ public class Invoke extends OperatorProc
 
     /**
      * process : Do : Paint the specified XObject (section 4.7).
+     * 
      * @param operator The operator that is being executed.
      * @param arguments List
      * @throws IOException If there is an error invoking the sub object.
      */
     public void process(PDFOperator operator, List<COSBase> arguments) throws IOException
     {
-        PageDrawer drawer = (PageDrawer)context;
+        PageDrawer drawer = (PageDrawer) context;
         PDPage page = drawer.getPage();
-        COSName objectName = (COSName)arguments.get( 0 );
+        COSName objectName = (COSName) arguments.get(0);
         Map<String, PDXObject> xobjects = drawer.getResources().getXObjects();
-        PDXObject xobject = (PDXObject)xobjects.get( objectName.getName() );
-        if ( xobject == null )
+        PDXObject xobject = (PDXObject) xobjects.get(objectName.getName());
+        if (xobject == null)
         {
-            LOG.warn("Can't find the XObject for '"+objectName.getName()+"'");
+            LOG.warn("Can't find the XObject for '" + objectName.getName() + "'");
         }
-        else if( xobject instanceof PDXObjectImage )
+        else if (xobject instanceof PDXObjectImage)
         {
-            PDXObjectImage image = (PDXObjectImage)xobject;
+            PDXObjectImage image = (PDXObjectImage) xobject;
             try
             {
                 if (image.getImageMask())
@@ -81,59 +82,46 @@ public class Invoke extends OperatorProc
                     image.setStencilColor(drawer.getGraphicsState().getNonStrokingColor());
                 }
                 BufferedImage awtImage = image.getRGBImage();
-                if (awtImage == null) 
+                if (awtImage == null)
                 {
                     LOG.warn("getRGBImage returned NULL");
-                    return;//TODO PKOCH
+                    return;// TODO PKOCH
                 }
                 int imageWidth = awtImage.getWidth();
                 int imageHeight = awtImage.getHeight();
-                double pageHeight = drawer.getPageSize().getHeight();
 
                 LOG.debug("imageWidth: " + imageWidth + "\t\timageHeight: " + imageHeight);
-        
+
                 Matrix ctm = drawer.getGraphicsState().getCurrentTransformationMatrix();
-                float yScaling = ctm.getYScale();
-                float angle = (float)Math.acos(ctm.getValue(0, 0)/ctm.getXScale());
-                if (ctm.getValue(0, 1) < 0 && ctm.getValue(1, 0) > 0)
-                {
-                    angle = (-1)*angle;
-                }
-                ctm.setValue(2, 1, (float)(pageHeight - ctm.getYPosition() - Math.cos(angle)*yScaling));
-                ctm.setValue(2, 0, (float)(ctm.getXPosition() - Math.sin(angle)*yScaling));
-                // because of the moved 0,0-reference, we have to shear in the opposite direction
-                ctm.setValue(0, 1, (-1)*ctm.getValue(0, 1));
-                ctm.setValue(1, 0, (-1)*ctm.getValue(1, 0));
-                AffineTransform ctmAT = ctm.createAffineTransform();
-                ctmAT.scale(1f/imageWidth, 1f/imageHeight);
-                drawer.drawImage( awtImage, ctmAT ); 
+                AffineTransform imageTransform = ctm.createAffineTransform();
+                drawer.drawImage(awtImage, imageTransform);
             }
-            catch( Exception e )
+            catch (Exception e)
             {
                 e.printStackTrace();
                 LOG.error(e, e);
             }
         }
-        else if(xobject instanceof PDXObjectForm)
+        else if (xobject instanceof PDXObjectForm)
         {
             // save the graphics state
-            context.getGraphicsStack().push( (PDGraphicsState)context.getGraphicsState().clone() );
-            
-            PDXObjectForm form = (PDXObjectForm)xobject;
+            context.getGraphicsStack().push((PDGraphicsState) context.getGraphicsState().clone());
+
+            PDXObjectForm form = (PDXObjectForm) xobject;
             COSStream formContentstream = form.getCOSStream();
             // find some optional resources, instead of using the current resources
             PDResources pdResources = form.getResources();
             // if there is an optional form matrix, we have to map the form space to the user space
             Matrix matrix = form.getMatrix();
-            if (matrix != null) 
+            if (matrix != null)
             {
-                Matrix xobjectCTM = matrix.multiply( context.getGraphicsState().getCurrentTransformationMatrix());
+                Matrix xobjectCTM = matrix.multiply(context.getGraphicsState().getCurrentTransformationMatrix());
                 context.getGraphicsState().setCurrentTransformationMatrix(xobjectCTM);
             }
-            getContext().processSubStream( page, pdResources, formContentstream );
-            
+            getContext().processSubStream(page, pdResources, formContentstream);
+
             // restore the graphics state
-            context.setGraphicsState( (PDGraphicsState)context.getGraphicsStack().pop() );
+            context.setGraphicsState((PDGraphicsState) context.getGraphicsStack().pop());
         }
     }
 }