Author: lehmi
Date: Sun Jan 22 13:13:39 2012
New Revision: 1234506
URL: http://svn.apache.org/viewvc?rev=1234506&view=rev
Log:
PDFBOX-610: removed font caching as proposed by Peter Costello, optimized and
simplified the handling of pdf resources
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDResources.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/edit/PDPageContentStream.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontFactory.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDResources.java
URL:
http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDResources.java?rev=1234506&r1=1234505&r2=1234506&view=diff
==============================================================================
---
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDResources.java
(original)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDResources.java
Sun Jan 22 13:13:39 2012
@@ -21,10 +21,11 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
-import org.apache.pdfbox.cos.COSStream;
import org.apache.pdfbox.pdmodel.common.COSDictionaryMap;
import org.apache.pdfbox.pdmodel.common.COSObjectable;
import org.apache.pdfbox.pdmodel.font.PDFont;
@@ -37,6 +38,7 @@ import org.apache.pdfbox.pdmodel.graphic
import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObject;
import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage;
import org.apache.pdfbox.pdmodel.markedcontent.PDPropertyList;
+import org.apache.pdfbox.util.MapUtil;
/**
* This represents a set of resources available at the page/pages/stream level.
@@ -47,6 +49,20 @@ import org.apache.pdfbox.pdmodel.markedc
public class PDResources implements COSObjectable
{
private COSDictionary resources;
+ private Map<String,PDFont> fonts = null;
+ private Map<PDFont, String> fontMappings = null;
+ private Map<String,PDColorSpace> colorspaces = null;
+ private Map<String,PDXObject> xobjects = null;
+ private Map<PDXObject,String> xobjectMappings = null;
+ private HashMap<String,PDXObjectImage> images = null;
+ private Map<String,PDExtendedGraphicsState> graphicsStates = null;
+ private Map<String,PDPatternResources> patterns = null;
+ private Map<String,PDShadingResources> shadings = null;
+
+ /**
+ * Log instance.
+ */
+ private static final Log LOG = LogFactory.getLog(PDResources.class);
/**
* Default constructor.
@@ -87,84 +103,145 @@ public class PDResources implements COSO
}
/**
- * This will get the map of fonts. This will never return null. The keys
are string
- * and the values are PDFont objects.
- *
- * @param fontCache A map of existing PDFont objects to reuse.
- * @return The map of fonts.
- *
- * @throws IOException If there is an error getting the fonts.
+ * Calling this will release all cached information.
+ *
*/
- public Map<String,PDFont> getFonts( Map<String,PDFont> fontCache ) throws
IOException
+ public void clear()
{
- Map<String,PDFont> retval = null;
- COSDictionary fonts = (COSDictionary)resources.getDictionaryObject(
COSName.FONT );
-
- if( fonts == null )
+ if (fonts != null)
{
- fonts = new COSDictionary();
- resources.setItem( COSName.FONT, fonts );
+ fonts.clear();
}
-
- Map<String,PDFont> actuals = new HashMap<String,PDFont>();
- retval = new COSDictionaryMap( actuals, fonts );
- for( COSName fontName : fonts.keySet() )
+ if (colorspaces != null)
{
- COSBase font = fonts.getDictionaryObject( fontName );
- //data-000174.pdf contains a font that is a COSArray, looks to be
an error in the
- //PDF, we will just ignore entries that are not dictionaries.
- if( font instanceof COSDictionary )
- {
- COSDictionary fontDictionary = (COSDictionary)font;
- actuals.put( fontName.getName(), PDFontFactory.createFont(
fontDictionary, fontCache ));
- }
+ colorspaces.clear();
}
- return retval;
+ if (xobjects != null)
+ {
+ xobjects.clear();
+ }
+ if (images != null)
+ {
+ images.clear();
+ }
+ if (graphicsStates != null)
+ {
+ graphicsStates.clear();
+ }
+ if (patterns != null)
+ {
+ patterns.clear();
+ }
+ if (shadings != null)
+ {
+ shadings.clear();
+ }
+ resources = null;
}
-
/**
* This will get the map of fonts. This will never return null. The keys
are string
* and the values are PDFont objects.
*
+ * @param fontCache A map of existing PDFont objects to reuse.
* @return The map of fonts.
*
* @throws IOException If there is an error getting the fonts.
+ *
+ * @deprecated due to some side effects font caching is no longer
supported, use {@link #getFonts()} instead
*/
- public Map<String,PDFont> getFonts() throws IOException
+ public Map<String,PDFont> getFonts( Map<String,PDFont> fontCache ) throws
IOException
{
- return getFonts( null );
+ return getFonts();
}
/**
- * This will get the map of PDXObjects that are in the resource dictionary.
- *
- * @return The map of xobjects.
+ * This will get the map of fonts. This will never return null.
*
- * @throws IOException If there is an error creating the xobjects.
+ * @return The map of fonts.
*/
- public Map<String,PDXObject> getXObjects() throws IOException
+ public Map<String,PDFont> getFonts()
{
- Map<String,PDXObject> retval = null;
- COSDictionary xobjects = (COSDictionary)resources.getDictionaryObject(
COSName.XOBJECT );
-
- if( xobjects == null )
+ if (fonts == null)
{
- xobjects = new COSDictionary();
- resources.setItem( COSName.XOBJECT, xobjects );
+ // at least an empty map will be returned
+ // TODO we should return null instead of an empty map
+ fonts = new HashMap<String,PDFont>();
+ COSDictionary fontsDictionary =
(COSDictionary)resources.getDictionaryObject( COSName.FONT );
+ if( fontsDictionary == null )
+ {
+ fontsDictionary = new COSDictionary();
+ resources.setItem( COSName.FONT, fontsDictionary );
+ }
+ else
+ {
+ for( COSName fontName : fontsDictionary.keySet() )
+ {
+ COSBase font = fontsDictionary.getDictionaryObject(
fontName );
+ //data-000174.pdf contains a font that is a COSArray,
looks to be an error in the
+ //PDF, we will just ignore entries that are not
dictionaries.
+ if( font instanceof COSDictionary )
+ {
+ PDFont newFont = null;
+ try
+ {
+ newFont = PDFontFactory.createFont(
(COSDictionary)font );
+ }
+ catch (IOException exception)
+ {
+ LOG.error("error while creating a font",
exception);
+ }
+ if (newFont != null)
+ {
+ fonts.put( fontName.getName(), newFont);
+ }
+ }
+ }
+ }
}
+ return fonts;
+ }
- Map<String,PDXObject> actuals = new HashMap<String,PDXObject>();
- retval = new COSDictionaryMap( actuals, xobjects );
- for( COSName objName : xobjects.keySet() )
+ /**
+ * This will get the map of PDXObjects that are in the resource dictionary.
+ * This will never return null.
+ *
+ * @return The map of xobjects.
+ */
+ public Map<String,PDXObject> getXObjects()
+ {
+ if (xobjects == null)
{
- COSBase cosObject = xobjects.getDictionaryObject(objName);
- PDXObject xobject = PDXObject.createXObject( cosObject );
- if( xobject !=null )
+ // at least an empty map will be returned
+ // TODO we should return null instead of an empty map
+ xobjects = new HashMap<String,PDXObject>();
+ COSDictionary xobjectsDictionary =
(COSDictionary)resources.getDictionaryObject( COSName.XOBJECT );
+ if( xobjectsDictionary == null )
+ {
+ xobjectsDictionary = new COSDictionary();
+ resources.setItem( COSName.XOBJECT, xobjectsDictionary );
+ }
+ else
{
- actuals.put( objName.getName(), xobject);
+ xobjects = new HashMap<String,PDXObject>();
+ for( COSName objName : xobjectsDictionary.keySet() )
+ {
+ PDXObject xobject = null;
+ try
+ {
+ xobject = PDXObject.createXObject(
xobjectsDictionary.getDictionaryObject(objName) );
+ }
+ catch (IOException exception)
+ {
+ LOG.error("error while creating a xobject", exception);
+ }
+ if( xobject != null )
+ {
+ xobjects.put( objName.getName(), xobject);
+ }
+ }
}
}
- return retval;
+ return xobjects;
}
/**
@@ -179,42 +256,42 @@ public class PDResources implements COSO
*/
public Map<String,PDXObjectImage> getImages() throws IOException
{
- Map<String,PDXObjectImage> retval = null;
- COSDictionary images = (COSDictionary)resources.getDictionaryObject(
COSName.XOBJECT );
-
- if( images == null )
- {
- images = new COSDictionary();
- resources.setItem( COSName.XOBJECT, images );
- }
-
- Map<String,PDXObjectImage> actuals = new
HashMap<String,PDXObjectImage>();
- retval = new COSDictionaryMap( actuals, images );
- for( COSName imageName : images.keySet() )
+ if (images == null)
{
- COSStream image =
(COSStream)(images.getDictionaryObject(imageName));
-
- COSName subType
=(COSName)image.getDictionaryObject(COSName.SUBTYPE);
- if( subType.equals(COSName.IMAGE) )
+ Map<String,PDXObject> allXObjects = getXObjects();
+ images = new HashMap<String,PDXObjectImage>();
+ for( String imageName : allXObjects.keySet() )
{
- PDXObjectImage ximage =
(PDXObjectImage)PDXObject.createXObject( image );
- if( ximage !=null )
+ PDXObject xobject = images.get(imageName);
+ if( xobject instanceof PDXObjectImage )
{
- actuals.put( imageName.getName(), ximage);
+ images.put( imageName, (PDXObjectImage)xobject);
}
}
}
- return retval;
+ return images;
}
/**
* This will set the map of fonts.
*
- * @param fonts The new map of fonts.
+ * @param fontsValue The new map of fonts.
+ */
+ public void setFonts( Map<String,PDFont> fontsValue )
+ {
+ fonts = fontsValue;
+ resources.setItem( COSName.FONT, COSDictionaryMap.convert( fontsValue
) );
+ }
+
+ /**
+ * This will set the map of xobjects.
+ *
+ * @param xobjectsValue The new map of xobjects.
*/
- public void setFonts( Map<String,PDFont> fonts )
+ public void setXObjects( Map<String,PDXObject> xobjectsValue )
{
- resources.setItem( COSName.FONT, COSDictionaryMap.convert( fonts ) );
+ xobjects = xobjectsValue;
+ resources.setItem( COSName.XOBJECT, COSDictionaryMap.convert(
xobjectsValue ) );
}
/**
@@ -223,35 +300,46 @@ public class PDResources implements COSO
* and the values are PDColorSpace objects.
*
* @return The map of colorspaces.
- *
- * @throws IOException If there is an error getting the colorspaces.
*/
- public Map<String,PDColorSpace> getColorSpaces() throws IOException
+ public Map<String,PDColorSpace> getColorSpaces()
{
- Map<String,PDColorSpace> retval = null;
- COSDictionary colorspaces =
(COSDictionary)resources.getDictionaryObject( COSName.COLORSPACE );
-
- if( colorspaces != null )
+ if (colorspaces == null)
{
- Map<String,PDColorSpace> actuals = new
HashMap<String,PDColorSpace>();
- retval = new COSDictionaryMap( actuals, colorspaces );
- for( COSName csName : colorspaces.keySet() )
+ COSDictionary csDictionary =
(COSDictionary)resources.getDictionaryObject( COSName.COLORSPACE );
+ if( csDictionary != null )
{
- COSBase cs = colorspaces.getDictionaryObject( csName );
- actuals.put( csName.getName(),
PDColorSpaceFactory.createColorSpace( cs ) );
+ colorspaces = new HashMap<String,PDColorSpace>();
+ for( COSName csName : csDictionary.keySet() )
+ {
+ COSBase cs = csDictionary.getDictionaryObject( csName );
+ PDColorSpace colorspace = null;
+ try
+ {
+ colorspace = PDColorSpaceFactory.createColorSpace( cs
);
+ }
+ catch (IOException exception)
+ {
+ LOG.error("error while creating a colorspace",
exception);
+ }
+ if (colorspace != null)
+ {
+ colorspaces.put( csName.getName(), colorspace );
+ }
+ }
}
}
- return retval;
+ return colorspaces;
}
/**
* This will set the map of colorspaces.
*
- * @param colorspaces The new map of colorspaces.
+ * @param csValue The new map of colorspaces.
*/
- public void setColorSpaces( Map<String,PDColorSpace> colorspaces )
+ public void setColorSpaces( Map<String,PDColorSpace> csValue )
{
- resources.setItem( COSName.COLORSPACE, COSDictionaryMap.convert(
colorspaces ) );
+ colorspaces = csValue;
+ resources.setItem( COSName.COLORSPACE, COSDictionaryMap.convert(
csValue ) );
}
/**
@@ -263,20 +351,20 @@ public class PDResources implements COSO
*/
public Map<String,PDExtendedGraphicsState> getGraphicsStates()
{
- Map<String,PDExtendedGraphicsState> retval = null;
- COSDictionary states = (COSDictionary)resources.getDictionaryObject(
COSName.EXT_G_STATE );
-
- if( states != null )
+ if (graphicsStates == null)
{
- Map<String,PDExtendedGraphicsState> actuals = new
HashMap<String,PDExtendedGraphicsState>();
- retval = new COSDictionaryMap( actuals, states );
- for( COSName name : states.keySet() )
+ COSDictionary states =
(COSDictionary)resources.getDictionaryObject( COSName.EXT_G_STATE );
+ if( states != null )
{
- COSDictionary dictionary =
(COSDictionary)states.getDictionaryObject( name );
- actuals.put( name.getName(), new PDExtendedGraphicsState(
dictionary ) );
+ graphicsStates = new HashMap<String,PDExtendedGraphicsState>();
+ for( COSName name : states.keySet() )
+ {
+ COSDictionary dictionary =
(COSDictionary)states.getDictionaryObject( name );
+ graphicsStates.put( name.getName(), new
PDExtendedGraphicsState( dictionary ) );
+ }
}
}
- return retval;
+ return graphicsStates;
}
/**
@@ -286,6 +374,7 @@ public class PDResources implements COSO
*/
public void setGraphicsStates( Map<String,PDExtendedGraphicsState> states )
{
+ graphicsStates = states;
Iterator<String> iter = states.keySet().iterator();
COSDictionary dic = new COSDictionary();
while( iter.hasNext() )
@@ -335,35 +424,36 @@ public class PDResources implements COSO
*/
public Map<String,PDPatternResources> getPatterns() throws IOException
{
- Map<String,PDPatternResources> retval = null;
- COSDictionary patterns = (COSDictionary)resources.getDictionaryObject(
COSName.PATTERN );
-
- if( patterns != null )
+ if (patterns == null)
{
- Map<String,PDPatternResources> actuals = new
HashMap<String,PDPatternResources>();
- retval = new COSDictionaryMap( actuals, patterns );
- for( COSName name : patterns.keySet() )
+ COSDictionary patternsDictionary =
(COSDictionary)resources.getDictionaryObject( COSName.PATTERN );
+ if( patternsDictionary != null )
{
- COSDictionary dictionary =
(COSDictionary)patterns.getDictionaryObject( name );
- actuals.put( name.getName(), PDPatternResources.create(
dictionary ) );
+ patterns = new HashMap<String,PDPatternResources>();
+ for( COSName name : patternsDictionary.keySet() )
+ {
+ COSDictionary dictionary =
(COSDictionary)patternsDictionary.getDictionaryObject( name );
+ patterns.put( name.getName(), PDPatternResources.create(
dictionary ) );
+ }
}
}
- return retval;
+ return patterns;
}
/**
* This will set the map of patterns.
*
- * @param patterns The new map of patterns.
+ * @param patternsValue The new map of patterns.
*/
- public void setPatterns( Map<String,PDPatternResources> patterns )
+ public void setPatterns( Map<String,PDPatternResources> patternsValue )
{
- Iterator<String> iter = patterns.keySet().iterator();
+ patterns = patternsValue;
+ Iterator<String> iter = patternsValue.keySet().iterator();
COSDictionary dic = new COSDictionary();
while( iter.hasNext() )
{
String name = iter.next();
- PDPatternResources pattern = patterns.get( name );
+ PDPatternResources pattern = patternsValue.get( name );
dic.setItem( COSName.getPDFName( name ), pattern.getCOSObject() );
}
resources.setItem( COSName.PATTERN, dic );
@@ -380,37 +470,113 @@ public class PDResources implements COSO
*/
public Map<String,PDShadingResources> getShadings() throws IOException
{
- Map<String,PDShadingResources> retval = null;
- COSDictionary shadings = (COSDictionary)resources.getDictionaryObject(
COSName.SHADING );
-
- if( shadings != null )
+ if (shadings == null)
{
- Map<String,PDShadingResources> actuals = new
HashMap<String,PDShadingResources>();
- retval = new COSDictionaryMap( actuals, shadings );
- for( COSName name : shadings.keySet() )
+ COSDictionary shadingsDictionary =
(COSDictionary)resources.getDictionaryObject( COSName.SHADING );
+ if( shadingsDictionary != null )
{
- COSDictionary dictionary =
(COSDictionary)shadings.getDictionaryObject( name );
- actuals.put( name.getName(), PDShadingResources.create(
dictionary ) );
+ shadings = new HashMap<String,PDShadingResources>();
+ for( COSName name : shadingsDictionary.keySet() )
+ {
+ COSDictionary dictionary =
(COSDictionary)shadingsDictionary.getDictionaryObject( name );
+ shadings.put( name.getName(), PDShadingResources.create(
dictionary ) );
+ }
}
}
- return retval;
+ return shadings;
}
/**
* This will set the map of shadings.
*
- * @param shadings The new map of shadings.
+ * @param shadingsValue The new map of shadings.
*/
- public void setShadings( Map<String,PDShadingResources> shadings )
+ public void setShadings( Map<String,PDShadingResources> shadingsValue )
{
- Iterator<String> iter = shadings.keySet().iterator();
+ shadings = shadingsValue;
+ Iterator<String> iter = shadingsValue.keySet().iterator();
COSDictionary dic = new COSDictionary();
while( iter.hasNext() )
{
String name = iter.next();
- PDShadingResources shading = shadings.get( name );
+ PDShadingResources shading = shadingsValue.get( name );
dic.setItem( COSName.getPDFName( name ), shading.getCOSObject() );
}
resources.setItem( COSName.SHADING, dic );
}
+
+ /**
+ * Adds the given font to the resources of the current the page.
+ *
+ * @param font the font to be added
+ * @return the font name to be used within the content stream.
+ */
+ public String addFont(PDFont font)
+ {
+ if (fonts == null)
+ {
+ fonts = new HashMap<String,PDFont>();
+ fontMappings = reverseMap(fonts, PDFont.class);
+ setFonts(fonts);
+ }
+ String fontMapping = fontMappings.get( font );
+ if( fontMapping == null )
+ {
+ fontMapping = MapUtil.getNextUniqueKey( fonts, "F" );
+ fontMappings.put( font, fontMapping );
+ fonts.put( fontMapping, font );
+ addFontToDictionary(font, fontMapping);
+ }
+ return fontMapping;
+ }
+
+ private void addFontToDictionary(PDFont font, String fontName)
+ {
+ COSDictionary fontsDictionary =
(COSDictionary)resources.getDictionaryObject(COSName.FONT);
+ fontsDictionary.setItem(fontName, font);
+ }
+ /**
+ * Adds the given XObject to the resources of the current the page.
+ *
+ * @param xobject the XObject to be added
+ * @param prefix the prefix to be used for the name
+ *
+ * @return the XObject name to be used within the content stream.
+ */
+ public String addXObject(PDXObject xobject, String prefix)
+ {
+ if (xobjects == null)
+ {
+ xobjects = new HashMap<String,PDXObject>();
+ xobjectMappings = reverseMap(xobjects, PDXObject.class);
+ setXObjects(xobjects);
+ }
+ String objMapping = xobjectMappings.get( xobject );
+ if( objMapping == null )
+ {
+ objMapping = MapUtil.getNextUniqueKey( xobjects, prefix );
+ xobjectMappings.put( xobject, objMapping );
+ xobjects.put( objMapping, xobject );
+ addXObjectToDictionary(xobject, objMapping);
+ }
+ return objMapping;
+ }
+
+ private void addXObjectToDictionary(PDXObject xobject, String xobjectName)
+ {
+ COSDictionary fontsDictionary =
(COSDictionary)resources.getDictionaryObject(COSName.XOBJECT);
+ fontsDictionary.setItem(xobjectName, xobject);
+ }
+
+ private <T> Map<T, String> reverseMap(Map<String, T> map, Class<T>
keyClass)
+ {
+ Map<T, String> reversed = new java.util.HashMap<T, String>();
+ for (Map.Entry<String, T> entry : map.entrySet())
+ {
+ reversed.put(keyClass.cast(entry.getValue()),
(String)entry.getKey());
+ }
+ return reversed;
+ }
+
+
}
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=1234506&r1=1234505&r2=1234506&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 Jan 22 13:13:39 2012
@@ -27,7 +27,6 @@ import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
-import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -51,11 +50,10 @@ import org.apache.pdfbox.pdmodel.graphic
import org.apache.pdfbox.pdmodel.graphics.color.PDSeparation;
import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObject;
import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage;
-import org.apache.pdfbox.util.MapUtil;
/**
- * This class will is a convenience for creating page content streams. You
MUST
+ * 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:[email protected]">Ben Litchfield</a>
@@ -71,11 +69,7 @@ public class PDPageContentStream
private PDPage page;
private OutputStream output;
private boolean inTextMode = false;
- private Map<PDFont,String> fontMappings;
- private Map<PDXObject,String> xobjectMappings;
private PDResources resources;
- private Map<String,PDFont> fonts;
- private Map<String,PDXObject> xobjects;
private PDColorSpace currentStrokingColorSpace = new PDDeviceGray();
private PDColorSpace currentNonStrokingColorSpace = new PDDeviceGray();
@@ -187,14 +181,6 @@ public class PDPageContentStream
page.setResources( resources );
}
- //Fonts including reverse lookup
- fonts = resources.getFonts();
- fontMappings = reverseMap(fonts, PDFont.class);
-
- //XObjects including reverse lookup
- xobjects = resources.getXObjects();
- xobjectMappings = reverseMap(xobjects, PDXObject.class);
-
// Get the pdstream from the source page instead of creating a new one
PDStream contents = sourcePage.getContents();
boolean hasContent = contents != null;
@@ -278,17 +264,6 @@ public class PDPageContentStream
formatDecimal.setGroupingUsed( false );
}
- private <T> Map<T, String> reverseMap(Map map, Class<T> keyClass)
- {
- Map<T, String> reversed = new java.util.HashMap<T, String>();
- for (Object o : map.entrySet())
- {
- Map.Entry entry = (Map.Entry)o;
- reversed.put(keyClass.cast(entry.getValue()),
(String)entry.getKey());
- }
- return reversed;
- }
-
/**
* Begin some text operations.
*
@@ -330,13 +305,7 @@ public class PDPageContentStream
*/
public void setFont( PDFont font, float fontSize ) throws IOException
{
- String fontMapping = fontMappings.get( font );
- if( fontMapping == null )
- {
- fontMapping = MapUtil.getNextUniqueKey( fonts, "F" );
- fontMappings.put( font, fontMapping );
- fonts.put( fontMapping, font );
- }
+ String fontMapping = resources.addFont(font);
appendRawCommands( "/");
appendRawCommands( fontMapping );
appendRawCommands( SPACE );
@@ -395,14 +364,7 @@ public class PDPageContentStream
{
xObjectPrefix = "Form";
}
-
- String objMapping = xobjectMappings.get( xobject );
- if( objMapping == null )
- {
- objMapping = MapUtil.getNextUniqueKey( xobjects, xObjectPrefix );
- xobjectMappings.put( xobject, objMapping );
- xobjects.put( objMapping, xobject );
- }
+ String objMapping = resources.addXObject(xobject, xObjectPrefix);
saveGraphicsState();
appendRawCommands( SPACE );
concatenate2CTM(transform);
@@ -1180,6 +1142,8 @@ public class PDPageContentStream
/**
* Fill the path.
*
+ * @param windingRule the winding rule to be used for filling
+ *
* @throws IOException If there is an error while filling the path.
*/
public void fill(int windingRule) throws IOException
@@ -1212,6 +1176,8 @@ public class PDPageContentStream
/**
* Clip path.
*
+ * @param windingRule the winding rule to be used for clipping
+ *
* @throws IOException If there is an error while clipping the path.
*/
public void clipPath(int windingRule) throws IOException
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontFactory.java
URL:
http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontFactory.java?rev=1234506&r1=1234505&r2=1234506&view=diff
==============================================================================
---
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontFactory.java
(original)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontFactory.java
Sun Jan 22 13:13:39 2012
@@ -42,7 +42,7 @@ public class PDFontFactory
/**
* Logger instance.
*/
- private static final Log log = LogFactory.getLog(PDFontFactory.class);
+ private static final Log LOG = LogFactory.getLog(PDFontFactory.class);
/**
* This will create the correct font based on information in the
dictionary.
@@ -54,33 +54,13 @@ public class PDFontFactory
* @return The corrent implementation for the font.
*
* @throws IOException If the dictionary is not valid.
+ *
+ * @deprecated due to some side effects font caching is no longer
supported,
+ * use {@link #createFont(COSDictionary)} instead
*/
public static PDFont createFont(COSDictionary dic, Map fontCache) throws
IOException
{
- PDFont retval = null;
- if (fontCache != null)
- {
- String fontKey = dic.getNameAsString(COSName.BASE_FONT) +
dic.getNameAsString(COSName.NAME)
- + dic.getNameAsString(COSName.SUBTYPE);
- if (dic.getItem(COSName.ENCODING) != null)
- {
- fontKey += dic.getItem(COSName.ENCODING).toString();
- }
- if (fontCache.containsKey(fontKey))
- {
- retval = (PDFont)fontCache.get(fontKey);
- }
- else
- {
- retval = PDFontFactory.createFont( dic );
- fontCache.put(fontKey, retval);
- }
- }
- else
- {
- retval = PDFontFactory.createFont( dic );
- }
- return retval;
+ return createFont(dic);
}
/**
@@ -133,8 +113,8 @@ public class PDFontFactory
}
else
{
- log.warn("Substituting TrueType for unknown font subtype=" +
dic.getDictionaryObject( COSName.SUBTYPE ).toString());
- //throw new IOException( "Unknown font subtype=" + subType );
+ LOG.warn("Substituting TrueType for unknown font subtype=" +
+ dic.getDictionaryObject( COSName.SUBTYPE ).toString());
retval = new PDTrueTypeFont( dic );
}
return retval;
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java
URL:
http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java?rev=1234506&r1=1234505&r2=1234506&view=diff
==============================================================================
---
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java
(original)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java
Sun Jan 22 13:13:39 2012
@@ -66,7 +66,7 @@ public class PDFStreamEngine
/**
* Log instance.
*/
- private static final Log log = LogFactory.getLog(PDFStreamEngine.class);
+ private static final Log LOG = LogFactory.getLog(PDFStreamEngine.class);
/**
* The PDF operators that are ignored by this engine.
@@ -83,12 +83,10 @@ public class PDFStreamEngine
private Map<String,OperatorProcessor> operators = new
HashMap<String,OperatorProcessor>();
- private Stack<StreamResources> streamResourcesStack = new
Stack<StreamResources>();
+ private Stack<PDResources> streamResourcesStack = new Stack<PDResources>();
private PDPage page;
- private Map<String,PDFont> documentFontCache = new
HashMap<String,PDFont>();
-
private int validCharCnt;
private int totalCharCnt;
@@ -98,22 +96,6 @@ public class PDFStreamEngine
private boolean forceParsing = false;
/**
- * This is a simple internal class used by the Stream engine to handle the
- * resources stack.
- */
- private static class StreamResources
- {
- private Map<String,PDFont> fonts;
- private Map<String,PDColorSpace> colorSpaces;
- private Map<String,PDXObject> xobjects;
- private Map<String,PDExtendedGraphicsState> graphicsStates;
- private PDResources resources;
-
- private StreamResources()
- {};
- }
-
- /**
* Constructor.
*/
public PDFStreamEngine()
@@ -170,12 +152,24 @@ public class PDFStreamEngine
totalCharCnt = 0;
}
- public boolean isForceParsing() {
+ /**
+ * Indicates if force parsing is activated.
+ *
+ * @return true if force parsing is active
+ */
+ public boolean isForceParsing()
+ {
return forceParsing;
}
- public void setForceParsing(boolean forceParsing) {
- this.forceParsing = forceParsing;
+ /**
+ * Enable/Disable force parsing.
+ *
+ * @param forceParsingValue true activates force parsing
+ */
+ public void setForceParsing(boolean forceParsingValue)
+ {
+ forceParsing = forceParsingValue;
}
/**
@@ -199,7 +193,6 @@ public class PDFStreamEngine
*/
public void resetEngine()
{
- documentFontCache.clear();
validCharCnt = 0;
totalCharCnt = 0;
}
@@ -221,7 +214,6 @@ public class PDFStreamEngine
textLineMatrix = null;
graphicsStack.clear();
streamResourcesStack.clear();
-
processSubStream( aPage, resources, cosStream );
}
@@ -234,50 +226,58 @@ public class PDFStreamEngine
*
* @throws IOException If there is an exception while processing the
stream.
*/
- public void processSubStream(
- PDPage aPage, PDResources resources, COSStream cosStream)
- throws IOException {
+ public void processSubStream(PDPage aPage, PDResources resources,
COSStream cosStream) throws IOException
+ {
page = aPage;
- if (resources != null) {
- StreamResources sr = new StreamResources();
- sr.fonts = resources.getFonts( documentFontCache );
- sr.colorSpaces = resources.getColorSpaces();
- sr.xobjects = resources.getXObjects();
- sr.graphicsStates = resources.getGraphicsStates();
- sr.resources = resources;
-
- streamResourcesStack.push(sr);
- try {
+ if (resources != null)
+ {
+ streamResourcesStack.push(resources);
+ try
+ {
processSubStream(cosStream);
- } finally {
- streamResourcesStack.pop();
}
- } else {
+ finally
+ {
+ streamResourcesStack.pop().clear();
+ }
+ }
+ else
+ {
processSubStream(cosStream);
}
}
- private void processSubStream(COSStream cosStream) throws IOException {
+ private void processSubStream(COSStream cosStream) throws IOException
+ {
List<COSBase> arguments = new ArrayList<COSBase>();
PDFStreamParser parser = new PDFStreamParser(cosStream, forceParsing);
- try {
+ try
+ {
Iterator<Object> iter = parser.getTokenIterator();
-
- while (iter.hasNext()) {
+ while (iter.hasNext())
+ {
Object next = iter.next();
- if (log.isDebugEnabled()) {
- log.debug("processing substream token: " + next);
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("processing substream token: " + next);
}
- if (next instanceof COSObject) {
+ if (next instanceof COSObject)
+ {
arguments.add(((COSObject) next).getObject());
- } else if (next instanceof PDFOperator) {
+ }
+ else if (next instanceof PDFOperator)
+ {
processOperator((PDFOperator) next, arguments);
arguments = new ArrayList<COSBase>();
- } else {
+ }
+ else
+ {
arguments.add((COSBase) next);
}
}
- } finally {
+ }
+ finally
+ {
parser.close();
}
}
@@ -358,7 +358,7 @@ public class PDFStreamEngine
}
catch (Throwable exception)
{
- log.warn( exception, exception);
+ LOG.warn( exception, exception);
}
if( spaceWidthText == 0 )
@@ -400,7 +400,8 @@ public class PDFStreamEngine
}
// the space width has to be transformed into display units
- float spaceWidthDisp = spaceWidthText * fontSizeText *
horizontalScalingText * textMatrix.getValue(0, 0) * ctm.getValue(0, 0);
+ float spaceWidthDisp = spaceWidthText * fontSizeText *
horizontalScalingText
+ * textMatrix.getValue(0, 0) *
ctm.getValue(0, 0);
//todo, handle horizontal displacement
// get the width and height of this character in text units
@@ -464,7 +465,8 @@ public class PDFStreamEngine
final float endYPosition = textMatrixEnd.getYPosition();
// add some spacing to the text matrix (see comment above)
- tx =
((characterHorizontalDisplacementText)*fontSizeText+characterSpacingText+spacingText)*horizontalScalingText;
+ tx =
((characterHorizontalDisplacementText)*fontSizeText+characterSpacingText+spacingText)
+ *horizontalScalingText;
td.setValue( 2, 0, tx );
textMatrix = td.multiply(textMatrix, textMatrix );
@@ -527,7 +529,7 @@ public class PDFStreamEngine
}
catch (IOException e)
{
- log.warn(e, e);
+ LOG.warn(e, e);
}
}
@@ -554,14 +556,14 @@ public class PDFStreamEngine
{
if (!unsupportedOperators.contains(operation))
{
- log.info("unsupported/disabled operation: " + operation);
+ LOG.info("unsupported/disabled operation: " + operation);
unsupportedOperators.add(operation);
}
}
}
catch (Exception e)
{
- log.warn(e, e);
+ LOG.warn(e, e);
}
}
@@ -570,7 +572,7 @@ public class PDFStreamEngine
*/
public Map<String,PDColorSpace> getColorSpaces()
{
- return streamResourcesStack.peek().colorSpaces;
+ return streamResourcesStack.peek().getColorSpaces();
}
/**
@@ -578,7 +580,7 @@ public class PDFStreamEngine
*/
public Map<String,PDXObject> getXObjects()
{
- return streamResourcesStack.peek().xobjects;
+ return streamResourcesStack.peek().getXObjects();
}
/**
@@ -586,21 +588,21 @@ public class PDFStreamEngine
*/
public void setColorSpaces(Map<String,PDColorSpace> value)
{
- streamResourcesStack.peek().colorSpaces = value;
+ streamResourcesStack.peek().setColorSpaces(value);
}
/**
* @return Returns the fonts.
*/
public Map<String,PDFont> getFonts()
{
- return streamResourcesStack.peek().fonts;
+ return streamResourcesStack.peek().getFonts();
}
/**
* @param value The fonts to set.
*/
public void setFonts(Map<String,PDFont> value)
{
- streamResourcesStack.peek().fonts = value;
+ streamResourcesStack.peek().setFonts(value);
}
/**
* @return Returns the graphicsStack.
@@ -635,14 +637,14 @@ public class PDFStreamEngine
*/
public Map<String,PDExtendedGraphicsState> getGraphicsStates()
{
- return streamResourcesStack.peek().graphicsStates;
+ return streamResourcesStack.peek().getGraphicsStates();
}
/**
* @param value The graphicsStates to set.
*/
public void setGraphicsStates(Map<String,PDExtendedGraphicsState> value)
{
- ((StreamResources) streamResourcesStack.peek()).graphicsStates = value;
+ streamResourcesStack.peek().setGraphicsStates(value);
}
/**
* @return Returns the textLineMatrix.
@@ -677,7 +679,7 @@ public class PDFStreamEngine
*/
public PDResources getResources()
{
- return streamResourcesStack.peek().resources;
+ return streamResourcesStack.peek();
}
/**