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/12/13 00:20:51 UTC
svn commit: r1645090 - in /pdfbox/trunk:
fontbox/src/main/java/org/apache/fontbox/ttf/
pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/
Author: jahewson
Date: Fri Dec 12 23:20:51 2014
New Revision: 1645090
URL: http://svn.apache.org/r1645090
Log:
PDFBOX-1372: Handle monospace width for last hmtx entry
Modified:
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/HorizontalMetricsTable.java
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeFont.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFontEmbedder.java
Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/HorizontalMetricsTable.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/HorizontalMetricsTable.java?rev=1645090&r1=1645089&r2=1645090&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/HorizontalMetricsTable.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/HorizontalMetricsTable.java Fri Dec 12 23:20:51 2014
@@ -33,6 +33,7 @@ public class HorizontalMetricsTable exte
private int[] advanceWidth;
private short[] leftSideBearing;
private short[] nonHorizontalLeftSideBearing;
+ private int numHMetrics;
/**
* This will read the required data from the stream.
@@ -44,7 +45,7 @@ public class HorizontalMetricsTable exte
public void read(TrueTypeFont ttf, TTFDataStream data) throws IOException
{
HorizontalHeaderTable hHeader = ttf.getHorizontalHeader();
- int numHMetrics = hHeader.getNumberOfHMetrics();
+ numHMetrics = hHeader.getNumberOfHMetrics();
int numGlyphs = ttf.getNumberOfGlyphs();
int bytesRead = 0;
@@ -80,18 +81,23 @@ public class HorizontalMetricsTable exte
initialized = true;
}
+
/**
- * @return Returns the advanceWidth.
- */
- public int[] getAdvanceWidth()
- {
- return advanceWidth;
- }
- /**
- * @param advanceWidthValue The advanceWidth to set.
+ * Returns the advance width for the given GID.
+ *
+ * @param gid GID
*/
- public void setAdvanceWidth(int[] advanceWidthValue)
+ public int getAdvanceWidth(int gid)
{
- advanceWidth = advanceWidthValue;
+ if (gid < numHMetrics)
+ {
+ return advanceWidth[gid];
+ }
+ else
+ {
+ // monospaced fonts may not have a width for every glyph
+ // the last one is for subsequent glyphs
+ return advanceWidth[advanceWidth.length -1];
+ }
}
}
Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeFont.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeFont.java?rev=1645090&r1=1645089&r2=1645090&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeFont.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeFont.java Fri Dec 12 23:20:51 2014
@@ -37,7 +37,6 @@ public class TrueTypeFont implements Typ
private float version;
private int numberOfGlyphs = -1;
private int unitsPerEm = -1;
- private int[] advanceWidths = null;
protected Map<String,TTFTable> tables = new HashMap<String,TTFTable>();
private TTFDataStream data;
private Map<String, Integer> postScriptNames;
@@ -342,28 +341,15 @@ public class TrueTypeFont implements Typ
*/
public int getAdvanceWidth(int gid) throws IOException
{
- if (advanceWidths == null)
+ HorizontalMetricsTable hmtx = getHorizontalMetrics();
+ if (hmtx != null)
{
- HorizontalMetricsTable hmtx = getHorizontalMetrics();
- if (hmtx != null)
- {
- advanceWidths = hmtx.getAdvanceWidth();
- }
- else
- {
- // this should never happen
- advanceWidths = new int[]{250};
- }
- }
- if (advanceWidths.length > gid)
- {
- return advanceWidths[gid];
+ return hmtx.getAdvanceWidth(gid);
}
else
{
- // monospaced fonts may not have a width for every glyph
- // the last one is for subsequent glyphs
- return advanceWidths[advanceWidths.length-1];
+ // this should never happen
+ return 250;
}
}
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java?rev=1645090&r1=1645089&r2=1645090&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java Fri Dec 12 23:20:51 2014
@@ -141,12 +141,12 @@ final class PDCIDFontType2Embedder exten
cidFont.setItem(COSName.FONT_DESC, fontDescriptor.getCOSObject());
// W - widths
- int[] subwidths = ttf.getHorizontalMetrics().getAdvanceWidth();
- int[] gidwidths = new int[subwidths.length*2];
- for (int i = 0; i < subwidths.length; i++)
+ int numGlyphs = ttf.getNumberOfGlyphs();
+ int[] gidwidths = new int[numGlyphs * 2];
+ for (int i = 0; i < numGlyphs; i++)
{
gidwidths[i * 2] = i;
- gidwidths[i * 2 + 1] = subwidths[i];
+ gidwidths[i * 2 + 1] = ttf.getHorizontalMetrics().getAdvanceWidth(i);
}
cidFont.setItem(COSName.W, getWidths(gidwidths));
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=1645090&r1=1645089&r2=1645090&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 Fri Dec 12 23:20:51 2014
@@ -75,54 +75,33 @@ final class PDTrueTypeFontEmbedder exten
private void setWidths(COSDictionary font, GlyphList glyphList) throws IOException
{
float scaling = 1000f / ttf.getHeader().getUnitsPerEm();
+ HorizontalMetricsTable hmtx = ttf.getHorizontalMetrics();
- Map<Integer, String> codeToName = this.getFontEncoding().getCodeToNameMap();
+ Map<Integer, String> codeToName = getFontEncoding().getCodeToNameMap();
int firstChar = Collections.min(codeToName.keySet());
int lastChar = Collections.max(codeToName.keySet());
- HorizontalMetricsTable hMet = ttf.getHorizontalMetrics();
- int[] widthValues = hMet.getAdvanceWidth();
-
- // some monospaced fonts provide only one value for the width
- // instead of an array containing the same value for every glyph id
- boolean isMonospaced = ttf.getHorizontalHeader().getNumberOfHMetrics() == 1;
-
- int numWidths = lastChar - firstChar + 1;
- List<Integer> widths = new ArrayList<Integer>(numWidths);
-
- // use the first width as default
- // proportional fonts -> width of the .notdef character
- // monospaced-fonts -> the first width
- int defaultWidth = Math.round(widthValues[0] * scaling);
- for (int i = 0; i < numWidths; i++)
+ List<Integer> widths = new ArrayList<Integer>(lastChar - firstChar + 1);
+ for (int i = 0; i < lastChar - firstChar + 1; i++)
{
- widths.add(defaultWidth);
+ widths.add(0);
}
// a character code is mapped to a glyph name via the provided font encoding
// afterwards, the glyph name is translated to a glyph ID.
- for (Map.Entry<Integer, String> e : codeToName.entrySet())
+ for (Map.Entry<Integer, String> entry : codeToName.entrySet())
{
- String name = e.getValue();
- // pdf code to unicode by glyph list.
- if (!name.equals(".notdef"))
+ int code = entry.getKey();
+ String name = entry.getValue();
+
+ if (code >= firstChar && code <= lastChar)
{
- String c = glyphList.toUnicode(name);
- int charCode = c.codePointAt(0);
+ String uni = glyphList.toUnicode(name);
+ int charCode = uni.codePointAt(0);
int gid = cmap.getGlyphId(charCode);
- if (gid != 0)
- {
- if (isMonospaced)
- {
- widths.set(e.getKey() - firstChar, defaultWidth);
- }
- else
- {
- widths.set(e.getKey() - firstChar,
- Math.round(widthValues[gid] * scaling));
- }
- }
+ widths.set(entry.getKey() - firstChar,
+ Math.round(hmtx.getAdvanceWidth(gid) * scaling));
}
}