You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ti...@apache.org on 2016/07/27 16:43:48 UTC
svn commit: r1754315 - in
/pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane:
FontEncodingPaneController.java FontEncodingView.java SimpleFont.java
Type0Font.java Type3Font.java
Author: tilman
Date: Wed Jul 27 16:43:48 2016
New Revision: 1754315
URL: http://svn.apache.org/viewvc?rev=1754315&view=rev
Log:
PDFBOX-2941: Show all CID fonts with glyphs; use vertical bounds for all glyphs; copy old SimpleFont pane for type3 fonts
Added:
pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/Type3Font.java (with props)
Modified:
pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingPaneController.java
pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingView.java
pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/SimpleFont.java
pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/Type0Font.java
Modified: pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingPaneController.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingPaneController.java?rev=1754315&r1=1754314&r2=1754315&view=diff
==============================================================================
--- pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingPaneController.java (original)
+++ pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingPaneController.java Wed Jul 27 16:43:48 2016
@@ -16,19 +16,47 @@
package org.apache.pdfbox.debugger.fontencodingpane;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Rectangle2D;
import java.io.IOException;
import javax.swing.JPanel;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDResources;
-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.PDType0Font;
+import org.apache.pdfbox.pdmodel.font.PDType3Font;
-interface FontPane
+abstract class FontPane
{
- JPanel getPanel();
+ abstract JPanel getPanel();
+
+ /**
+ * Calculate vertical bounds common to all rendered glyphs.
+ *
+ * @param tableData
+ * @param glyphIndex the table index that has glyphs.
+ * @return an array with two elements: min lower bound (but max 0), and max upper bound (but min
+ * 0).
+ */
+ double[] getYBounds(Object[][] tableData, int glyphIndex)
+ {
+ double minY = 0;
+ double maxY = 0;
+ for (int i = 0; i < tableData.length; ++i)
+ {
+ GeneralPath path = (GeneralPath) tableData[i][glyphIndex];
+ Rectangle2D bounds2D = path.getBounds2D();
+ if (bounds2D.isEmpty())
+ {
+ continue;
+ }
+ minY = Math.min(minY, bounds2D.getMinY());
+ maxY = Math.max(maxY, bounds2D.getMaxY());
+ }
+ return new double[]{minY, maxY};
+ }
}
/**
@@ -52,14 +80,17 @@ public class FontEncodingPaneController
try
{
PDFont font = resources.getFont(fontName);
- if (font instanceof PDSimpleFont)
+ if (font instanceof PDType3Font)
+ {
+ fontPane = new Type3Font((PDType3Font) font);
+ }
+ else if (font instanceof PDSimpleFont)
{
fontPane = new SimpleFont((PDSimpleFont) font);
}
- else if (font instanceof PDType0Font
- && ((PDType0Font) font).getDescendantFont() instanceof PDCIDFontType2)
+ else if (font instanceof PDType0Font)
{
- fontPane = new Type0Font((PDCIDFontType2) ((PDType0Font) font).getDescendantFont(), font);
+ fontPane = new Type0Font(((PDType0Font) font).getDescendantFont(), (PDType0Font) font);
}
}
catch (IOException e)
Modified: pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingView.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingView.java?rev=1754315&r1=1754314&r2=1754315&view=diff
==============================================================================
--- pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingView.java (original)
+++ pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingView.java Wed Jul 27 16:43:48 2016
@@ -25,7 +25,6 @@ import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.awt.RenderingHints;
-import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
@@ -41,6 +40,7 @@ import javax.swing.table.TableCellRender
/**
* @author Khyrul Bashar
+ * @author Tilman Hausherr
* A class that creates the UI for font encoding pane.
*/
class FontEncodingView
@@ -53,10 +53,11 @@ class FontEncodingView
* @param headerAttributes Map<String, String> instance which contains info for showing in header
* panel. Here keys will be info type.
* @param columnNames String array containing the columns name.
+ * @param yBounds min low and max high bound of all glyphs.
*/
- FontEncodingView(Object[][] tableData, Map<String, String> headerAttributes, String[] columnNames)
+ FontEncodingView(Object[][] tableData, Map<String, String> headerAttributes, String[] columnNames, double[] yBounds)
{
- createView(getHeaderPanel(headerAttributes), getTable(tableData, columnNames));
+ createView(getHeaderPanel(headerAttributes), getTable(tableData, columnNames, yBounds));
}
private void createView(JPanel headerPanel, JTable table)
@@ -86,11 +87,11 @@ class FontEncodingView
panel.add(scrollPane, gbc);
}
- private JTable getTable(Object[][] tableData, String[] columnNames)
+ private JTable getTable(Object[][] tableData, String[] columnNames, double[] yBounds)
{
JTable table = new JTable(tableData, columnNames);
table.setRowHeight(40);
- table.setDefaultRenderer(Object.class, new GlyphCellRenderer());
+ table.setDefaultRenderer(Object.class, new GlyphCellRenderer(yBounds));
return table;
}
@@ -103,7 +104,6 @@ class FontEncodingView
Iterator<String> keys = attributes.keySet().iterator();
int row = 0;
while (keys.hasNext())
-
{
String key = keys.next();
JLabel encodingNameLabel = new JLabel(key + ": " + attributes.get(key));
@@ -116,7 +116,6 @@ class FontEncodingView
gbc.anchor = GridBagConstraints.LINE_START;
headerPanel.add(encodingNameLabel, gbc);
-
}
}
return headerPanel;
@@ -129,6 +128,12 @@ class FontEncodingView
private static final class GlyphCellRenderer implements TableCellRenderer
{
+ private final double[] yBounds;
+
+ private GlyphCellRenderer(double[] yBounds)
+ {
+ this.yBounds = yBounds;
+ }
@Override
public Component getTableCellRendererComponent(JTable jTable, Object o, boolean b, boolean b1, int row, int col)
@@ -147,8 +152,6 @@ class FontEncodingView
Rectangle cellRect = jTable.getCellRect(row, col, false);
BufferedImage bim = renderGlyph(path, bounds2D, cellRect);
return new JLabel(new ImageIcon(bim));
-
- //TODO possible improvement? render all glyphs with the same scale in the same bounding box
}
if (o != null)
{
@@ -166,23 +169,26 @@ class FontEncodingView
private BufferedImage renderGlyph(GeneralPath path, Rectangle2D bounds2D, Rectangle cellRect)
{
- path.transform(AffineTransform.getTranslateInstance(-bounds2D.getMinX(), -bounds2D.getMinY()));
- double scaleX = bounds2D.getWidth() / cellRect.getWidth();
- double scaleY = bounds2D.getHeight() / cellRect.getHeight();
- double scale = 1 / Math.ceil(Math.max(scaleX, scaleY)) / 2;
BufferedImage bim = new BufferedImage((int) cellRect.getWidth(), (int) cellRect.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g = (Graphics2D) bim.getGraphics();
g.setBackground(Color.white);
g.clearRect(0, 0, bim.getWidth(), bim.getHeight());
+ double scale = 1 / ((yBounds[1] - yBounds[0]) / cellRect.getHeight());
+
// flip
g.scale(1, -1);
g.translate(0, -bim.getHeight());
- // center
- g.translate((cellRect.getWidth() - bounds2D.getWidth() * scale) / 2, cellRect.getHeight() / 4);
+ // horizontal center
+ g.translate((cellRect.getWidth() - bounds2D.getWidth() * scale) / 2, 0);
+ // scale from the glyph to the cell
g.scale(scale, scale);
+
+ // Adjust for negative y min bound
+ g.translate(0, -yBounds[0]);
+
g.setColor(Color.black);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
Modified: pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/SimpleFont.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/SimpleFont.java?rev=1754315&r1=1754314&r2=1754315&view=diff
==============================================================================
--- pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/SimpleFont.java (original)
+++ pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/SimpleFont.java Wed Jul 27 16:43:48 2016
@@ -26,7 +26,7 @@ import org.apache.pdfbox.pdmodel.font.PD
* @author Khyrul Bashar
* A class that shows the glyph table along with unicode characters for SimpleFont.
*/
-class SimpleFont implements FontPane
+class SimpleFont extends FontPane
{
public static final String NO_GLYPH = "No glyph";
private int totalAvailableGlyph = 0;
@@ -40,13 +40,16 @@ class SimpleFont implements FontPane
SimpleFont(PDSimpleFont font) throws IOException
{
Object[][] tableData = getGlyphs(font);
+
+ double[] yBounds = getYBounds(tableData, 3);
Map<String, String> attributes = new LinkedHashMap<String, String>();
attributes.put("Encoding", getEncodingName(font));
attributes.put("Font", font.getName());
attributes.put("Glyph count", Integer.toString(totalAvailableGlyph));
- view = new FontEncodingView(tableData, attributes, new String[] {"Code", "Glyph Name","Unicode Character","Glyph"});
+ view = new FontEncodingView(tableData, attributes,
+ new String[] {"Code", "Glyph Name", "Unicode Character", "Glyph"}, yBounds);
}
private Object[][] getGlyphs(PDSimpleFont font) throws IOException
@@ -74,7 +77,6 @@ class SimpleFont implements FontPane
return glyphs;
}
-
private String getEncodingName(PDSimpleFont font)
{
return font.getEncoding().getClass().getSimpleName();
Modified: pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/Type0Font.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/Type0Font.java?rev=1754315&r1=1754314&r2=1754315&view=diff
==============================================================================
--- pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/Type0Font.java (original)
+++ pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/Type0Font.java Wed Jul 27 16:43:48 2016
@@ -17,6 +17,7 @@
package org.apache.pdfbox.debugger.fontencodingpane;
import java.awt.Dimension;
+import java.awt.geom.GeneralPath;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedHashMap;
@@ -27,25 +28,28 @@ import org.apache.pdfbox.cos.COSDictiona
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSStream;
import org.apache.pdfbox.io.IOUtils;
-import org.apache.pdfbox.pdmodel.font.PDCIDFontType2;
+import org.apache.pdfbox.pdmodel.font.PDCIDFont;
import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.pdmodel.font.PDType0Font;
/**
* @author Khyrul Bashar
* A class that shows the CIDToGID table along with unicode characters for Type0Fonts when descendent
* font is of type PDCIDFontType2.
*/
-class Type0Font implements FontPane
+class Type0Font extends FontPane
{
- private FontEncodingView view;
-
+ private final FontEncodingView view;
+ public static final String NO_GLYPH = "No glyph";
+ private int totalAvailableGlyph = 0;
+
/**
* Constructor.
* @param descendantFont PDCIDFontType2 instance.
* @param parentFont PDFont instance.
* @throws IOException If fails to parse cidtogid map.
*/
- Type0Font(PDCIDFontType2 descendantFont, PDFont parentFont) throws IOException
+ Type0Font(PDCIDFont descendantFont, PDType0Font parentFont) throws IOException
{
Object[][] cidtogid = readCIDToGIDMap(descendantFont, parentFont);
if (cidtogid != null)
@@ -54,11 +58,55 @@ class Type0Font implements FontPane
attributes.put("Font", descendantFont.getName());
attributes.put("CID count", Integer.toString(cidtogid.length));
- view = new FontEncodingView(cidtogid, attributes, new String[]{"CID", "GID", "Unicode Character"});
+ view = new FontEncodingView(cidtogid, attributes,
+ new String[]{"CID", "GID", "Unicode Character", "Glyph"}, getYBounds(cidtogid, 3));
+ }
+ else
+ {
+ Object[][] tab = readMap(descendantFont, parentFont);
+ Map<String, String> attributes = new LinkedHashMap<String, String>();
+ attributes.put("Font", descendantFont.getName());
+ attributes.put("CID count", Integer.toString(tab.length));
+ attributes.put("Glyph count", Integer.toString(totalAvailableGlyph));
+
+ view = new FontEncodingView(tab, attributes,
+ new String[]{"Code", "CID", "GID", "Unicode Character", "Glyph"}, getYBounds(tab, 4));
+ }
+ }
+
+ private Object[][] readMap(PDCIDFont descendantFont, PDType0Font parentFont) throws IOException
+ {
+ int codes = 0;
+ for (int code = 0; code < 65535; ++code)
+ {
+ if (descendantFont.hasGlyph(code))
+ {
+ ++codes;
+ }
}
+ Object[][] tab = new Object[codes][5];
+ int index = 0;
+ for (int code = 0; code < 65535; ++code)
+ {
+ if (descendantFont.hasGlyph(code))
+ {
+ tab[index][0] = code;
+ tab[index][1] = descendantFont.codeToCID(code);
+ tab[index][2] = descendantFont.codeToGID(code);
+ tab[index][3] = parentFont.toUnicode(code);
+ GeneralPath path = descendantFont.getPath(code);
+ tab[index][4] = path;
+ if (!path.getBounds2D().isEmpty())
+ {
+ ++totalAvailableGlyph;
+ }
+ ++index;
+ }
+ }
+ return tab;
}
- private Object[][] readCIDToGIDMap(PDCIDFontType2 font, PDFont parentFont) throws IOException
+ private Object[][] readCIDToGIDMap(PDCIDFont font, PDFont parentFont) throws IOException
{
Object[][] cid2gid = null;
COSDictionary dict = font.getCOSObject();
@@ -71,7 +119,7 @@ class Type0Font implements FontPane
byte[] mapAsBytes = IOUtils.toByteArray(is);
IOUtils.closeQuietly(is);
int numberOfInts = mapAsBytes.length / 2;
- cid2gid = new Object[numberOfInts][3];
+ cid2gid = new Object[numberOfInts][4];
int offset = 0;
for (int index = 0; index < numberOfInts; index++)
{
@@ -82,14 +130,18 @@ class Type0Font implements FontPane
{
cid2gid[index][2] = parentFont.toUnicode(index);
}
+ GeneralPath path = font.getPath(index);
+ cid2gid[index][3] = path;
+ if (!path.getBounds2D().isEmpty())
+ {
+ ++totalAvailableGlyph;
+ }
offset += 2;
}
}
return cid2gid;
}
-
-
@Override
public JPanel getPanel()
{
Added: pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/Type3Font.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/Type3Font.java?rev=1754315&view=auto
==============================================================================
--- pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/Type3Font.java (added)
+++ pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/Type3Font.java Wed Jul 27 16:43:48 2016
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2015 The Apache Software Foundation.
+ *
+ * Licensed 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.debugger.fontencodingpane;
+
+import java.io.IOException;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import javax.swing.JPanel;
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
+import org.apache.pdfbox.pdmodel.font.PDSimpleFont;
+import org.apache.pdfbox.pdmodel.font.PDType3CharProc;
+import org.apache.pdfbox.pdmodel.font.PDType3Font;
+
+/**
+ * @author Khyrul Bashar
+ * A class that shows the glyph table along with unicode characters for SimpleFont.
+ */
+class Type3Font extends FontPane
+{
+ public static final String NO_GLYPH = "No glyph";
+ private int totalAvailableGlyph = 0;
+ private final FontEncodingView view;
+
+ /**
+ * Constructor.
+ * @param font PDSimpleFont instance.
+ * @throws IOException If fails to parse unicode characters.
+ */
+ Type3Font(PDType3Font font) throws IOException
+ {
+ Object[][] tableData = getGlyphs(font);
+
+ Map<String, String> attributes = new LinkedHashMap<String, String>();
+ attributes.put("Encoding", getEncodingName(font));
+ attributes.put("Font", font.getName());
+ attributes.put("Glyph count", Integer.toString(totalAvailableGlyph));
+
+ view = new FontEncodingView(tableData, attributes, new String[] {"Code", "Glyph Name", "Unicode Character"}, null);
+ }
+
+ private Object[][] getGlyphs(PDType3Font font) throws IOException
+ {
+ Object[][] glyphs = new Object[256][3];
+
+ for (int index = 0; index <= 255; index++)
+ {
+ glyphs[index][0] = index;
+ if (font.getEncoding().contains(index))
+ {
+ glyphs[index][1] = font.getEncoding().getName(index);
+ glyphs[index][2] = font.toUnicode(index);
+ totalAvailableGlyph++;
+ }
+ else
+ {
+ glyphs[index][1] = NO_GLYPH;
+ glyphs[index][2] = NO_GLYPH;
+ }
+ }
+ return glyphs;
+ }
+
+ private String getEncodingName(PDSimpleFont font)
+ {
+ return font.getEncoding().getClass().getSimpleName();
+ }
+
+ @Override
+ public JPanel getPanel()
+ {
+ return view.getPanel();
+ }
+}
Propchange: pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/Type3Font.java
------------------------------------------------------------------------------
svn:eol-style = native