You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2013/09/23 18:18:25 UTC
svn commit: r1525637 - in
/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox:
pdfviewer/PageDrawer.java pdfviewer/font/TTFGlyph2D.java
pdmodel/font/PDCIDFontType2Font.java
Author: lehmi
Date: Mon Sep 23 16:18:25 2013
New Revision: 1525637
URL: http://svn.apache.org/r1525637
Log:
PDFBOX-1718: use a given CIDToGID mapping, rearranged some code
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/TTFGlyph2D.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Font.java
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java?rev=1525637&r1=1525636&r2=1525637&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java Mon Sep 23 16:18:25 2013
@@ -113,8 +113,8 @@ public class PageDrawer extends PDFStrea
private GeneralPath linePath = new GeneralPath();
- private HashMap<PDFont, Glyph2D> fontGlyph2D = new HashMap<PDFont, Glyph2D>();
- private HashMap<PDFont, Font> awtFonts = new HashMap<PDFont, Font>();
+ private Map<PDFont, Glyph2D> fontGlyph2D = new HashMap<PDFont, Glyph2D>();
+ private Map<PDFont, Font> awtFonts = new HashMap<PDFont, Font>();
/**
* Default constructor, loads properties from file.
@@ -299,13 +299,13 @@ public class PageDrawer extends PDFStrea
if (glyph2D != null)
{
// Let PDFBox render the font if supported
- drawGlyph2D(glyph2D, text.getCodePoints(), graphics, at, x, y);
+ drawGlyph2D(glyph2D, text.getCodePoints(), at, x, y);
}
else
{
// Use AWT to render the font (Type1 fonts, standard14 fonts, if the embedded font is substituted)
// TODO to be removed in the long run?
- drawString((PDSimpleFont) font, text.getCharacter(), text.getCodePoints(), graphics, at, x, y);
+ drawString((PDSimpleFont) font, text.getCharacter(), at, x, y);
}
}
}
@@ -320,13 +320,12 @@ public class PageDrawer extends PDFStrea
*
* @param glyph2D the Glyph2D implementation provided a GeneralPath for each glyph
* @param codePoints the string to be rendered
- * @param graphics the graphics object to be used for rendering
* @param at the transformation
* @param x the x coordinate of the text
* @param y the y coordinate of the text
* @throws IOException if something went wrong
*/
- private void drawGlyph2D(Glyph2D glyph2D, int[] codePoints, Graphics graphics, AffineTransform at, float x, float y)
+ private void drawGlyph2D(Glyph2D glyph2D, int[] codePoints, AffineTransform at, float x, float y)
throws IOException
{
Graphics2D g2d = (Graphics2D) graphics;
@@ -412,7 +411,6 @@ public class PageDrawer extends PDFStrea
*
* @param font the font to be used to draw the string
* @param string The string to draw.
- * @param codePoints The codePoints of the given string.
* @param g The graphics to draw onto.
* @param at The transformation matrix with all information for scaling and shearing of the font.
* @param x The x coordinate to draw at.
@@ -420,14 +418,13 @@ public class PageDrawer extends PDFStrea
*
* @throws IOException If there is an error drawing the specific string.
*/
- private void drawString(PDSimpleFont font, String string, int[] codePoints, Graphics g, AffineTransform at,
- float x, float y) throws IOException
+ private void drawString(PDSimpleFont font, String string, AffineTransform at, float x, float y) throws IOException
{
Font awtFont = createAWTFont(font);
FontRenderContext frc = new FontRenderContext(new AffineTransform(), true, true);
GlyphVector glyphs = awtFont.createGlyphVector(frc, string);
- Graphics2D g2d = (Graphics2D) g;
+ Graphics2D g2d = (Graphics2D) graphics;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
writeFont(g2d, at, x, y, glyphs);
}
@@ -486,7 +483,7 @@ public class PageDrawer extends PDFStrea
{
PDType1Font type1Font = (PDType1Font) font;
PDFontDescriptor fd = type1Font.getFontDescriptor();
- if (fd != null && fd instanceof PDFontDescriptorDictionary)
+ if (fd instanceof PDFontDescriptorDictionary)
{
PDFontDescriptorDictionary fdDictionary = (PDFontDescriptorDictionary) fd;
if (fdDictionary.getFontFile() != null)
@@ -570,7 +567,7 @@ public class PageDrawer extends PDFStrea
TrueTypeFont ttf = ttfFont.getTTFFont();
if (ttf != null)
{
- glyph2D = new TTFGlyph2D(ttf, font.getBaseFont(), ttfFont.isSymbolicFont(), font.getFontEncoding());
+ glyph2D = new TTFGlyph2D(ttf, font);
}
}
else if (font instanceof PDType1Font)
@@ -598,16 +595,7 @@ public class PageDrawer extends PDFStrea
TrueTypeFont ttf = cidType2Font.getTTFFont();
if (ttf != null)
{
- if (cidType2Font.hasCIDToGIDMap())
- {
- glyph2D = new TTFGlyph2D(ttf, font.getBaseFont(), cidType2Font.isSymbolicFont(),
- font.getFontEncoding(), cidType2Font.getCID2GID());
- }
- else
- {
- glyph2D = new TTFGlyph2D(ttf, font.getBaseFont(), cidType2Font.isSymbolicFont(),
- font.getFontEncoding(), type0Font.getCMap());
- }
+ glyph2D = new TTFGlyph2D(ttf, font, cidType2Font);
}
}
else if (type0Font.getDescendantFont() instanceof PDCIDFontType0Font)
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/TTFGlyph2D.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/TTFGlyph2D.java?rev=1525637&r1=1525636&r2=1525637&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/TTFGlyph2D.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/TTFGlyph2D.java Mon Sep 23 16:18:25 2013
@@ -23,6 +23,7 @@ import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.io.IOException;
import java.util.HashMap;
+import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -36,6 +37,8 @@ import org.apache.fontbox.ttf.HeaderTabl
import org.apache.fontbox.ttf.TrueTypeFont;
import org.apache.pdfbox.encoding.Encoding;
import org.apache.pdfbox.encoding.MacOSRomanEncoding;
+import org.apache.pdfbox.pdmodel.font.PDCIDFontType2Font;
+import org.apache.pdfbox.pdmodel.font.PDFont;
/**
* This class provides a glyph to GeneralPath conversion for true type fonts.
@@ -51,91 +54,73 @@ public class TTFGlyph2D implements Glyph
*/
private static final Log LOG = LogFactory.getLog(TTFGlyph2D.class);
+ /**
+ * Default scaling value.
+ */
+ private static final float DEFAULT_SCALING = 0.001f;
+
+ /**
+ * Start of coderanges.
+ */
+ private static final int START_RANGE_F000 = 0xF000;
+ private static final int START_RANGE_F100 = 0xF100;
+ private static final int START_RANGE_F200 = 0xF200;
+
private TrueTypeFont font;
+ private PDCIDFontType2Font descendantFont;
private String name;
- private float scale = 0.001f;
+ private float scale;
private CMAPEncodingEntry cmapWinUnicode = null;
private CMAPEncodingEntry cmapWinSymbol = null;
private CMAPEncodingEntry cmapMacintoshSymbol = null;
private boolean isSymbol = false;
- private HashMap<Integer, GeneralPath> glyphs = new HashMap<Integer, GeneralPath>();
+ private Map<Integer, GeneralPath> glyphs = new HashMap<Integer, GeneralPath>();
private Encoding fontEncoding = null;
private CMap fontCMap = null;
+ private boolean hasIdentityCIDMapping = false;
+ private boolean hasCID2GIDMapping = false;
private boolean hasTwoByteMappings = false;
- private int[] cid2gid = null;
-
- /**
- * Constructor.
- *
- * @param trueTypeFont the true type font containing the glyphs
- * @param fontname the name of the given font
- * @param symbolFont indicates if the font is a symbolic font
- * @param encoding the encoding of the font
- *
- */
- public TTFGlyph2D(TrueTypeFont trueTypeFont, String fontname, boolean symbolFont, Encoding encoding)
- {
- this(trueTypeFont, fontname, symbolFont, encoding, null, null);
- }
/**
* Constructor.
*
* @param trueTypeFont the true type font containing the glyphs
- * @param fontname the name of the given font
- * @param symbolFont indicates if the font is a symbolic font
- * @param encoding the encoding of the font
- * @param cid2gidMapping an optional CID2GID mapping
+ * @param pdFont the given PDFont
*/
- public TTFGlyph2D(TrueTypeFont trueTypeFont, String fontname, boolean symbolFont, Encoding encoding,
- int[] cid2gidMapping)
+ public TTFGlyph2D(TrueTypeFont trueTypeFont, PDFont pdFont)
{
- this(trueTypeFont, fontname, symbolFont, encoding, cid2gidMapping, null);
+ this(trueTypeFont, pdFont, null);
}
/**
* Constructor.
*
* @param trueTypeFont the true type font containing the glyphs
- * @param fontname the name of the given font
- * @param symbolFont indicates if the font is a symbolic font
- * @param encoding the encoding of the font
- * @param cMap an optional CMap
+ * @param pdFont the given PDFont
+ * @param descFont the descendant font of a Type0Font
*/
- public TTFGlyph2D(TrueTypeFont trueTypeFont, String fontname, boolean symbolFont, Encoding encoding, CMap cMap)
- {
- this(trueTypeFont, fontname, symbolFont, encoding, null, cMap);
- }
-
- /**
- * Constructor.
- *
- * @param trueTypeFont the true type font containing the glyphs
- * @param fontname the name of the given font
- * @param symbolFont indicates if the font is a symbolic font
- * @param encoding the encoding of the font
- * @param cid2gidMapping an optional CID2GID mapping
- * @param cMap an optional CMap
- */
- public TTFGlyph2D(TrueTypeFont trueTypeFont, String fontname, boolean symbolFont, Encoding encoding,
- int[] cid2gidMapping, CMap cMap)
+ public TTFGlyph2D(TrueTypeFont trueTypeFont, PDFont pdFont, PDCIDFontType2Font descFont)
{
font = trueTypeFont;
- isSymbol = symbolFont;
- name = fontname;
- fontEncoding = encoding;
- cid2gid = cid2gidMapping;
- fontCMap = cMap;
- if (fontCMap != null)
- {
- hasTwoByteMappings = fontCMap.hasTwoByteMappings();
- }
// get units per em, which is used as scaling factor
HeaderTable header = font.getHeader();
if (header != null)
{
scale = 1f / header.getUnitsPerEm();
}
+ else
+ {
+ scale = DEFAULT_SCALING;
+ }
+ extractCMaps();
+ extractFontSpecifics(pdFont, descFont);
+ }
+
+ /**
+ * extract all useful CMaps.
+ */
+ private void extractCMaps()
+ {
CMAPTable cmapTable = font.getCMAP();
if (cmapTable != null)
{
@@ -163,6 +148,31 @@ public class TTFGlyph2D implements Glyph
}
}
}
+
+ }
+
+ /**
+ * Extract all font specific information.
+ *
+ * @param pdFont the given PDFont
+ */
+ private void extractFontSpecifics(PDFont pdFont, PDCIDFontType2Font descFont)
+ {
+ isSymbol = pdFont.isSymbolicFont();
+ name = pdFont.getBaseFont();
+ fontEncoding = pdFont.getFontEncoding();
+ if (descFont != null)
+ {
+ descendantFont = descFont;
+ hasIdentityCIDMapping = descendantFont.hasIdentityCIDToGIDMap();
+ hasCID2GIDMapping = descendantFont.hasCIDToGIDMap();
+ fontCMap = pdFont.getCMap();
+ if (fontCMap != null)
+ {
+ hasTwoByteMappings = fontCMap.hasTwoByteMappings();
+ }
+
+ }
}
/**
@@ -222,6 +232,17 @@ public class TTFGlyph2D implements Glyph
*/
private int getGlyphcode(int code)
{
+ if (hasIdentityCIDMapping)
+ {
+ // identity mapping
+ return code;
+ }
+ if (hasCID2GIDMapping)
+ {
+ // use the provided CID2GID mapping
+ return descendantFont.mapCIDToGID(code);
+ }
+
int result = 0;
if (fontEncoding != null && !isSymbol)
{
@@ -235,14 +256,14 @@ public class TTFGlyph2D implements Glyph
String unicode = Encoding.getCharacterForName(charactername);
if (unicode != null)
{
- code = unicode.codePointAt(0);
+ result = unicode.codePointAt(0);
}
- result = cmapWinUnicode.getGlyphId(code);
+ result = cmapWinUnicode.getGlyphId(result);
}
else if (cmapMacintoshSymbol != null)
{
- code = MacOSRomanEncoding.INSTANCE.getCode(charactername);
- result = cmapMacintoshSymbol.getGlyphId(code);
+ result = MacOSRomanEncoding.INSTANCE.getCode(charactername);
+ result = cmapMacintoshSymbol.getGlyphId(result);
}
}
}
@@ -264,17 +285,17 @@ public class TTFGlyph2D implements Glyph
if (result == 0)
{
// F000 - F0FF
- result = cmapWinSymbol.getGlyphId(code + 0xF000);
+ result = cmapWinSymbol.getGlyphId(code + START_RANGE_F000);
}
if (result == 0)
{
// F100 - F1FF
- result = cmapWinSymbol.getGlyphId(code + 0xF100);
+ result = cmapWinSymbol.getGlyphId(code + START_RANGE_F100);
}
if (result == 0)
{
// F200 - F2FF
- result = cmapWinSymbol.getGlyphId(code + 0xF200);
+ result = cmapWinSymbol.getGlyphId(code + START_RANGE_F200);
}
}
}
@@ -299,21 +320,17 @@ public class TTFGlyph2D implements Glyph
{
return getPathForGlyphId(glyphId);
}
+ glyphId = code;
// there isn't any mapping, but probably an optional CMap
if (fontCMap != null)
{
String string = fontCMap.lookup(code, hasTwoByteMappings ? 2 : 1);
if (string != null)
{
- code = string.codePointAt(0);
+ glyphId = string.codePointAt(0);
}
}
- // there isn't any mapping, but probably an optional CID2GID mapping
- if (cid2gid != null && code <= cid2gid.length)
- {
- code = cid2gid[code];
- }
- return getPathForGlyphId(code);
+ return getPathForGlyphId(glyphId);
}
/**
@@ -429,7 +446,7 @@ public class TTFGlyph2D implements Glyph
lastCtrlPoint = point;
continue;
}
- System.err.println("Unknown glyph command!!");
+ LOG.error("Unknown glyph command!!");
break;
}
return path;
@@ -447,10 +464,10 @@ public class TTFGlyph2D implements Glyph
private class Point
{
- public int x = 0;
- public int y = 0;
- public boolean onCurve = true;
- public boolean endOfContour = false;
+ private int x = 0;
+ private int y = 0;
+ private boolean onCurve = true;
+ private boolean endOfContour = false;
public Point(int xValue, int yValue, boolean onCurveValue, boolean endOfContourValue)
{
@@ -478,12 +495,13 @@ public class TTFGlyph2D implements Glyph
@Override
public void dispose()
{
- cid2gid = null;
cmapMacintoshSymbol = null;
cmapWinSymbol = null;
cmapWinUnicode = null;
font = null;
+ descendantFont = null;
fontCMap = null;
+ fontEncoding = null;
if (glyphs != null)
{
glyphs.clear();
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Font.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Font.java?rev=1525637&r1=1525636&r2=1525637&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Font.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Font.java Mon Sep 23 16:18:25 2013
@@ -44,6 +44,7 @@ public class PDCIDFontType2Font extends
private static final Log LOG = LogFactory.getLog(PDCIDFontType2Font.class);
private Boolean hasCIDToGIDMap = null;
+ private Boolean hasIdentityCIDToGIDMap = null;
private int[] cid2gid = null;
/**
@@ -116,6 +117,28 @@ public class PDCIDFontType2Font extends
}
/**
+ * Indicates if this font has an identity CIDToGIDMap.
+ *
+ * @return returns true if the font has an identity CIDToGIDMap.
+ */
+ public boolean hasIdentityCIDToGIDMap()
+ {
+ if (hasIdentityCIDToGIDMap == null)
+ {
+ COSBase map = font.getDictionaryObject(COSName.CID_TO_GID_MAP);
+ if (map != null && map instanceof COSName)
+ {
+ hasIdentityCIDToGIDMap = Boolean.TRUE;
+ }
+ else
+ {
+ hasIdentityCIDToGIDMap = Boolean.FALSE;
+ }
+ }
+ return hasIdentityCIDToGIDMap.booleanValue();
+ }
+
+ /**
* Maps the given CID to the correspondent GID.
*
* @param cid the given CID