You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ja...@apache.org on 2014/08/28 22:55:22 UTC
svn commit: r1621203 - in /pdfbox/branches/no-awt:
fontbox/src/main/java/org/apache/fontbox/cff/
fontbox/src/main/java/org/apache/fontbox/ttf/
fontbox/src/main/java/org/apache/fontbox/type1/
fontbox/src/main/java/org/apache/fontbox/util/ pdfbox/src/mai...
Author: jahewson
Date: Thu Aug 28 20:55:21 2014
New Revision: 1621203
URL: http://svn.apache.org/r1621203
Log:
PDFBOX-2262: Refactor text positioning
Modified:
pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java
pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeFont.java
pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/ttf/Type1Equivalent.java
pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/type1/Type1Font.java
pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/util/BoundingBox.java
pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java
pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java
pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java
pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java
pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java
pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java
pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java
pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java
pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java
pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java
pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/Matrix.java
pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java
pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFTextStreamEngine.java
Modified: pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java?rev=1621203&r1=1621202&r2=1621203&view=diff
==============================================================================
--- pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java (original)
+++ pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java Thu Aug 28 20:55:21 2014
@@ -92,9 +92,7 @@ public abstract class CFFFont
public BoundingBox getFontBBox()
{
List<Number> numbers = (List<Number>)topDict.get("FontBBox");
- BoundingBox bbox = new BoundingBox(numbers.get(0).floatValue(), numbers.get(1).floatValue(),
- numbers.get(2).floatValue(), numbers.get(3).floatValue());
- return bbox;
+ return new BoundingBox(numbers);
}
/**
Modified: pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeFont.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeFont.java?rev=1621203&r1=1621202&r2=1621203&view=diff
==============================================================================
--- pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeFont.java (original)
+++ pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeFont.java Thu Aug 28 20:55:21 2014
@@ -25,6 +25,7 @@ import java.io.IOException;
import java.io.InputStream;
import org.apache.fontbox.encoding.Encoding;
+import org.apache.fontbox.util.BoundingBox;
/**
* A TrueType font file.
@@ -476,6 +477,17 @@ public class TrueTypeFont implements Typ
}
@Override
+ public BoundingBox getFontBBox() throws IOException
+ {
+ short xMin = getHeader().getXMin();
+ short xMax = getHeader().getXMax();
+ short yMin = getHeader().getYMin();
+ short yMax = getHeader().getYMax();
+ float scale = 1000f / getUnitsPerEm();
+ return new BoundingBox(xMin * scale, yMin * scale, xMax * scale, yMax * scale);
+ }
+
+ @Override
public String toString()
{
try
Modified: pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/ttf/Type1Equivalent.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/ttf/Type1Equivalent.java?rev=1621203&r1=1621202&r2=1621203&view=diff
==============================================================================
--- pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/ttf/Type1Equivalent.java (original)
+++ pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/ttf/Type1Equivalent.java Thu Aug 28 20:55:21 2014
@@ -1,8 +1,10 @@
package org.apache.fontbox.ttf;
import org.apache.fontbox.encoding.Encoding;
+import org.apache.fontbox.util.BoundingBox;
import java.awt.geom.GeneralPath;
+import java.awt.geom.Rectangle2D;
import java.io.IOException;
/**
@@ -43,5 +45,10 @@ public interface Type1Equivalent
/**
* Returns the PostScript Encoding vector for the font.
*/
- public Encoding getEncoding();
+ public Encoding getEncoding() throws IOException;
+
+ /**
+ * Returns the font's bounding box in PostScript units.
+ */
+ public abstract BoundingBox getFontBBox() throws IOException;
}
Modified: pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/type1/Type1Font.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/type1/Type1Font.java?rev=1621203&r1=1621202&r2=1621203&view=diff
==============================================================================
--- pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/type1/Type1Font.java (original)
+++ pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/type1/Type1Font.java Thu Aug 28 20:55:21 2014
@@ -22,6 +22,7 @@ import org.apache.fontbox.cff.Type1CharS
import org.apache.fontbox.encoding.Encoding;
import org.apache.fontbox.pfb.PfbParser;
import org.apache.fontbox.ttf.Type1Equivalent;
+import org.apache.fontbox.util.BoundingBox;
import java.awt.geom.GeneralPath;
import java.io.IOException;
@@ -233,9 +234,9 @@ public final class Type1Font implements
*
* @return the font bounding box
*/
- public List<Number> getFontBBox()
+ public BoundingBox getFontBBox()
{
- return Collections.unmodifiableList(fontBBox);
+ return new BoundingBox(fontBBox);
}
/**
Modified: pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/util/BoundingBox.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/util/BoundingBox.java?rev=1621203&r1=1621202&r2=1621203&view=diff
==============================================================================
--- pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/util/BoundingBox.java (original)
+++ pdfbox/branches/no-awt/fontbox/src/main/java/org/apache/fontbox/util/BoundingBox.java Thu Aug 28 20:55:21 2014
@@ -17,6 +17,8 @@
package org.apache.fontbox.util;
+import java.util.List;
+
/**
* This is an implementation of a bounding box. This was originally written for the
* AMF parser.
@@ -52,6 +54,20 @@ public class BoundingBox
upperRightX = maxX;
upperRightY = maxY;
}
+
+ /**
+ * Constructor.
+ *
+ * @param numbers list of four numbers
+ */
+ public BoundingBox(List<Number> numbers)
+ {
+ lowerLeftX = numbers.get(0).floatValue();
+ lowerLeftY = numbers.get(1).floatValue();
+ upperRightX = numbers.get(2).floatValue();
+ upperRightY = numbers.get(3).floatValue();
+ }
+
/**
* Getter for property lowerLeftX.
*
Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java?rev=1621203&r1=1621202&r2=1621203&view=diff
==============================================================================
--- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java (original)
+++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java Thu Aug 28 20:55:21 2014
@@ -20,6 +20,7 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
+import org.apache.fontbox.util.BoundingBox;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
@@ -148,6 +149,11 @@ public abstract class PDCIDFont implemen
}
/**
+ * Returns the font's bounding box.
+ */
+ public abstract BoundingBox getBoundingBox() throws IOException;
+
+ /**
* This will get the default width. The default value for the default width is 1000.
*
* @return The default width for the glyphs in this font.
Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java?rev=1621203&r1=1621202&r2=1621203&view=diff
==============================================================================
--- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java (original)
+++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java Thu Aug 28 20:55:21 2014
@@ -18,6 +18,7 @@ package org.apache.pdfbox.pdmodel.font;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
@@ -28,6 +29,7 @@ import org.apache.fontbox.cff.CFFFont;
import org.apache.fontbox.cff.CFFParser;
import org.apache.fontbox.cff.CFFType1Font;
import org.apache.fontbox.cff.Type2CharString;
+import org.apache.fontbox.util.BoundingBox;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.pdmodel.common.PDStream;
@@ -134,6 +136,18 @@ public class PDCIDFontType0 extends PDCI
return fontMatrix;
}
+ @Override
+ public BoundingBox getBoundingBox()
+ {
+ if (cidFont != null)
+ {
+ return cidFont.getFontBBox();
+ } else
+ {
+ return t1Font.getFontBBox();
+ }
+ }
+
/**
* Returns the embedded CFF CIDFont.
*/
Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java?rev=1621203&r1=1621202&r2=1621203&view=diff
==============================================================================
--- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java (original)
+++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java Thu Aug 28 20:55:21 2014
@@ -26,6 +26,7 @@ import org.apache.fontbox.ttf.CmapSubtab
import org.apache.fontbox.ttf.CmapTable;
import org.apache.fontbox.ttf.TTFParser;
import org.apache.fontbox.ttf.TrueTypeFont;
+import org.apache.fontbox.util.BoundingBox;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
@@ -121,6 +122,12 @@ public class PDCIDFontType2 extends PDCI
return fontMatrix;
}
+ @Override
+ public BoundingBox getBoundingBox() throws IOException
+ {
+ return ttf.getFontBBox();
+ }
+
private int[] readCIDToGIDMap()
{
int[] cid2gid = null;
Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java?rev=1621203&r1=1621202&r2=1621203&view=diff
==============================================================================
--- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java (original)
+++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java Thu Aug 28 20:55:21 2014
@@ -24,6 +24,7 @@ import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fontbox.cmap.CMap;
+import org.apache.fontbox.util.BoundingBox;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
@@ -33,7 +34,6 @@ import org.apache.pdfbox.cos.COSStream;
import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.pdmodel.common.COSArrayList;
import org.apache.pdfbox.pdmodel.common.COSObjectable;
-import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.util.Matrix;
/**
@@ -157,7 +157,7 @@ public abstract class PDFont implements
}
/**
- * Returns the width of the given character.
+ * Returns the width of the given character, in glyph space.
*
* @param code character code
*/
@@ -207,47 +207,12 @@ public abstract class PDFont implements
public abstract boolean isEmbedded();
/**
- * This will get the font height for a character.
+ * Returns the height of the given character, in glyph space. This can be expensive to
+ * calculate. Results are only approximate.
*
* @param code character code
- * @return The height is in 1000 unit of text space, ie 333 or 777
*/
- // todo: this is not the glyph height at all! this method is *supposed* to get the y-advance
- public float getHeight(int code) throws IOException
- {
- // maybe there is already a precalculated value
- PDFontDescriptor desc = getFontDescriptor();
- if (desc != null)
- {
- // the following values are all more or less accurate at least all are average
- // values. Maybe we'll find another way to get those value for every single glyph
- // in the future if needed
- PDRectangle fontBBox = desc.getFontBoundingBox();
- float retval = 0;
- if (fontBBox != null)
- {
- retval = fontBBox.getHeight() / 2;
- }
- if (retval == 0)
- {
- retval = desc.getCapHeight();
- }
- if (retval == 0)
- {
- retval = desc.getAscent();
- }
- if (retval == 0)
- {
- retval = desc.getXHeight();
- if (retval > 0)
- {
- retval -= desc.getDescent();
- }
- }
- return retval;
- }
- return 0;
- }
+ public abstract float getHeight(int code) throws IOException;
/**
* Returns the width of the given Unicode string.
@@ -430,6 +395,11 @@ public abstract class PDFont implements
}
/**
+ * Returns the font's bounding box.
+ */
+ public abstract BoundingBox getBoundingBox() throws IOException;
+
+ /**
* The widths of the characters. This will be null for the standard 14 fonts.
*
* @return The widths of the characters.
Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java?rev=1621203&r1=1621202&r2=1621203&view=diff
==============================================================================
--- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java (original)
+++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java Thu Aug 28 20:55:21 2014
@@ -27,8 +27,10 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fontbox.ttf.CmapSubtable;
import org.apache.fontbox.ttf.CmapTable;
+import org.apache.fontbox.ttf.GlyphData;
import org.apache.fontbox.ttf.TTFParser;
import org.apache.fontbox.ttf.TrueTypeFont;
+import org.apache.fontbox.util.BoundingBox;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.encoding.Encoding;
import org.apache.pdfbox.encoding.GlyphList;
@@ -136,6 +138,7 @@ public class PDTrueTypeFont extends PDSi
@Override
protected Encoding readEncodingFromFont() throws IOException
{
+ // TTF fonts don't have PostScript Encoding vectors
return null;
}
@@ -156,6 +159,12 @@ public class PDTrueTypeFont extends PDSi
return in.read();
}
+ @Override
+ public BoundingBox getBoundingBox() throws IOException
+ {
+ return ttf.getFontBBox();
+ }
+
/**
* Returns the embedded or substituted TrueType font.
*/
@@ -178,6 +187,18 @@ public class PDTrueTypeFont extends PDSi
}
@Override
+ public float getHeight(int code) throws IOException
+ {
+ int gid = codeToGID(code);
+ GlyphData glyph = ttf.getGlyph().getGlyphs()[gid];
+ if (glyph != null)
+ {
+ return glyph.getBoundingBox().getHeight();
+ }
+ return 0;
+ }
+
+ @Override
public boolean isEmbedded()
{
return isEmbedded;
Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java?rev=1621203&r1=1621202&r2=1621203&view=diff
==============================================================================
--- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java (original)
+++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java Thu Aug 28 20:55:21 2014
@@ -22,6 +22,7 @@ import java.io.InputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fontbox.cmap.CMap;
+import org.apache.fontbox.util.BoundingBox;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
@@ -226,6 +227,12 @@ public class PDType0Font extends PDFont
}
@Override
+ public BoundingBox getBoundingBox() throws IOException
+ {
+ return descendantFont.getBoundingBox();
+ }
+
+ @Override
public int readCode(InputStream in) throws IOException
{
return cMap.readCode(in);
Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java?rev=1621203&r1=1621202&r2=1621203&view=diff
==============================================================================
--- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java (original)
+++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java Thu Aug 28 20:55:21 2014
@@ -31,6 +31,7 @@ import org.apache.commons.logging.LogFac
import org.apache.fontbox.cff.CFFParser;
import org.apache.fontbox.cff.CFFType1Font;
import org.apache.fontbox.ttf.Type1Equivalent;
+import org.apache.fontbox.util.BoundingBox;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.encoding.Encoding;
import org.apache.pdfbox.encoding.GlyphList;
@@ -131,6 +132,12 @@ public class PDType1CFont extends PDSimp
}
@Override
+ public BoundingBox getBoundingBox() throws IOException
+ {
+ return type1Equivalent.getFontBBox();
+ }
+
+ @Override
public boolean hasGlyph(String name) throws IOException
{
return type1Equivalent.hasGlyph(name);
Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java?rev=1621203&r1=1621202&r2=1621203&view=diff
==============================================================================
--- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java (original)
+++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java Thu Aug 28 20:55:21 2014
@@ -29,6 +29,7 @@ import org.apache.fontbox.afm.AFMParser;
import org.apache.fontbox.afm.FontMetrics;
import org.apache.fontbox.ttf.Type1Equivalent;
import org.apache.fontbox.type1.Type1Font;
+import org.apache.fontbox.util.BoundingBox;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSStream;
@@ -272,12 +273,15 @@ public class PDType1Font extends PDSimpl
@Override
public float getHeight(int code) throws IOException
{
+ String name = getEncoding().getName(code);
if (afm != null)
{
- String characterName = getEncoding().getName(code);
- return afm.getCharacterHeight(characterName); // todo: isn't this the y-advance, not the height?
+ return afm.getCharacterHeight(name); // todo: isn't this the y-advance, not the height?
+ }
+ else
+ {
+ return (float)type1Equivalent.getPath(name).getBounds().getHeight();
}
- return super.getHeight(code);
}
@Override
@@ -367,6 +371,12 @@ public class PDType1Font extends PDSimpl
}
@Override
+ public BoundingBox getBoundingBox() throws IOException
+ {
+ return type1Equivalent.getFontBBox();
+ }
+
+ @Override
public boolean hasGlyph(String name) throws IOException
{
return type1Equivalent.hasGlyph(name);
Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java?rev=1621203&r1=1621202&r2=1621203&view=diff
==============================================================================
--- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java (original)
+++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java Thu Aug 28 20:55:21 2014
@@ -21,6 +21,7 @@ import java.io.InputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.fontbox.util.BoundingBox;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
@@ -111,6 +112,42 @@ public class PDType3Font extends PDSimpl
}
@Override
+ public float getHeight(int code) throws IOException
+ {
+ PDFontDescriptor desc = getFontDescriptor();
+ if (desc != null)
+ {
+ // the following values are all more or less accurate at least all are average
+ // values. Maybe we'll find another way to get those value for every single glyph
+ // in the future if needed
+ PDRectangle fontBBox = desc.getFontBoundingBox();
+ float retval = 0;
+ if (fontBBox != null)
+ {
+ retval = fontBBox.getHeight() / 2;
+ }
+ if (retval == 0)
+ {
+ retval = desc.getCapHeight();
+ }
+ if (retval == 0)
+ {
+ retval = desc.getAscent();
+ }
+ if (retval == 0)
+ {
+ retval = desc.getXHeight();
+ if (retval > 0)
+ {
+ retval -= desc.getDescent();
+ }
+ }
+ return retval;
+ }
+ return 0;
+ }
+
+ @Override
public int readCode(InputStream in) throws IOException
{
return in.read();
@@ -156,9 +193,8 @@ public class PDType3Font extends PDSimpl
* This will get the fonts bounding box.
*
* @return The fonts bounding box.
- * @throws IOException If there is an error getting the bounding box.
*/
- public PDRectangle getBoundingBox() throws IOException
+ public PDRectangle getFontBBox()
{
COSArray rect = (COSArray) dict.getDictionaryObject(COSName.FONT_BBOX);
PDRectangle retval = null;
@@ -168,6 +204,14 @@ public class PDType3Font extends PDSimpl
}
return retval;
}
+
+ @Override
+ public BoundingBox getBoundingBox()
+ {
+ PDRectangle rect = getFontBBox();
+ return new BoundingBox(rect.getLowerLeftX(), rect.getLowerLeftY(),
+ rect.getWidth(), rect.getHeight());
+ }
/**
* Returns the dictionary containing all streams to be used to render the glyphs.
Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java?rev=1621203&r1=1621202&r2=1621203&view=diff
==============================================================================
--- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java (original)
+++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java Thu Aug 28 20:55:21 2014
@@ -271,13 +271,12 @@ public class PageDrawer extends PDFGraph
}
@Override
- protected void processGlyph(Matrix textMatrix, Point2D.Float end, float maxHeight,
- float widthText, int code, String unicode, PDFont font,
- float fontSize) throws IOException
+ protected void processGlyph(Matrix textRenderingMatrix, float dx, float dy, int code,
+ String unicode, PDFont font) throws IOException
{
try
{
- AffineTransform at = textMatrix.createAffineTransform();
+ AffineTransform at = textRenderingMatrix.createAffineTransform();
Matrix fontMatrix = font.getFontMatrix();
// use different methods to draw the string
Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/Matrix.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/Matrix.java?rev=1621203&r1=1621202&r2=1621203&view=diff
==============================================================================
--- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/Matrix.java (original)
+++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/Matrix.java Thu Aug 28 20:55:21 2014
@@ -21,6 +21,7 @@ import org.apache.pdfbox.cos.COSFloat;
import org.apache.pdfbox.cos.COSNumber;
import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
/**
* This class will be used for matrix manipulation.
@@ -74,6 +75,7 @@ public class Matrix implements Cloneable
single[4] = d;
single[6] = e;
single[7] = f;
+ single[8] = 1;
}
/**
@@ -180,6 +182,16 @@ public class Matrix implements Cloneable
}
/**
+ * Concatenates (premultiplies) the given matrix to this matrix.
+ *
+ * @param matrix The matrix to concatenate.
+ */
+ public void concatenate(Matrix matrix)
+ {
+ matrix.multiply(this, this);
+ }
+
+ /**
* This will take the current matrix and multipy it with a matrix that is passed in.
*
* @param b The matrix to multiply by.
@@ -273,6 +285,39 @@ public class Matrix implements Cloneable
}
/**
+ * Transforms the given point by this matrix.
+ *
+ * @param point point to transform
+ */
+ public void transform(Point2D point) {
+ double x = point.getX();
+ double y = point.getY();
+ double a = single[0];
+ double b = single[1];
+ double c = single[3];
+ double d = single[4];
+ double e = single[6];
+ double f = single[7];
+ point.setLocation(x * a + y * c + e, x * b + y * d + f);
+ }
+
+ /**
+ * Transforms the given point by this matrix.
+ *
+ * @param x x-coordinate
+ * @param y y-coordinate
+ */
+ public Point2D transform(double x, double y) {
+ double a = single[0];
+ double b = single[1];
+ double c = single[3];
+ double d = single[4];
+ double e = single[6];
+ double f = single[7];
+ return new Point2D.Double(x * a + y * c + e, x * b + y * d + f);
+ }
+
+ /**
* Create a new matrix with just the scaling operators.
*
* @return A new matrix with just the scaling operators.
@@ -337,6 +382,19 @@ public class Matrix implements Cloneable
}
/**
+ * Produces a copy of the first matrix, with the second matrix concatenated.
+ *
+ * @param a The matrix to copy.
+ * @param b The matrix to concatenate.
+ */
+ public static Matrix concatenate(Matrix a, Matrix b)
+ {
+ Matrix copy = a.clone();
+ copy.concatenate(b);
+ return copy;
+ }
+
+ /**
* Clones this object.
* @return cloned matrix as an object.
*/
Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java?rev=1621203&r1=1621202&r2=1621203&view=diff
==============================================================================
--- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java (original)
+++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java Thu Aug 28 20:55:21 2014
@@ -16,6 +16,7 @@
*/
package org.apache.pdfbox.util;
+import java.awt.Point;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.io.ByteArrayInputStream;
@@ -48,6 +49,7 @@ import org.apache.pdfbox.pdmodel.graphic
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.pdmodel.graphics.state.PDGraphicsState;
import org.apache.pdfbox.pdmodel.graphics.PDXObject;
+import org.apache.pdfbox.pdmodel.graphics.state.PDTextState;
import org.apache.pdfbox.util.operator.Operator;
import org.apache.pdfbox.util.operator.OperatorProcessor;
@@ -358,123 +360,78 @@ public class PDFStreamEngine
*/
protected void processText(byte[] string) throws IOException
{
- // Note on variable names: there are three different units being used in this code.
- // Character sizes are given in glyph units, text locations are initially given in text
- // units, and we want to save the data in display units. The variable names should end with
- // Text or Disp to represent if the values are in text or disp units (no glyph units are
- // saved).
-
PDGraphicsState state = getGraphicsState();
-
- final float fontSizeText = state.getTextState().getFontSize();
- final float horizontalScalingText = state.getTextState().getHorizontalScaling() / 100f;
- final float riseText = state.getTextState().getRise();
- final float wordSpacingText = state.getTextState().getWordSpacing();
- final float characterSpacingText = state.getTextState().getCharacterSpacing();
+ PDTextState textState = state.getTextState();
// get the current font
- PDFont font = state.getTextState().getFont();
+ PDFont font = textState.getFont();
if (font == null)
{
LOG.warn("No current font, will use default");
font = PDFontFactory.createDefaultFont();
}
- // all fonts have the width/height of a character in thousandths of a unit of text space
- float fontMatrixXScaling = 1 / 1000f;
- float fontMatrixYScaling = 1 / 1000f;
-
- // except Type 3 fonts, those provide the width of a character in glyph space units
- if (font instanceof PDType3Font)
- {
- Matrix fontMatrix = font.getFontMatrix();
- fontMatrixXScaling = fontMatrix.getValue(0, 0);
- fontMatrixYScaling = fontMatrix.getValue(1, 1);
- }
-
- Matrix textStateParameters = new Matrix();
- textStateParameters.setValue(0, 0, fontSizeText * horizontalScalingText);
- textStateParameters.setValue(1, 1, fontSizeText);
- textStateParameters.setValue(2, 1, riseText);
-
- Matrix ctm = state.getCurrentTransformationMatrix();
- Matrix textXctm = new Matrix();
- Matrix textMatrixEnd = new Matrix();
- Matrix td = new Matrix();
- Matrix tempMatrix = new Matrix();
+ float fontSize = textState.getFontSize();
+ float horizontalScaling = textState.getHorizontalScaling() / 100f;
+ float characterSpacing = textState.getCharacterSpacing();
+
+ // put the text state parameters into matrix form
+ Matrix parameters = new Matrix(
+ fontSize * horizontalScaling, 0, // 0
+ 0, fontSize, // 0
+ 0, textState.getRise()); // 1
+ // read the stream until it is empty
InputStream in = new ByteArrayInputStream(string);
while (in.available() > 0)
{
+ // decode a character
int before = in.available();
int code = font.readCode(in);
int codeLength = before - in.available();
String unicode = font.toUnicode(code);
- // TODO: handle horizontal displacement
- // get the width and height of this character in text units
- float charHorizontalDisplacementText = font.getWidth(code);
- float charVerticalDisplacementText = font.getHeight(code); // todo: NOPE we want y-advance not BBox
-
- // multiply the width/height with the scaling factor
- charHorizontalDisplacementText = charHorizontalDisplacementText * fontMatrixXScaling;
- charVerticalDisplacementText = charVerticalDisplacementText * fontMatrixYScaling;
-
// Word spacing shall be applied to every occurrence of the single-byte character code
// 32 in a string when using a simple font or a composite font that defines code 32 as
// a single-byte code.
- float spacingText = 0;
+ float wordSpacing = 0;
if (codeLength == 1)
{
if (code == 32)
{
- spacingText += wordSpacingText;
+ wordSpacing += textState.getWordSpacing();
}
}
- textMatrix.multiply(ctm, textXctm);
- // Convert textMatrix to display units
- // We need to instantiate a new Matrix instance here as it is passed to the TextPosition
- // constructor below
- Matrix textMatrixStart = textStateParameters.multiply(textXctm);
-
- // TODO: tx should be set for horizontal text and ty for vertical text
- // which seems to be specified in the font (not the direction in the matrix).
- float tx = charHorizontalDisplacementText * fontSizeText * horizontalScalingText;
- float ty = 0;
- // reset the matrix instead of creating a new one
- td.reset();
- td.setValue(2, 0, tx);
- td.setValue(2, 1, ty);
-
- // The text matrix gets updated after each glyph is placed. The updated
- // version will have the X and Y coordinates for the next glyph.
- // textMatrixEnd contains the coordinates of the end of the last glyph without
- // taking characterSpacingText and spacintText into account, otherwise it'll be
- // impossible to detect new words within text extraction
- textStateParameters.multiply(td, tempMatrix);
- tempMatrix.multiply(textXctm, textMatrixEnd);
- final float endXPosition = textMatrixEnd.getXPosition();
- final float endYPosition = textMatrixEnd.getYPosition();
-
- // add some spacing to the text matrix (see comment above)
- tx = (charHorizontalDisplacementText * fontSizeText + characterSpacingText +
- spacingText) * horizontalScalingText;
- td.setValue(2, 0, tx);
- td.multiply(textMatrix, textMatrix);
-
- // determine the width of this character
- // TODO: Note that if we handled vertical text, we should be using Y here
- float startXPosition = textMatrixStart.getXPosition();
- float widthText = endXPosition - startXPosition;
+ // get glyph's horizontal and vertical displacements (glyph space -> text space)
+ float w0, w1;
+ if (font instanceof PDType3Font)
+ {
+ // Type 3 fonts specify a custom matrix
+ Point2D adv = font.getFontMatrix().transform(font.getWidth(code), font.getHeight(code));
+ w0 = (float)adv.getX();
+ w1 = (float)adv.getY();
+ }
+ else
+ {
+ // all other fonts use 1:1000 for widths, even those with a FontMatrix, see FOP-2252
+ w0 = font.getWidth(code) / 1000f;
+ w1 = 0; // todo: support vertical writing mode
+ }
- float totalVerticalDisplacementDisp = charVerticalDisplacementText * fontSizeText *
- textXctm.getYScale();
+ // text rendering matrix (text space -> device space)
+ Matrix ctm = state.getCurrentTransformationMatrix();
+ Matrix textRenderingMatrix = parameters.multiply(textMatrix).multiply(ctm);
// process the decoded glyph
- processGlyph(textMatrixStart, new Point2D.Float(endXPosition, endYPosition),
- totalVerticalDisplacementDisp, widthText, code, unicode,
- font, fontSizeText);
+ processGlyph(textRenderingMatrix, w0, w1, code, unicode, font);
+
+ // calculate the combined displacements
+ float tx = (w0 * fontSize + characterSpacing + wordSpacing) * horizontalScaling;
+ float ty = 0; // todo: support vertical writing mode
+
+ // update the text matrix
+ textMatrix.concatenate(Matrix.getTranslatingInstance(tx, ty));
}
}
@@ -482,19 +439,16 @@ public class PDFStreamEngine
* Called when a glyph is to be processed.This method is intended for overriding in subclasses,
* the default implementation does nothing.
*
- * @param textMatrix the text matrix at the start of the glyph
- * @param end the end position of the glyph in text space
- * @param maxHeight the height of the glyph in device space
- * @param widthText the width of the glyph in text space
- * @param unicode the Unicode text for this glyph, or null. May be meaningless.
+ * @param textRenderingMatrix the current text rendering matrix, T<sub>rm</sub>
+ * @param dx the x-advance of the glyph in text space
+ * @param dy the y-advance of the glyph in text space
* @param code internal PDF character code for the glyph
+ * @param unicode the Unicode text for this glyph, or null if the PDF does provide it
* @param font the current font
- * @param fontSize font size in text space
* @throws IOException if the glyph cannot be processed
*/
- protected void processGlyph(Matrix textMatrix, Point2D.Float end, float maxHeight,
- float widthText, int code, String unicode, PDFont font,
- float fontSize) throws IOException
+ protected void processGlyph(Matrix textRenderingMatrix, float dx, float dy, int code,
+ String unicode, PDFont font) throws IOException
{
// overridden in subclasses
}
Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFTextStreamEngine.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFTextStreamEngine.java?rev=1621203&r1=1621202&r2=1621203&view=diff
==============================================================================
--- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFTextStreamEngine.java (original)
+++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFTextStreamEngine.java Thu Aug 28 20:55:21 2014
@@ -24,6 +24,7 @@ import org.apache.pdfbox.pdmodel.common.
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDSimpleFont;
import org.apache.pdfbox.pdmodel.font.PDType3Font;
+import org.apache.pdfbox.pdmodel.graphics.state.PDGraphicsState;
import org.apache.pdfbox.text.TextPosition;
import java.awt.geom.Point2D;
@@ -81,10 +82,46 @@ public class PDFTextStreamEngine extends
* This method was originally written by Ben Litchfield for PDFStreamEngine.
*/
@Override
- protected final void processGlyph(Matrix textMatrix, Point2D.Float end, float maxHeight,
- float widthText, int code, String unicode, PDFont font,
- float fontSize) throws IOException
+ protected void processGlyph(Matrix textRenderingMatrix, float dx, float dy, int code,
+ String unicode, PDFont font) throws IOException
{
+ //
+ // legacy calculations which were previously in PDFStreamEngine
+ //
+
+ PDGraphicsState state = getGraphicsState();
+ Matrix ctm = state.getCurrentTransformationMatrix();
+ float fontSize = state.getTextState().getFontSize();
+ float horizontalScaling = state.getTextState().getHorizontalScaling() / 100f;
+ Matrix textMatrix = getTextMatrix();
+
+ // 1/2 the bbox is used as the height todo: why?
+ float glyphHeight = font.getBoundingBox().getHeight() / 2;
+
+ // transform from glyph space -> text space
+ float height = (float)font.getFontMatrix().transform(0, glyphHeight).getY();
+
+ // (modified) combined displacement, this is calculated *without* taking the character
+ // spacing and word spacing into account, due to legacy code in TextStripper
+ float tx = dx * fontSize * horizontalScaling;
+ float ty = 0; // todo: support vertical writing mode
+
+ // (modified) combined displacement matrix
+ Matrix td = Matrix.getTranslatingInstance(tx, ty);
+
+ // (modified) text rendering matrix
+ Matrix nextTextRenderingMatrix = td.multiply(textMatrix).multiply(ctm); // text space -> device space
+ float nextX = nextTextRenderingMatrix.getXPosition();
+ float nextY = nextTextRenderingMatrix.getYPosition();
+
+ // (modified) width and height calculations
+ float dxDisplay = nextX - textRenderingMatrix.getXPosition();
+ float dyDisplay = height * textRenderingMatrix.getYScale();
+
+ //
+ // start of the original method
+ //
+
// Note on variable names. There are three different units being used in this code.
// Character sizes are given in glyph units, text locations are initially given in text
// units, and we want to save the data in display units. The variable names should end with
@@ -93,7 +130,7 @@ public class PDFTextStreamEngine extends
float fontSizeText = getGraphicsState().getTextState().getFontSize();
float horizontalScalingText = getGraphicsState().getTextState().getHorizontalScaling()/100f;
- Matrix ctm = getGraphicsState().getCurrentTransformationMatrix();
+ //Matrix ctm = getGraphicsState().getCurrentTransformationMatrix();
float glyphSpaceToTextSpaceFactor = 1 / 1000f;
if (font instanceof PDType3Font)
@@ -126,8 +163,8 @@ public class PDFTextStreamEngine extends
}
// the space width has to be transformed into display units
- float spaceWidthDisp = spaceWidthText * fontSizeText * horizontalScalingText *
- textMatrix.getXScale() * ctm.getXScale();
+ float spaceWidthDisplay = spaceWidthText * fontSizeText * horizontalScalingText *
+ textRenderingMatrix.getXScale() * ctm.getXScale();
// when there is no Unicode mapping available, Acrobat simply coerces the character code
// into Unicode, so we do the same. Subclasses of PDFStreamEngine don't necessarily want
@@ -148,9 +185,10 @@ public class PDFTextStreamEngine extends
}
processTextPosition(new TextPosition(pageRotation, pageSize.getWidth(),
- pageSize.getHeight(), textMatrix, end.x, end.y, maxHeight, widthText,
- spaceWidthDisp, unicode, new int[] { code } , font, fontSize,
- (int)(fontSize * textMatrix.getXScale())));
+ pageSize.getHeight(), textRenderingMatrix, nextX, nextY,
+ dyDisplay, dxDisplay,
+ spaceWidthDisplay, unicode, new int[] { code } , font, fontSize,
+ (int)(fontSize * textRenderingMatrix.getXScale())));
}
/**