Author: jahewson Date: Thu Sep 25 03:35:24 2014 New Revision: 1627450 URL: http://svn.apache.org/r1627450 Log: PDFBOX-2372: Refactor Standard 14 font and AFM handling
Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/Standard14Fonts.java Removed: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontDescriptorAFM.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontDescriptorDictionary.java Modified: pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/pdmodel/ExtractTTFFonts.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/ExternalFonts.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontDescriptor.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDSimpleFont.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFontEmbedder.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1FontEmbedder.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/font/TTFGlyph2D.java pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/CIDType0DescriptorHelper.java pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/CIDType2DescriptorHelper.java pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/FontDescriptorHelper.java pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/TrueTypeDescriptorHelper.java pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/Type1DescriptorHelper.java pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/TextToPDF.java Modified: pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/pdmodel/ExtractTTFFonts.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/pdmodel/ExtractTTFFonts.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/pdmodel/ExtractTTFFonts.java (original) +++ pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/pdmodel/ExtractTTFFonts.java Thu Sep 25 03:35:24 2014 @@ -32,7 +32,6 @@ import org.apache.pdfbox.pdmodel.font.PD import org.apache.pdfbox.pdmodel.font.PDCIDFontType2; import org.apache.pdfbox.pdmodel.font.PDFont; import org.apache.pdfbox.pdmodel.font.PDFontDescriptor; -import org.apache.pdfbox.pdmodel.font.PDFontDescriptorDictionary; import org.apache.pdfbox.pdmodel.font.PDTrueTypeFont; import org.apache.pdfbox.pdmodel.font.PDType0Font; import org.apache.pdfbox.pdmodel.graphics.PDXObject; @@ -221,10 +220,9 @@ public class ExtractTTFFonts private void writeFont(PDFontDescriptor fd, String name) throws IOException { - PDFontDescriptorDictionary fdd = (PDFontDescriptorDictionary) fd; if (fd != null) { - PDStream ff2Stream = fdd.getFontFile2(); + PDStream ff2Stream = fd.getFontFile2(); if (ff2Stream != null) { System.out.println("Writing font:" + name); Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/ExternalFonts.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/ExternalFonts.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/ExternalFonts.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/ExternalFonts.java Thu Sep 25 03:35:24 2014 @@ -163,26 +163,16 @@ public final class ExternalFonts substitutes.put("$Adobe-Korea1", Arrays.asList("AdobeGothicStd-Bold")); substitutes.put("$Adobe-GB1", Arrays.asList("AdobeHeitiStd-Regular")); - // the Adobe Supplement to the ISO 32000 specifies some alternative names for some - // of the standard 14 fonts, so we map these to our fallbacks above - substitutes.put("CourierCourierNew", copySubstitutes("Courier")); - substitutes.put("CourierNew", copySubstitutes("Courier")); - substitutes.put("CourierNew,Italic", copySubstitutes("Courier-Oblique")); - substitutes.put("CourierNew,Bold", copySubstitutes("Courier-Bold")); - substitutes.put("CourierNew,BoldItalic", copySubstitutes("Courier-BoldOblique")); - substitutes.put("Arial", copySubstitutes("Helvetica")); - substitutes.put("Arial,Italic", copySubstitutes("Helvetica-Oblique")); - substitutes.put("Arial,Bold", copySubstitutes("Helvetica-Bold")); - substitutes.put("Arial,BoldItalic", copySubstitutes("Helvetica-BoldOblique")); - substitutes.put("TimesNewRoman", copySubstitutes("Times-Roman")); - substitutes.put("TimesNewRoman,Italic", copySubstitutes("Times-Italic")); - substitutes.put("TimesNewRoman,Bold", copySubstitutes("Times-Bold")); - substitutes.put("TimesNewRoman,BoldItalic", copySubstitutes("Times-BoldItalic")); - - // Acrobat treats these fonts as "standard 14" too (at least Acrobat preflight says so) - substitutes.put("Symbol,Italic", copySubstitutes("Symbol")); - substitutes.put("Symbol,Bold", copySubstitutes("Symbol")); - substitutes.put("Symbol,BoldItalic", copySubstitutes("Symbol")); + // Acrobat also uses alternative names for Standard 14 fonts, which we map to those above + // these include names such as "Arial" and "TimesNewRoman" + for (String baseName : Standard14Fonts.getNames()) + { + if (!substitutes.containsKey(baseName)) + { + String mappedName = Standard14Fonts.getMappedFontName(baseName); + substitutes.put(baseName, copySubstitutes(mappedName)); + } + } } /** Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java Thu Sep 25 03:35:24 2014 @@ -188,7 +188,7 @@ public abstract class PDCIDFont implemen COSDictionary fd = (COSDictionary) dict.getDictionaryObject(COSName.FONT_DESC); if (fd != null) { - fontDescriptor = new PDFontDescriptorDictionary(fd); + fontDescriptor = new PDFontDescriptor(fd); } } return fontDescriptor; Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java Thu Sep 25 03:35:24 2014 @@ -68,9 +68,9 @@ public class PDCIDFontType0 extends PDCI PDFontDescriptor fd = getFontDescriptor(); byte[] bytes = null; - if (fd != null && fd instanceof PDFontDescriptorDictionary) // <-- todo: must be true + if (fd != null) { - PDStream ff3Stream = ((PDFontDescriptorDictionary) fd).getFontFile3(); + PDStream ff3Stream = fd.getFontFile3(); if (ff3Stream != null) { bytes = IOUtils.toByteArray(ff3Stream.createInputStream()); Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java Thu Sep 25 03:35:24 2014 @@ -63,7 +63,7 @@ public class PDCIDFontType2 extends PDCI { super(fontDictionary, parent); - PDFontDescriptorDictionary fd = (PDFontDescriptorDictionary) getFontDescriptor(); + PDFontDescriptor fd = getFontDescriptor(); PDStream ff2Stream = fd.getFontFile2(); PDStream ff3Stream = fd.getFontFile3(); Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java Thu Sep 25 03:35:24 2014 @@ -23,6 +23,7 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.fontbox.afm.FontMetrics; import org.apache.fontbox.cmap.CMap; import org.apache.fontbox.util.BoundingBox; import org.apache.pdfbox.cos.COSArray; @@ -49,7 +50,8 @@ public abstract class PDFont implements protected final COSDictionary dict; private final CMap toUnicodeCMap; - private PDFontDescriptor fontDescriptor; + private final FontMetrics afmStandard14; // AFM for standard 14 fonts + private final PDFontDescriptor fontDescriptor; private List<Integer> widths; private float avgFontWidth; @@ -64,6 +66,23 @@ public abstract class PDFont implements dict = new COSDictionary(); dict.setItem(COSName.TYPE, COSName.FONT); toUnicodeCMap = null; + fontDescriptor = null; + afmStandard14 = null; + } + + /** + * Constructor for Standard 14. + */ + protected PDFont(String baseFont) + { + dict = new COSDictionary(); + toUnicodeCMap = null; + fontDescriptor = null; + afmStandard14 = Standard14Fonts.getAFM(getName()); // may be null (it usually is) + if (afmStandard14 == null) + { + throw new IllegalArgumentException("No AFM for font " + baseFont); + } } /** @@ -75,11 +94,23 @@ public abstract class PDFont implements { dict = fontDictionary; + // standard 14 fonts use an AFM + afmStandard14 = Standard14Fonts.getAFM(getName()); // may be null (it usually is) + if (afmStandard14 != null) + { + isSymbolic = afmStandard14.getEncodingScheme().equals("FontSpecific"); + } + // font descriptor COSDictionary fd = (COSDictionary) dict.getDictionaryObject(COSName.FONT_DESC); if (fd != null) { - fontDescriptor = new PDFontDescriptorDictionary(fd); + fontDescriptor = new PDFontDescriptor(fd); + } + else if (afmStandard14 != null) + { + // build font descriptor from the AFM + fontDescriptor = PDType1FontEmbedder.buildFontDescriptor(afmStandard14); } else { @@ -102,18 +133,18 @@ public abstract class PDFont implements } } - @Override - public PDFontDescriptor getFontDescriptor() + /** + * Returns the AFM if this is a Standard 14 font. + */ + protected final FontMetrics getStandard14AFM() { - return fontDescriptor; + return afmStandard14; } - /** - * Sets the font descriptor. For internal PDFBox use only. - */ - void setFontDescriptor(PDFontDescriptor fontDescriptor) + @Override + public PDFontDescriptor getFontDescriptor() { - this.fontDescriptor = fontDescriptor; + return fontDescriptor; } /** @@ -183,26 +214,24 @@ public abstract class PDFont implements // embedded", however PDFBOX-427 shows that it also applies to embedded fonts. // Type1, Type1C, Type3 - int firstChar = dict.getInt(COSName.FIRST_CHAR, -1); - int lastChar = dict.getInt(COSName.LAST_CHAR, -1); - if (getWidths().size() > 0 && code >= firstChar && code <= lastChar) - { - return getWidths().get(code - firstChar).floatValue(); - } - else + if (dict.containsKey(COSName.WIDTHS) || dict.containsKey(COSName.MISSING_WIDTH)) { - PDFontDescriptor fd = getFontDescriptor(); - if (fd instanceof PDFontDescriptorDictionary && - ((PDFontDescriptorDictionary) fd).hasWidths()) + int firstChar = dict.getInt(COSName.FIRST_CHAR, -1); + int lastChar = dict.getInt(COSName.LAST_CHAR, -1); + if (getWidths().size() > 0 && code >= firstChar && code <= lastChar) { - return fd.getMissingWidth(); + return getWidths().get(code - firstChar).floatValue(); } - else + + PDFontDescriptor fd = getFontDescriptor(); + if (fd != null) { - // if there's nothing to override with, then obviously we fall back to the font - return getWidthFromFont(code); + return fd.getMissingWidth(); // default is 0 } } + + // if there's nothing to override with, then obviously we fall back to the font + return getWidthFromFont(code); } @Override @@ -293,7 +322,7 @@ public abstract class PDFont implements */ public String toUnicode(int code) throws IOException { - // if the font dictionary contains a ToUnicode CMap, use that CMap + // if the font dictionary containsName a ToUnicode CMap, use that CMap if (toUnicodeCMap != null) { if (toUnicodeCMap.getName() != null && toUnicodeCMap.getName().startsWith("Identity-")) @@ -456,6 +485,29 @@ public abstract class PDFont implements */ public abstract boolean isVertical(); + /** + * Returns true if this font is one of the "Standard 14" fonts and receives special handling. + */ + public boolean isStandard14() + { + // this logic is based on Acrobat's behaviour, see see PDFBOX-2372 + + // symbolic fonts are never standard: they don't use the Adobe Standard Roman character set + if (isSymbolic()) + { + return false; + } + + // embedded fonts never get special treatment + if (isEmbedded()) + { + return false; + } + + // if the name matches, this is a Standard 14 font + return Standard14Fonts.containsName(getName()); + } + @Override public boolean equals(Object other) { Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontDescriptor.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontDescriptor.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontDescriptor.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontDescriptor.java Thu Sep 25 03:35:24 2014 @@ -16,132 +16,56 @@ */ package org.apache.pdfbox.pdmodel.font; -import java.io.IOException; - +import org.apache.pdfbox.cos.COSArray; +import org.apache.pdfbox.cos.COSDictionary; +import org.apache.pdfbox.cos.COSName; +import org.apache.pdfbox.cos.COSStream; +import org.apache.pdfbox.cos.COSString; +import org.apache.pdfbox.pdmodel.common.COSObjectable; import org.apache.pdfbox.pdmodel.common.PDRectangle; +import org.apache.pdfbox.pdmodel.common.PDStream; /** - * This class represents an interface to the font description. This will depend - * on the font type for the actual implementation. If it is a AFM/cmap/or embedded font. + * A font descriptor. * - * @author <a href="mailto:b...@benlitchfield.com">Ben Litchfield</a> - * @version $Revision: 1.2 $ + * @author Ben Litchfield */ -public abstract class PDFontDescriptor +public final class PDFontDescriptor implements COSObjectable { - /** - * A font descriptor flag. See PDF Reference for description. - */ private static final int FLAG_FIXED_PITCH = 1; - /** - * A font descriptor flag. See PDF Reference for description. - */ private static final int FLAG_SERIF = 2; - /** - * A font descriptor flag. See PDF Reference for description. - */ private static final int FLAG_SYMBOLIC = 4; - /** - * A font descriptor flag. See PDF Reference for description. - */ private static final int FLAG_SCRIPT = 8; - /** - * A font descriptor flag. See PDF Reference for description. - */ private static final int FLAG_NON_SYMBOLIC = 32; - /** - * A font descriptor flag. See PDF Reference for description. - */ private static final int FLAG_ITALIC = 64; - /** - * A font descriptor flag. See PDF Reference for description. - */ private static final int FLAG_ALL_CAP = 65536; - /** - * A font descriptor flag. See PDF Reference for description. - */ private static final int FLAG_SMALL_CAP = 131072; - /** - * A font descriptor flag. See PDF Reference for description. - */ private static final int FLAG_FORCE_BOLD = 262144; + private final COSDictionary dic; + private float xHeight = Float.NEGATIVE_INFINITY; + private float capHeight = Float.NEGATIVE_INFINITY; + private int flags = -1; - /** - * Get the font name. - * - * @return The name of the font. - */ - public abstract String getFontName(); - - /** - * This will set the font name. - * - * @param fontName The new name for the font. - */ - public abstract void setFontName( String fontName ); - - /** - * A string representing the preferred font family. - * - * @return The font family. - */ - public abstract String getFontFamily(); - - /** - * This will set the font family. - * - * @param fontFamily The font family. - */ - public abstract void setFontFamily( String fontFamily ); - - /** - * A string representing the preferred font stretch. - * According to the PDF Spec: - * The font stretch value; it must be one of the following (ordered from - * narrowest to widest): UltraCondensed, ExtraCondensed, Condensed, SemiCondensed, - * Normal, SemiExpanded, Expanded, ExtraExpanded or UltraExpanded. - * - * @return The font stretch. - */ - public abstract String getFontStretch(); - - /** - * This will set the font stretch. - * - * @param fontStretch The font stretch - */ - public abstract void setFontStretch( String fontStretch ); - - /** - * The weight of the font. According to the PDF spec "possible values are - * 100, 200, 300, 400, 500, 600, 700, 800 or 900" Where a higher number is - * more weight and appears to be more bold. - * - * @return The font weight. - */ - public abstract float getFontWeight(); /** - * Set the weight of the font. - * - * @param fontWeight The new weight of the font. + * Package-private constructor, for embedding. */ - public abstract void setFontWeight( float fontWeight ); - - /** - * This will get the font flags. - * - * @return The font flags. - */ - public abstract int getFlags(); + PDFontDescriptor() + { + dic = new COSDictionary(); + dic.setItem( COSName.TYPE, COSName.FONT_DESC ); + } /** - * This will set the font flags. + * Creates a PDFontDescriptor from a COS dictionary. * - * @param flags The new font flags. + * @param desc The wrapped COS Dictionary. */ - public abstract void setFlags( int flags ); + public PDFontDescriptor( COSDictionary desc ) + { + dic = desc; + } /** * A convenience method that checks the flag bit. @@ -343,189 +267,543 @@ public abstract class PDFontDescriptor } /** - * This will get the fonts bouding box. + * Convert this standard java object to a COS object. + * + * @return The cos object that matches this Java object. + */ + public COSDictionary getCOSObject() + { + return dic; + } + + /** + * Get the font name. + * + * @return The name of the font. + */ + public String getFontName() + { + String retval = null; + COSName name = (COSName)dic.getDictionaryObject( COSName.FONT_NAME ); + if( name != null ) + { + retval = name.getName(); + } + return retval; + } + + /** + * This will set the font name. + * + * @param fontName The new name for the font. + */ + public void setFontName( String fontName ) + { + COSName name = null; + if( fontName != null ) + { + name = COSName.getPDFName( fontName ); + } + dic.setItem( COSName.FONT_NAME, name ); + } + + /** + * A string representing the preferred font family. + * + * @return The font family. + */ + public String getFontFamily() + { + String retval = null; + COSString name = (COSString)dic.getDictionaryObject( COSName.FONT_FAMILY ); + if( name != null ) + { + retval = name.getString(); + } + return retval; + } + + /** + * This will set the font family. + * + * @param fontFamily The font family. + */ + public void setFontFamily( String fontFamily ) + { + COSString name = null; + if( fontFamily != null ) + { + name = new COSString( fontFamily ); + } + dic.setItem( COSName.FONT_FAMILY, name ); + } + + /** + * The weight of the font. According to the PDF spec "possible values are + * 100, 200, 300, 400, 500, 600, 700, 800 or 900" Where a higher number is + * more weight and appears to be more bold. + * + * @return The font weight. + */ + public float getFontWeight() + { + return dic.getFloat( COSName.FONT_WEIGHT,0 ); + } + + /** + * Set the weight of the font. * - * @return The fonts bouding box. + * @param fontWeight The new weight of the font. */ - public abstract PDRectangle getFontBoundingBox(); + public void setFontWeight( float fontWeight ) + { + dic.setFloat( COSName.FONT_WEIGHT, fontWeight ); + } + + /** + * A string representing the preferred font stretch. + * According to the PDF Spec: + * The font stretch value; it must be one of the following (ordered from + * narrowest to widest): UltraCondensed, ExtraCondensed, Condensed, SemiCondensed, + * Normal, SemiExpanded, Expanded, ExtraExpanded or UltraExpanded. + * + * @return The stretch of the font. + */ + public String getFontStretch() + { + String retval = null; + COSName name = (COSName)dic.getDictionaryObject( COSName.FONT_STRETCH ); + if( name != null ) + { + retval = name.getName(); + } + return retval; + } + + /** + * This will set the font stretch. + * + * @param fontStretch The new stretch for the font. + */ + public void setFontStretch( String fontStretch ) + { + COSName name = null; + if( fontStretch != null ) + { + name = COSName.getPDFName( fontStretch ); + } + dic.setItem( COSName.FONT_STRETCH, name ); + } + + /** + * This will get the font flags. + * + * @return The font flags. + */ + public int getFlags() + { + if (flags == -1) + { + flags = dic.getInt( COSName.FLAGS, 0 ); + } + return flags; + } + + /** + * This will set the font flags. + * + * @param flags The new font flags. + */ + public void setFlags( int flags ) + { + dic.setInt( COSName.FLAGS, flags ); + this.flags = flags; + } + + /** + * This will get the fonts bounding box. + * + * @return The fonts bounding box. + */ + public PDRectangle getFontBoundingBox() + { + COSArray rect = (COSArray)dic.getDictionaryObject( COSName.FONT_BBOX ); + PDRectangle retval = null; + if( rect != null ) + { + retval = new PDRectangle( rect ); + } + return retval; + } /** * Set the fonts bounding box. * * @param rect The new bouding box. */ - public abstract void setFontBoundingBox( PDRectangle rect ); + public void setFontBoundingBox( PDRectangle rect ) + { + COSArray array = null; + if( rect != null ) + { + array = rect.getCOSArray(); + } + dic.setItem( COSName.FONT_BBOX, array ); + } /** * This will get the italic angle for the font. * * @return The italic angle. */ - public abstract float getItalicAngle(); + public float getItalicAngle() + { + return dic.getFloat( COSName.ITALIC_ANGLE, 0 ); + } /** * This will set the italic angle for the font. * * @param angle The new italic angle for the font. */ - public abstract void setItalicAngle( float angle ); + public void setItalicAngle( float angle ) + { + dic.setFloat( COSName.ITALIC_ANGLE, angle ); + } /** * This will get the ascent for the font. * * @return The ascent. */ - public abstract float getAscent(); + public float getAscent() + { + return dic.getFloat( COSName.ASCENT, 0 ); + } /** * This will set the ascent for the font. * * @param ascent The new ascent for the font. */ - public abstract void setAscent( float ascent ); + public void setAscent( float ascent ) + { + dic.setFloat( COSName.ASCENT, ascent ); + } /** * This will get the descent for the font. * * @return The descent. */ - public abstract float getDescent(); + public float getDescent() + { + return dic.getFloat( COSName.DESCENT, 0 ); + } /** * This will set the descent for the font. * * @param descent The new descent for the font. */ - public abstract void setDescent( float descent ); + public void setDescent( float descent ) + { + dic.setFloat( COSName.DESCENT, descent ); + } /** * This will get the leading for the font. * * @return The leading. */ - public abstract float getLeading(); + public float getLeading() + { + return dic.getFloat( COSName.LEADING, 0 ); + } /** * This will set the leading for the font. * * @param leading The new leading for the font. */ - public abstract void setLeading( float leading ); + public void setLeading( float leading ) + { + dic.setFloat( COSName.LEADING, leading ); + } /** * This will get the CapHeight for the font. * * @return The cap height. */ - public abstract float getCapHeight(); + public float getCapHeight() + { + if(capHeight==Float.NEGATIVE_INFINITY) + { + /* We observed a negative value being returned with + * the Scheherazade font. PDFBOX-429 was logged for this. + * We are not sure if returning the absolute value + * is the correct fix, but it seems to work. */ + capHeight = java.lang.Math.abs(dic.getFloat( COSName.CAP_HEIGHT, 0 )); + } + return capHeight; + } + /** * This will set the cap height for the font. * * @param capHeight The new cap height for the font. */ - public abstract void setCapHeight( float capHeight ); + public void setCapHeight( float capHeight ) + { + dic.setFloat( COSName.CAP_HEIGHT, capHeight ); + this.capHeight = capHeight; + } /** * This will get the x height for the font. * * @return The x height. */ - public abstract float getXHeight(); + public float getXHeight() + { + if(xHeight==Float.NEGATIVE_INFINITY) + { + /* We observed a negative value being returned with + * the Scheherazade font. PDFBOX-429 was logged for this. + * We are not sure if returning the absolute value + * is the correct fix, but it seems to work. */ + xHeight = java.lang.Math.abs(dic.getFloat( COSName.XHEIGHT, 0 )); + } + return xHeight; + } /** * This will set the x height for the font. * * @param xHeight The new x height for the font. */ - public abstract void setXHeight( float xHeight ); + public void setXHeight( float xHeight ) + { + dic.setFloat( COSName.XHEIGHT, xHeight ); + this.xHeight = xHeight; + } /** * This will get the stemV for the font. * * @return The stem v value. */ - public abstract float getStemV(); + public float getStemV() + { + return dic.getFloat( COSName.STEM_V, 0 ); + } /** * This will set the stem V for the font. * * @param stemV The new stem v for the font. */ - public abstract void setStemV( float stemV ); + public void setStemV( float stemV ) + { + dic.setFloat( COSName.STEM_V, stemV ); + } /** * This will get the stemH for the font. * * @return The stem h value. */ - public abstract float getStemH(); + public float getStemH() + { + return dic.getFloat( COSName.STEM_H, 0 ); + } /** * This will set the stem H for the font. * * @param stemH The new stem h for the font. */ - public abstract void setStemH( float stemH ); + public void setStemH( float stemH ) + { + dic.setFloat( COSName.STEM_H, stemH ); + } /** - * This will get the average width for the font. This is part of the - * definition in the font description. If it is not present then PDFBox - * will make an attempt to calculate it. + * This will get the average width for the font. * * @return The average width value. - * - * @throws IOException If there is an error calculating the average width. */ - public abstract float getAverageWidth() throws IOException; + public float getAverageWidth() + { + return dic.getFloat( COSName.AVG_WIDTH, 0 ); + } /** * This will set the average width for the font. * * @param averageWidth The new average width for the font. */ - public abstract void setAverageWidth( float averageWidth ); + public void setAverageWidth( float averageWidth ) + { + dic.setFloat( COSName.AVG_WIDTH, averageWidth ); + } /** * This will get the max width for the font. * * @return The max width value. */ - public abstract float getMaxWidth(); + public float getMaxWidth() + { + return dic.getFloat( COSName.MAX_WIDTH, 0 ); + } /** * This will set the max width for the font. * * @param maxWidth The new max width for the font. */ - public abstract void setMaxWidth( float maxWidth ); + public void setMaxWidth( float maxWidth ) + { + dic.setFloat( COSName.MAX_WIDTH, maxWidth ); + } + + /** + * Returns true if widths are present in the font descriptor. + */ + public boolean hasWidths() + { + return dic.containsKey(COSName.WIDTHS) || dic.containsKey(COSName.MISSING_WIDTH); + } + + /** + * This will get the missing width for the font. + * + * @return The missing width value. + */ + public float getMissingWidth() + { + return dic.getFloat( COSName.MISSING_WIDTH, 0 ); + } + + /** + * This will set the missing width for the font. + * + * @param missingWidth The new missing width for the font. + */ + public void setMissingWidth( float missingWidth ) + { + dic.setFloat( COSName.MISSING_WIDTH, missingWidth ); + } /** * This will get the character set for the font. * * @return The character set value. */ - public abstract String getCharSet(); + public String getCharSet() + { + String retval = null; + COSString name = (COSString)dic.getDictionaryObject( COSName.CHAR_SET ); + if( name != null ) + { + retval = name.getString(); + } + return retval; + } /** * This will set the character set for the font. * * @param charSet The new character set for the font. */ - public abstract void setCharacterSet( String charSet ); + public void setCharacterSet( String charSet ) + { + COSString name = null; + if( charSet != null ) + { + name = new COSString( charSet ); + } + dic.setItem( COSName.CHAR_SET, name ); + } /** - * This will get the missing width for the font. + * A stream containing a Type 1 font program. * - * @return The missing width value. + * @return A stream containing a Type 1 font program. */ - public abstract float getMissingWidth(); + public PDStream getFontFile() + { + PDStream retval = null; + COSStream stream = (COSStream)dic.getDictionaryObject( COSName.FONT_FILE ); + if( stream != null ) + { + retval = new PDStream( stream ); + } + return retval; + } /** - * This will set the missing width for the font. + * Set the type 1 font program. * - * @param missingWidth The new missing width for the font. + * @param type1Stream The type 1 stream. */ - public abstract void setMissingWidth( float missingWidth ); + public void setFontFile( PDStream type1Stream ) + { + dic.setItem( COSName.FONT_FILE, type1Stream ); + } + /** + * A stream containing a true type font program. + * + * @return A stream containing a true type font program. + */ + public PDStream getFontFile2() + { + PDStream retval = null; + COSStream stream = (COSStream)dic.getDictionaryObject( COSName.FONT_FILE2 ); + if( stream != null ) + { + retval = new PDStream( stream ); + } + return retval; + } + + /** + * Set the true type font program. + * + * @param ttfStream The true type stream. + */ + public void setFontFile2( PDStream ttfStream ) + { + dic.setItem( COSName.FONT_FILE2, ttfStream ); + } + + /** + * A stream containing a font program that is not true type or type 1. + * + * @return A stream containing a font program. + */ + public PDStream getFontFile3() + { + PDStream retval = null; + COSStream stream = (COSStream)dic.getDictionaryObject( COSName.FONT_FILE3 ); + if( stream != null ) + { + retval = new PDStream( stream ); + } + return retval; + } + + /** + * Set a stream containing a font program that is not true type or type 1. + * + * @param stream The font program stream. + */ + public void setFontFile3( PDStream stream ) + { + dic.setItem( COSName.FONT_FILE3, stream ); + } } Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDSimpleFont.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDSimpleFont.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDSimpleFont.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDSimpleFont.java Thu Sep 25 03:35:24 2014 @@ -29,7 +29,6 @@ import org.apache.pdfbox.encoding.Standa import org.apache.pdfbox.encoding.WinAnsiEncoding; import java.io.IOException; -import java.util.Arrays; import java.util.HashSet; import java.util.Set; @@ -42,31 +41,6 @@ public abstract class PDSimpleFont exten { private static final Log LOG = LogFactory.getLog(PDSimpleFont.class); - private static Set<String> STANDARD_14 = new HashSet<String>(); - static - { - // standard 14 names - STANDARD_14.addAll(Arrays.asList( - "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique", "Helvetica", - "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique", "Times-Roman", - "Times-Bold", "Times-Italic","Times-BoldItalic", "Symbol", "ZapfDingbats" - )); - // alternative names from Adobe Supplement to the ISO 32000 - STANDARD_14.addAll(Arrays.asList( - "CourierCourierNew", "CourierNew", "CourierNew,Italic", "CourierNew,Bold", - "CourierNew,BoldItalic", "Arial", "Arial,Italic", "Arial,Bold", "Arial,BoldItalic", - "TimesNewRoman", "TimesNewRoman,Italic", "TimesNewRoman,Bold", "TimesNewRoman,BoldItalic" - )); - } - - /** - * Returns true if this font is one of the "standard 14" fonts. - */ - public static boolean isStandard14(String name) - { - return STANDARD_14.contains(name); - } - protected Encoding encoding; protected GlyphList glyphList; private final Set<Integer> noUnicode = new HashSet<Integer>(); // for logging @@ -301,10 +275,40 @@ public abstract class PDSimpleFont exten } /** - * Returns true if this font is one of the "standard 14" fonts. + * Returns the glyph width from the AFM if this is a Standard 14 font. + * @param code character code + * @return width in 1/1000 text space */ + protected final float getStandard14Width(int code) + { + if (getStandard14AFM() != null) + { + String nameInAFM = getEncoding().getName(code); + + // the Adobe AFMs don't include .notdef, but Acrobat uses 250, test with PDFBOX-2334 + if (nameInAFM.equals(".notdef")) + { + return 250f; + } + + return getStandard14AFM().getCharacterWidth(nameInAFM); + } + throw new IllegalStateException("No AFM"); + } + public boolean isStandard14() { - return !isEmbedded() && STANDARD_14.contains(getName()); + // this logic is based on Acrobat's behaviour, see see PDFBOX-2372 + // the Encoding entry cannot have Differences if we want "standard 14" font handling + if (getEncoding() != null && getEncoding() instanceof DictionaryEncoding) + { + DictionaryEncoding dictionary = (DictionaryEncoding)getEncoding(); + if (dictionary.getDifferences().size() > 0) + { + // todo: do we need to check if entries actually differ from the base encoding? + return false; + } + } + return super.isStandard14(); } } Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java Thu Sep 25 03:35:24 2014 @@ -108,10 +108,10 @@ public class PDTrueTypeFont extends PDSi { super(fontDictionary); - PDFontDescriptorDictionary fd = (PDFontDescriptorDictionary) super.getFontDescriptor(); TrueTypeFont ttfFont = null; - if (fd != null) + if (getFontDescriptor() != null) { + PDFontDescriptor fd = super.getFontDescriptor(); PDStream ff2Stream = fd.getFontFile2(); if (ff2Stream != null) { @@ -205,6 +205,11 @@ public class PDTrueTypeFont extends PDSi @Override public float getWidthFromFont(int code) throws IOException { + if (getStandard14AFM() != null) + { + return getStandard14Width(code); + } + int gid = codeToGID(code); float width = ttf.getAdvanceWidth(gid); float unitsPerEM = ttf.getUnitsPerEm(); Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFontEmbedder.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFontEmbedder.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFontEmbedder.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFontEmbedder.java Thu Sep 25 03:35:24 2014 @@ -80,7 +80,7 @@ class PDTrueTypeFontEmbedder // as the stream was close within the PDStream constructor, we have to recreate it InputStream stream2 = null; - PDFontDescriptorDictionary fd; + PDFontDescriptor fd; try { stream2 = stream.createInputStream(); @@ -97,10 +97,10 @@ class PDTrueTypeFontEmbedder } // creates a new font descriptor dictionary for the given TTF - private PDFontDescriptorDictionary createFontDescriptor(COSDictionary dict, TrueTypeFont ttf) + private PDFontDescriptor createFontDescriptor(COSDictionary dict, TrueTypeFont ttf) throws IOException { - PDFontDescriptorDictionary fd = new PDFontDescriptorDictionary(); + PDFontDescriptor fd = new PDFontDescriptor(); NamingTable naming = ttf.getNaming(); List<NameRecord> records = naming.getNameRecords(); Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java Thu Sep 25 03:35:24 2014 @@ -320,6 +320,12 @@ public class PDType0Font extends PDFont } @Override + public boolean isStandard14() + { + return false; + } + + @Override public String toString() { String descendant = null; Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java Thu Sep 25 03:35:24 2014 @@ -73,9 +73,9 @@ public class PDType1CFont extends PDSimp PDFontDescriptor fd = getFontDescriptor(); byte[] bytes = null; - if (fd != null && fd instanceof PDFontDescriptorDictionary) // <-- todo: must be true + if (fd != null) { - PDStream ff3Stream = ((PDFontDescriptorDictionary) fd).getFontFile3(); + PDStream ff3Stream = fd.getFontFile3(); if (ff3Stream != null) { bytes = IOUtils.toByteArray(ff3Stream.createInputStream()); @@ -127,9 +127,8 @@ public class PDType1CFont extends PDSimp @Override public GeneralPath getPath(String name) throws IOException { - // Adobe's Standard 14 fonts have an empty .notdef glyph, but Microsoft's don't - // so we need to fake this glyph otherwise we get unwanted rectangles, see PDFBOX-2372 - if (!isEmbedded() && ".notdef".equals(name) && isStandard14()) + // Acrobat only draws .notdef for embedded or "Standard 14" fonts, see PDFBOX-2372 + if (name.equals(".notdef") && !isEmbedded() && !isStandard14()) { return new GeneralPath(); } @@ -192,6 +191,11 @@ public class PDType1CFont extends PDSimp @Override public float getWidthFromFont(int code) throws IOException { + if (getStandard14AFM() != null) + { + return getStandard14Width(code); + } + String name = codeToName(code); float width = type1Equivalent.getWidth(name); Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java Thu Sep 25 03:35:24 2014 @@ -19,7 +19,6 @@ package org.apache.pdfbox.pdmodel.font; import java.awt.geom.GeneralPath; import java.io.IOException; import java.io.InputStream; -import java.net.URL; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -27,8 +26,6 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.fontbox.afm.AFMParser; -import org.apache.fontbox.afm.FontMetrics; import org.apache.fontbox.ttf.Type1Equivalent; import org.apache.fontbox.type1.DamagedFontException; import org.apache.fontbox.type1.Type1Font; @@ -53,60 +50,6 @@ public class PDType1Font extends PDSimpl { private static final Log LOG = LogFactory.getLog(PDType1Font.class); - /** - * The static map of the default Adobe font metrics. - */ - private static final Map<String, FontMetrics> AFM_MAP; - static - { - try - { - AFM_MAP = new HashMap<String, FontMetrics>(); - addMetric("Courier-Bold"); - addMetric("Courier-BoldOblique"); - addMetric("Courier"); - addMetric("Courier-Oblique"); - addMetric("Helvetica"); - addMetric("Helvetica-Bold"); - addMetric("Helvetica-BoldOblique"); - addMetric("Helvetica-Oblique"); - addMetric("Symbol"); - addMetric("Times-Bold"); - addMetric("Times-BoldItalic"); - addMetric("Times-Italic"); - addMetric("Times-Roman"); - addMetric("ZapfDingbats"); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - } - - private static void addMetric(String fontName) throws IOException - { - String resourceName = "org/apache/pdfbox/resources/afm/" + fontName + ".afm"; - URL url = PDType1Font.class.getClassLoader().getResource(resourceName); - if (url != null) - { - InputStream afmStream = url.openStream(); - try - { - AFMParser parser = new AFMParser(afmStream); - FontMetrics metric = parser.parse(); - AFM_MAP.put(fontName, metric); - } - finally - { - afmStream.close(); - } - } - else - { - throw new IOException(resourceName + " not found"); - } - } - // alternative names for glyphs which are commonly encountered private static final Map<String, String> ALT_NAMES = new HashMap<String, String>(); static @@ -138,7 +81,6 @@ public class PDType1Font extends PDSimpl public static final PDType1Font SYMBOL = new PDType1Font("Symbol"); public static final PDType1Font ZAPF_DINGBATS = new PDType1Font("ZapfDingbats"); - private final FontMetrics afm; // for standard 14 fonts private final Type1Font type1font; // embedded font private final Type1Equivalent type1Equivalent; // embedded or system font for rendering private final boolean isEmbedded; @@ -156,12 +98,6 @@ public class PDType1Font extends PDSimpl encoding = new WinAnsiEncoding(); dict.setItem(COSName.ENCODING, COSName.WIN_ANSI_ENCODING); - afm = getAFMFromBaseFont(baseFont); - if (afm == null) - { - throw new IllegalArgumentException("No AFM for font " + baseFont); - } - // todo: could load the PFB font here if we wanted to support Standard 14 embedding type1font = null; type1Equivalent = ExternalFonts.getType1EquivalentFont(getBaseFont()); @@ -180,7 +116,6 @@ public class PDType1Font extends PDSimpl { PDType1FontEmbedder embedder = new PDType1FontEmbedder(doc, dict, afmIn, pfbIn); encoding = embedder.getFontEncoding(); - afm = null; // only used for standard 14 fonts, not AFM fonts as we already have the PFB type1font = embedder.getType1Font(); type1Equivalent = embedder.getType1Font(); isEmbedded = true; @@ -196,17 +131,17 @@ public class PDType1Font extends PDSimpl super(fontDictionary); PDFontDescriptor fd = getFontDescriptor(); Type1Font t1 = null; - if (fd != null && fd instanceof PDFontDescriptorDictionary) // <-- todo: must be true + if (fd != null) { // a Type1 font may contain a Type1C font - PDStream fontFile3 = ((PDFontDescriptorDictionary) fd).getFontFile3(); + PDStream fontFile3 = fd.getFontFile3(); if (fontFile3 != null) { throw new IllegalArgumentException("Use PDType1CFont for FontFile3"); } // or it may contain a PFB - PDStream fontFile = ((PDFontDescriptorDictionary) fd).getFontFile(); + PDStream fontFile = fd.getFontFile(); if (fontFile != null) { try @@ -260,27 +195,9 @@ public class PDType1Font extends PDSimpl type1Equivalent = ExternalFonts.getType1FallbackFont(getFontDescriptor()); } } - - // todo: for standard 14 only. todo: move this to a subclass "PDStandardType1Font" ? - afm = getAFMFromBaseFont(getBaseFont()); // may be null (it usually is) - readEncoding(); } - // todo: move this to a subclass? - private FontMetrics getAFMFromBaseFont(String baseFont) - { - if (baseFont != null) - { - if (baseFont.contains("+")) - { - baseFont = baseFont.substring(baseFont.indexOf('+') + 1); - } - return AFM_MAP.get(baseFont); - } - return null; - } - /** * Returns the PostScript name of the font. */ @@ -290,29 +207,13 @@ public class PDType1Font extends PDSimpl } @Override - public PDFontDescriptor getFontDescriptor() - { - PDFontDescriptor fd = super.getFontDescriptor(); - if (fd == null) - { - if (afm != null) - { - // this is for embedding fonts into PDFs, rather than for reading, though it works. - fd = new PDFontDescriptorAFM(afm); - setFontDescriptor(fd); - } - } - return fd; - } - - @Override public float getHeight(int code) throws IOException { String name = codeToName(code); - if (afm != null) + if (getStandard14AFM() != null) { String afmName = getEncoding().getName(code); - return afm.getCharacterHeight(afmName); // todo: isn't this the y-advance, not the height? + return getStandard14AFM().getCharacterHeight(afmName); // todo: isn't this the y-advance, not the height? } else { @@ -324,10 +225,9 @@ public class PDType1Font extends PDSimpl public float getWidthFromFont(int code) throws IOException { String name = codeToName(code); - if (afm != null) + if (getStandard14AFM() != null) { - String afmName = getEncoding().getName(code); - return afm.getCharacterWidth(afmName); + return getStandard14Width(code); } else { @@ -344,9 +244,9 @@ public class PDType1Font extends PDSimpl @Override public float getAverageFontWidth() { - if (afm != null) + if (getStandard14AFM() != null) { - return afm.getAverageCharacterWidth(); + return getStandard14AFM().getAverageCharacterWidth(); } else { @@ -363,10 +263,10 @@ public class PDType1Font extends PDSimpl @Override protected Encoding readEncodingFromFont() throws IOException { - if (afm != null) + if (getStandard14AFM() != null) { // read from AFM - return new Type1Encoding(afm); + return new Type1Encoding(getStandard14AFM()); } else { @@ -448,9 +348,8 @@ public class PDType1Font extends PDSimpl @Override public GeneralPath getPath(String name) throws IOException { - // Adobe's Standard 14 fonts have an empty .notdef glyph, but Microsoft's don't - // so we need to fake this glyph otherwise we get unwanted rectangles, see PDFBOX-2372 - if (!isEmbedded() && ".notdef".equals(name) && isStandard14()) + // Acrobat only draws .notdef for embedded or "Standard 14" fonts, see PDFBOX-2372 + if (name.equals(".notdef") && !isEmbedded() && !isStandard14()) { return new GeneralPath(); } Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1FontEmbedder.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1FontEmbedder.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1FontEmbedder.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1FontEmbedder.java Thu Sep 25 03:35:24 2014 @@ -66,8 +66,13 @@ class PDType1FontEmbedder { dict.setItem(COSName.SUBTYPE, COSName.TYPE1); - PDFontDescriptorDictionary fd = new PDFontDescriptorDictionary(); - dict.setItem(COSName.FONT_DESC, fd); + // read the afm + AFMParser afmParser = new AFMParser(afmStream); + metrics = afmParser.parse(); + this.fontEncoding = encodingFromAFM(metrics); + + // build font descriptor + PDFontDescriptor fd = buildFontDescriptor(metrics); // read the pfb byte[] pfbBytes = IOUtils.toByteArray(pfbStream); @@ -83,24 +88,9 @@ class PDType1FontEmbedder fontStream.addCompression(); fd.setFontFile(fontStream); - // read the afm - AFMParser afmParser = new AFMParser(afmStream); - metrics = afmParser.parse(); - this.fontEncoding = encodingFromAFM(metrics); - // set the values + dict.setItem(COSName.FONT_DESC, fd); dict.setName(COSName.BASE_FONT, metrics.getFontName()); - fd.setFontName(metrics.getFontName()); - fd.setFontFamily(metrics.getFamilyName()); - fd.setNonSymbolic(true); - fd.setFontBoundingBox(new PDRectangle(metrics.getFontBBox())); - fd.setItalicAngle(metrics.getItalicAngle()); - fd.setAscent(metrics.getAscender()); - fd.setDescent(metrics.getDescender()); - fd.setCapHeight(metrics.getCapHeight()); - fd.setXHeight(metrics.getXHeight()); - fd.setAverageWidth(metrics.getAverageCharacterWidth()); - fd.setCharacterSet(metrics.getCharacterSet()); // get firstchar, lastchar int firstchar = 255; @@ -139,6 +129,28 @@ class PDType1FontEmbedder dict.setItem(COSName.WIDTHS, COSArrayList.converterToCOSArray(widths)); } + /** + * Returns a PDFontDescriptor for the given AFM. + * + * @param metrics AFM + */ + static PDFontDescriptor buildFontDescriptor(FontMetrics metrics) + { + PDFontDescriptor fd = new PDFontDescriptor(); + fd.setFontName(metrics.getFontName()); + fd.setFontFamily(metrics.getFamilyName()); + fd.setNonSymbolic(true); + fd.setFontBoundingBox(new PDRectangle(metrics.getFontBBox())); + fd.setItalicAngle(metrics.getItalicAngle()); + fd.setAscent(metrics.getAscender()); + fd.setDescent(metrics.getDescender()); + fd.setCapHeight(metrics.getCapHeight()); + fd.setXHeight(metrics.getXHeight()); + fd.setAverageWidth(metrics.getAverageCharacterWidth()); + fd.setCharacterSet(metrics.getCharacterSet()); + return fd; + } + // This will generate a Encoding from the AFM-Encoding, because the AFM-Enconding isn't exported // to the pdf and consequently the StandardEncoding is used so that any special character is // missing I've copied the code from the pdfbox-forum posted by V0JT4 and made some additions Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java Thu Sep 25 03:35:24 2014 @@ -92,7 +92,7 @@ public class PDType3Font extends PDSimpl else { PDFontDescriptor fd = getFontDescriptor(); - if (fd instanceof PDFontDescriptorDictionary) + if (fd != null) { return fd.getMissingWidth(); } Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/Standard14Fonts.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/Standard14Fonts.java?rev=1627450&view=auto ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/Standard14Fonts.java (added) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/Standard14Fonts.java Thu Sep 25 03:35:24 2014 @@ -0,0 +1,163 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.pdfbox.pdmodel.font; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import org.apache.fontbox.afm.AFMParser; +import org.apache.fontbox.afm.FontMetrics; + +/** + * The "Standard 14" PDF fonts, also known as the "base 14" fonts. + * There are 14 font files, but Acrobat uses additional names for compatibility, e.g. Arial. + * + * @author John Hewson + */ +class Standard14Fonts +{ + private Standard14Fonts() + { + } + + private final static Set<String> STANDARD_14_NAMES = new HashSet<String>(); + private final static Map<String, String> STANDARD_14_MAPPING = new HashMap<String, String>(); + private static final Map<String, FontMetrics> STANDARD14_AFM_MAP; + static + { + try + { + STANDARD14_AFM_MAP = new HashMap<String, FontMetrics>(); + addAFM("Courier-Bold"); + addAFM("Courier-BoldOblique"); + addAFM("Courier"); + addAFM("Courier-Oblique"); + addAFM("Helvetica"); + addAFM("Helvetica-Bold"); + addAFM("Helvetica-BoldOblique"); + addAFM("Helvetica-Oblique"); + addAFM("Symbol"); + addAFM("Times-Bold"); + addAFM("Times-BoldItalic"); + addAFM("Times-Italic"); + addAFM("Times-Roman"); + addAFM("ZapfDingbats"); + + // alternative names from Adobe Supplement to the ISO 32000 + addAFM("CourierCourierNew", "Courier"); + addAFM("CourierNew", "Courier"); + addAFM("CourierNew,Italic", "Courier-Oblique"); + addAFM("CourierNew,Bold", "Courier-Bold"); + addAFM("CourierNew,BoldItalic", "Courier-BoldOblique"); + addAFM("Arial", "Helvetica"); + addAFM("Arial,Italic", "Helvetica-Oblique"); + addAFM("Arial,Bold", "Helvetica-Bold"); + addAFM("Arial,BoldItalic", "Helvetica-BoldOblique"); + addAFM("TimesNewRoman", "Times-Roman"); + addAFM("TimesNewRoman,Italic", "Times-Italic"); + addAFM("TimesNewRoman,Bold", "Times-Bold"); + addAFM("TimesNewRoman,BoldItalic", "Times-BoldItalic"); + + // Acrobat treats these fonts as "standard 14" too (at least Acrobat preflight says so) + addAFM("Symbol,Italic", "Symbol"); + addAFM("Symbol,Bold", "Symbol"); + addAFM("Symbol,BoldItalic", "Symbol"); + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } + + private static void addAFM(String fontName) throws IOException + { + addAFM(fontName, fontName); + } + + private static void addAFM(String fontName, String afmName) throws IOException + { + STANDARD_14_NAMES.add(fontName); + STANDARD_14_MAPPING.put(fontName, afmName); + + if (STANDARD14_AFM_MAP.containsKey(afmName)) + { + STANDARD14_AFM_MAP.put(fontName, STANDARD14_AFM_MAP.get(afmName)); + } + + String resourceName = "org/apache/pdfbox/resources/afm/" + afmName + ".afm"; + URL url = PDType1Font.class.getClassLoader().getResource(resourceName); + if (url != null) + { + InputStream afmStream = url.openStream(); + try + { + AFMParser parser = new AFMParser(afmStream); + FontMetrics metric = parser.parse(); + STANDARD14_AFM_MAP.put(fontName, metric); + } + finally + { + afmStream.close(); + } + } + else + { + throw new IOException(resourceName + " not found"); + } + } + + /** + * Returns the AFM for the given font. + * @param baseName base name of font + */ + public static FontMetrics getAFM(String baseName) + { + return STANDARD14_AFM_MAP.get(baseName); + } + + /** + * Returns true if the given font name a Standard 14 font. + * @param baseName base name of font + */ + public static boolean containsName(String baseName) + { + return STANDARD_14_NAMES.contains(baseName); + } + + /** + * Returns the set of Standard 14 font names, including additional names. + */ + public static Set<String> getNames() + { + return Collections.unmodifiableSet(STANDARD_14_NAMES); + } + + /** + * Returns the name of the actual font which the given font name maps to. + * @param baseName base name of font + */ + public static String getMappedFontName(String baseName) + { + return STANDARD_14_MAPPING.get(baseName); + } +} Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/font/TTFGlyph2D.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/font/TTFGlyph2D.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/font/TTFGlyph2D.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/font/TTFGlyph2D.java Thu Sep 25 03:35:24 2014 @@ -21,12 +21,9 @@ package org.apache.pdfbox.rendering.font import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; import java.io.IOException; -import java.util.Arrays; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.fontbox.ttf.GlyphData; @@ -34,7 +31,6 @@ import org.apache.fontbox.ttf.HeaderTabl import org.apache.fontbox.ttf.TrueTypeFont; import org.apache.pdfbox.pdmodel.font.PDCIDFontType2; import org.apache.pdfbox.pdmodel.font.PDFont; -import org.apache.pdfbox.pdmodel.font.PDSimpleFont; import org.apache.pdfbox.pdmodel.font.PDTrueTypeFont; import org.apache.pdfbox.pdmodel.font.PDType0Font; @@ -143,9 +139,8 @@ public class TTFGlyph2D implements Glyph GlyphData glyph = ttf.getGlyph().getGlyph(gid); - // workaround for Type0 "Standard 14" font handling, as Adobe has GID 0 as empty - // while Microsoft uses a rectangle, which we don't want to appear - if (gid == 0 && !font.isEmbedded() && PDSimpleFont.isStandard14(font.getName())) + // Acrobat only draws GID 0 for embedded or "Standard 14" fonts, see PDFBOX-2372 + if (gid == 0 && !font.isEmbedded() && !font.isStandard14()) { glyph = null; } Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/CIDType0DescriptorHelper.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/CIDType0DescriptorHelper.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/CIDType0DescriptorHelper.java (original) +++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/CIDType0DescriptorHelper.java Thu Sep 25 03:35:24 2014 @@ -39,7 +39,7 @@ import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.cos.COSStream; import org.apache.pdfbox.pdmodel.common.PDStream; import org.apache.pdfbox.pdmodel.font.PDFont; -import org.apache.pdfbox.pdmodel.font.PDFontDescriptorDictionary; +import org.apache.pdfbox.pdmodel.font.PDFontDescriptor; import org.apache.pdfbox.preflight.PreflightContext; import org.apache.pdfbox.preflight.ValidationResult; import org.apache.pdfbox.preflight.ValidationResult.ValidationError; @@ -56,7 +56,7 @@ public class CIDType0DescriptorHelper ex } @Override - public PDStream extractFontFile(PDFontDescriptorDictionary fontDescriptor) + public PDStream extractFontFile(PDFontDescriptor fontDescriptor) { PDStream ff3 = fontDescriptor.getFontFile3(); if (ff3 != null) @@ -96,12 +96,12 @@ public class CIDType0DescriptorHelper ex * * @param pfDescriptor */ - protected void checkCIDSet(PDFontDescriptorDictionary pfDescriptor) + protected void checkCIDSet(PDFontDescriptor pfDescriptor) { if (FontValidator.isSubSet(pfDescriptor.getFontName())) { COSDocument cosDocument = context.getDocument().getDocument(); - COSBase cidset = pfDescriptor.getCOSDictionary().getItem(COSName.getPDFName(FONT_DICTIONARY_KEY_CIDSET)); + COSBase cidset = pfDescriptor.getCOSObject().getItem(COSName.getPDFName(FONT_DICTIONARY_KEY_CIDSET)); if (cidset == null || !COSUtils.isStream(cidset, cosDocument)) { this.fContainer.push(new ValidationResult.ValidationError(ERROR_FONTS_CIDSET_MISSING_FOR_SUBSET, @@ -111,7 +111,7 @@ public class CIDType0DescriptorHelper ex } @Override - protected void processFontFile(PDFontDescriptorDictionary fontDescriptor, PDStream fontFile) + protected void processFontFile(PDFontDescriptor fontDescriptor, PDStream fontFile) { /* * try to load the font using the java.awt.font object. if the font is invalid, an exception will be thrown Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/CIDType2DescriptorHelper.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/CIDType2DescriptorHelper.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/CIDType2DescriptorHelper.java (original) +++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/CIDType2DescriptorHelper.java Thu Sep 25 03:35:24 2014 @@ -36,7 +36,7 @@ import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.cos.COSStream; import org.apache.pdfbox.pdmodel.common.PDStream; import org.apache.pdfbox.pdmodel.font.PDFont; -import org.apache.pdfbox.pdmodel.font.PDFontDescriptorDictionary; +import org.apache.pdfbox.pdmodel.font.PDFontDescriptor; import org.apache.pdfbox.preflight.PreflightContext; import org.apache.pdfbox.preflight.ValidationResult; import org.apache.pdfbox.preflight.ValidationResult.ValidationError; @@ -58,12 +58,12 @@ public class CIDType2DescriptorHelper ex * * @param pfDescriptor */ - protected void checkCIDSet(PDFontDescriptorDictionary pfDescriptor) + protected void checkCIDSet(PDFontDescriptor pfDescriptor) { if (FontValidator.isSubSet(pfDescriptor.getFontName())) { COSDocument cosDocument = context.getDocument().getDocument(); - COSBase cidset = pfDescriptor.getCOSDictionary().getItem(COSName.getPDFName(FONT_DICTIONARY_KEY_CIDSET)); + COSBase cidset = pfDescriptor.getCOSObject().getItem(COSName.getPDFName(FONT_DICTIONARY_KEY_CIDSET)); if (cidset == null || !COSUtils.isStream(cidset, cosDocument)) { this.fContainer.push(new ValidationResult.ValidationError(ERROR_FONTS_CIDSET_MISSING_FOR_SUBSET, @@ -73,7 +73,7 @@ public class CIDType2DescriptorHelper ex } @Override - public PDStream extractFontFile(PDFontDescriptorDictionary fontDescriptor) + public PDStream extractFontFile(PDFontDescriptor fontDescriptor) { PDStream ff2 = fontDescriptor.getFontFile2(); if (ff2 != null) @@ -94,7 +94,7 @@ public class CIDType2DescriptorHelper ex } @Override - protected void processFontFile(PDFontDescriptorDictionary fontDescriptor, PDStream fontFile) + protected void processFontFile(PDFontDescriptor fontDescriptor, PDStream fontFile) { /* * try to load the font using the java.awt.font object. if the font is invalid, an exception will be thrown Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/FontDescriptorHelper.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/FontDescriptorHelper.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/FontDescriptorHelper.java (original) +++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/FontDescriptorHelper.java Thu Sep 25 03:35:24 2014 @@ -51,7 +51,6 @@ import org.apache.pdfbox.pdmodel.common. import org.apache.pdfbox.pdmodel.common.PDStream; import org.apache.pdfbox.pdmodel.font.PDFont; import org.apache.pdfbox.pdmodel.font.PDFontDescriptor; -import org.apache.pdfbox.pdmodel.font.PDFontDescriptorDictionary; import org.apache.pdfbox.preflight.PreflightContext; import org.apache.pdfbox.preflight.ValidationResult.ValidationError; import org.apache.pdfbox.preflight.font.container.FontContainer; @@ -69,7 +68,7 @@ public abstract class FontDescriptorHelp protected PreflightContext context; protected PDFont font; - protected PDFontDescriptorDictionary fontDescriptor; + protected PDFontDescriptor fontDescriptor; public FontDescriptorHelper(PreflightContext context, PDFont font, T fontContainer) { @@ -83,11 +82,11 @@ public abstract class FontDescriptorHelp { PDFontDescriptor fd = this.font.getFontDescriptor(); // Only a PDFontDescriptorDictionary provides a way to embedded the font program. - if (fd != null && fd instanceof PDFontDescriptorDictionary) + if (fd != null) { - fontDescriptor = (PDFontDescriptorDictionary) fd; + fontDescriptor = fd; - if (checkMandatoryFields(fontDescriptor.getCOSDictionary())) + if (checkMandatoryFields(fontDescriptor.getCOSObject())) { if (hasOnlyOneFontFile(fontDescriptor)) { @@ -141,7 +140,7 @@ public abstract class FontDescriptorHelp return areFieldsPresent; } - public abstract PDStream extractFontFile(PDFontDescriptorDictionary fontDescriptor); + public abstract PDStream extractFontFile(PDFontDescriptor fontDescriptor); /** * Return true if the FontDescriptor has only one FontFile entry. @@ -149,7 +148,7 @@ public abstract class FontDescriptorHelp * @param fontDescriptor * @return */ - protected boolean hasOnlyOneFontFile(PDFontDescriptorDictionary fontDescriptor) + protected boolean hasOnlyOneFontFile(PDFontDescriptor fontDescriptor) { PDStream ff1 = fontDescriptor.getFontFile(); PDStream ff2 = fontDescriptor.getFontFile2(); @@ -157,7 +156,7 @@ public abstract class FontDescriptorHelp return (ff1 != null ^ ff2 != null ^ ff3 != null); } - protected boolean fontFileNotEmbedded(PDFontDescriptorDictionary fontDescriptor) + protected boolean fontFileNotEmbedded(PDFontDescriptor fontDescriptor) { PDStream ff1 = fontDescriptor.getFontFile(); PDStream ff2 = fontDescriptor.getFontFile2(); @@ -165,7 +164,7 @@ public abstract class FontDescriptorHelp return (ff1 == null && ff2 == null && ff3 == null); } - protected abstract void processFontFile(PDFontDescriptorDictionary fontDescriptor, PDStream fontFile); + protected abstract void processFontFile(PDFontDescriptor fontDescriptor, PDStream fontFile); /** * Type0, Type1 and TrueType FontValidator call this method to check the FontFile meta data. Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/TrueTypeDescriptorHelper.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/TrueTypeDescriptorHelper.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/TrueTypeDescriptorHelper.java (original) +++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/TrueTypeDescriptorHelper.java Thu Sep 25 03:35:24 2014 @@ -35,7 +35,7 @@ import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.cos.COSStream; import org.apache.pdfbox.pdmodel.common.PDStream; import org.apache.pdfbox.pdmodel.font.PDFont; -import org.apache.pdfbox.pdmodel.font.PDFontDescriptorDictionary; +import org.apache.pdfbox.pdmodel.font.PDFontDescriptor; import org.apache.pdfbox.preflight.PreflightContext; import org.apache.pdfbox.preflight.ValidationResult.ValidationError; import org.apache.pdfbox.preflight.font.container.TrueTypeContainer; @@ -48,7 +48,7 @@ public class TrueTypeDescriptorHelper ex super(context, font, fontContainer); } - public PDStream extractFontFile(PDFontDescriptorDictionary fontDescriptor) + public PDStream extractFontFile(PDFontDescriptor fontDescriptor) { PDStream fontFile = fontDescriptor.getFontFile2(); COSStream stream = (fontFile == null ? null : fontFile.getStream()); @@ -70,7 +70,7 @@ public class TrueTypeDescriptorHelper ex return fontFile; } - protected void processFontFile(PDFontDescriptorDictionary fontDescriptor, PDStream fontFile) + protected void processFontFile(PDFontDescriptor fontDescriptor, PDStream fontFile) { /* * Try to load the font using the TTFParser object. If the font is invalid, an exception will be thrown. Because Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/Type1DescriptorHelper.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/Type1DescriptorHelper.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/Type1DescriptorHelper.java (original) +++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/font/descriptor/Type1DescriptorHelper.java Thu Sep 25 03:35:24 2014 @@ -43,7 +43,7 @@ import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.cos.COSStream; import org.apache.pdfbox.pdmodel.common.PDStream; import org.apache.pdfbox.pdmodel.font.PDFont; -import org.apache.pdfbox.pdmodel.font.PDFontDescriptorDictionary; +import org.apache.pdfbox.pdmodel.font.PDFontDescriptor; import org.apache.pdfbox.pdmodel.font.PDSimpleFont; import org.apache.pdfbox.preflight.PreflightContext; import org.apache.pdfbox.preflight.ValidationResult.ValidationError; @@ -81,7 +81,7 @@ public class Type1DescriptorHelper exten } @Override - public PDStream extractFontFile(PDFontDescriptorDictionary fontDescriptor) + public PDStream extractFontFile(PDFontDescriptor fontDescriptor) { PDStream ff1 = fontDescriptor.getFontFile(); PDStream ff3 = fontDescriptor.getFontFile3(); @@ -118,7 +118,7 @@ public class Type1DescriptorHelper exten } @Override - protected void processFontFile(PDFontDescriptorDictionary fontDescriptor, PDStream fontFile) + protected void processFontFile(PDFontDescriptor fontDescriptor, PDStream fontFile) { if (isFontFile1) { @@ -137,7 +137,7 @@ public class Type1DescriptorHelper exten * @param fontDescriptor * @param fontFile */ - protected void processFontFile1(PDFontDescriptorDictionary fontDescriptor, PDStream fontFile) + protected void processFontFile1(PDFontDescriptor fontDescriptor, PDStream fontFile) { ByteArrayInputStream bis = null; try @@ -178,7 +178,7 @@ public class Type1DescriptorHelper exten * @return * @throws ValidationException */ - protected void processFontFile3(PDFontDescriptorDictionary fontDescriptor, PDStream fontFile) + protected void processFontFile3(PDFontDescriptor fontDescriptor, PDStream fontFile) { try { Modified: pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/TextToPDF.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/TextToPDF.java?rev=1627450&r1=1627449&r2=1627450&view=diff ============================================================================== --- pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/TextToPDF.java (original) +++ pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/TextToPDF.java Thu Sep 25 03:35:24 2014 @@ -79,7 +79,7 @@ public class TextToPDF { final int margin = 40; - float height = font.getFontDescriptor().getFontBoundingBox().getHeight()/1000; + float height = font.getBoundingBox().getHeight() / 1000; //calculate font height and increase by 5 percent. height = height*fontSize*1.05f;