Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 8C7A0200C13 for ; Mon, 6 Feb 2017 18:15:58 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 8AC92160B56; Mon, 6 Feb 2017 17:15:58 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id AE33C160B53 for ; Mon, 6 Feb 2017 18:15:57 +0100 (CET) Received: (qmail 51949 invoked by uid 500); 6 Feb 2017 17:15:57 -0000 Mailing-List: contact commits-help@pdfbox.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@pdfbox.apache.org Delivered-To: mailing list commits@pdfbox.apache.org Received: (qmail 51935 invoked by uid 99); 6 Feb 2017 17:15:56 -0000 Received: from Unknown (HELO svn01-us-west.apache.org) (209.188.14.144) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 06 Feb 2017 17:15:56 +0000 Received: from svn01-us-west.apache.org (localhost [127.0.0.1]) by svn01-us-west.apache.org (ASF Mail Server at svn01-us-west.apache.org) with ESMTP id 36C6E3A108E for ; Mon, 6 Feb 2017 17:15:56 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1781926 - in /pdfbox/branches/2.0/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane: FontEncodingPaneController.java FontEncodingView.java Type3Font.java Date: Mon, 06 Feb 2017 17:15:55 -0000 To: commits@pdfbox.apache.org From: tilman@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20170206171556.36C6E3A108E@svn01-us-west.apache.org> archived-at: Mon, 06 Feb 2017 17:15:58 -0000 Author: tilman Date: Mon Feb 6 17:15:55 2017 New Revision: 1781926 URL: http://svn.apache.org/viewvc?rev=1781926&view=rev Log: PDFBOX-2941: show type3 font glyph rendering Modified: pdfbox/branches/2.0/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingPaneController.java pdfbox/branches/2.0/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingView.java pdfbox/branches/2.0/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/Type3Font.java Modified: pdfbox/branches/2.0/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingPaneController.java URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingPaneController.java?rev=1781926&r1=1781925&r2=1781926&view=diff ============================================================================== --- pdfbox/branches/2.0/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingPaneController.java (original) +++ pdfbox/branches/2.0/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingPaneController.java Mon Feb 6 17:15:55 2017 @@ -82,7 +82,7 @@ public class FontEncodingPaneController PDFont font = resources.getFont(fontName); if (font instanceof PDType3Font) { - fontPane = new Type3Font((PDType3Font) font); + fontPane = new Type3Font((PDType3Font) font, resources); } else if (font instanceof PDSimpleFont) { Modified: pdfbox/branches/2.0/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingView.java URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingView.java?rev=1781926&r1=1781925&r2=1781926&view=diff ============================================================================== --- pdfbox/branches/2.0/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingView.java (original) +++ pdfbox/branches/2.0/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/FontEncodingView.java Mon Feb 6 17:15:55 2017 @@ -153,6 +153,30 @@ class FontEncodingView BufferedImage bim = renderGlyph(path, bounds2D, cellRect); return new JLabel(new ImageIcon(bim)); } + if (o instanceof BufferedImage) + { + Rectangle cellRect = jTable.getCellRect(row, col, false); + BufferedImage glyphImage = (BufferedImage) o; + BufferedImage cellImage = new BufferedImage((int) cellRect.getWidth(), (int) cellRect.getHeight(), BufferedImage.TYPE_INT_RGB); + Graphics2D g = (Graphics2D) cellImage.getGraphics(); + g.setBackground(Color.white); + g.clearRect(0, 0, cellImage.getWidth(), cellImage.getHeight()); + + double scale = 1 / (glyphImage.getHeight() / cellRect.getHeight()); + + // horizontal center + g.translate((cellRect.getWidth() - glyphImage.getWidth() * scale) / 2, 0); + + // scale from the glyph to the cell + g.scale(scale, scale); + + g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); + g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g.drawImage(glyphImage, 0, 0, null); + g.dispose(); + return new JLabel(new ImageIcon(cellImage)); + } if (o != null) { JLabel label = new JLabel(o.toString(), SwingConstants.CENTER); Modified: pdfbox/branches/2.0/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/Type3Font.java URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/Type3Font.java?rev=1781926&r1=1781925&r2=1781926&view=diff ============================================================================== --- pdfbox/branches/2.0/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/Type3Font.java (original) +++ pdfbox/branches/2.0/debugger/src/main/java/org/apache/pdfbox/debugger/fontencodingpane/Type3Font.java Mon Feb 6 17:15:55 2017 @@ -16,31 +16,51 @@ package org.apache.pdfbox.debugger.fontencodingpane; -import org.apache.pdfbox.pdmodel.font.PDSimpleFont; -import org.apache.pdfbox.pdmodel.font.PDType3Font; - -import javax.swing.JPanel; +import java.awt.geom.AffineTransform; +import java.awt.geom.NoninvertibleTransformException; +import java.awt.image.BufferedImage; import java.io.IOException; import java.util.LinkedHashMap; import java.util.Map; +import javax.swing.JPanel; + +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.PDResources; +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; +import org.apache.pdfbox.rendering.PDFRenderer; +import org.apache.pdfbox.util.Charsets; +import org.apache.pdfbox.util.Matrix; /** * @author Khyrul Bashar - * A class that shows the glyph table along with unicode characters for SimpleFont. + * @author Tilman Hausherr + * + * A class that shows the glyph table along with unicode characters for PDType3Font. */ class Type3Font extends FontPane { public static final String NO_GLYPH = "No glyph"; private final FontEncodingView view; private int totalAvailableGlyph = 0; + private PDRectangle fontBBox; + private final PDResources resources; /** * Constructor. * @param font PDSimpleFont instance. * @throws IOException If fails to parse unicode characters. */ - Type3Font(PDType3Font font) throws IOException + Type3Font(PDType3Font font, PDResources resources) throws IOException { + this.resources = resources; + + calcBBox(font); + Object[][] tableData = getGlyphs(font); Map attributes = new LinkedHashMap(); @@ -48,12 +68,39 @@ class Type3Font extends FontPane attributes.put("Encoding", getEncodingName(font)); attributes.put("Glyphs", Integer.toString(totalAvailableGlyph)); - view = new FontEncodingView(tableData, attributes, new String[] {"Code", "Glyph Name", "Unicode Character"}, null); + view = new FontEncodingView(tableData, attributes, + new String[] {"Code", "Glyph Name", "Unicode Character", "Glyph"}, null); + } + + private void calcBBox(PDType3Font font) throws IOException + { + double minX = 0; + double maxX = 0; + double minY = 0; + double maxY = 0; + for (int index = 0; index <= 255; ++index) + { + PDType3CharProc charProc = font.getCharProc(index); + if (charProc == null) + { + continue; + } + PDRectangle glyphBBox = charProc.getGlyphBBox(); + if (glyphBBox == null) + { + continue; + } + minX = Math.min(minX, glyphBBox.getLowerLeftX()); + maxX = Math.max(maxX, glyphBBox.getUpperRightX()); + minY = Math.min(minY, glyphBBox.getLowerLeftY()); + maxY = Math.max(maxY, glyphBBox.getUpperRightY()); + } + fontBBox = new PDRectangle((float) minX, (float) minY, (float) (maxX - minX), (float) (maxY - minY)); } private Object[][] getGlyphs(PDType3Font font) throws IOException { - Object[][] glyphs = new Object[256][3]; + Object[][] glyphs = new Object[256][4]; for (int index = 0; index <= 255; index++) { @@ -62,17 +109,66 @@ class Type3Font extends FontPane { glyphs[index][1] = font.getEncoding().getName(index); glyphs[index][2] = font.toUnicode(index); + if (fontBBox.toGeneralPath().getBounds2D().isEmpty()) + { + glyphs[index][3] = NO_GLYPH; + } + else + { + glyphs[index][3] = renderType3Glyph(font, index); + } totalAvailableGlyph++; } else { glyphs[index][1] = NO_GLYPH; glyphs[index][2] = NO_GLYPH; + glyphs[index][3] = NO_GLYPH; } } return glyphs; } + // Kindof an overkill to create a PDF for one glyph, but there is no better way at this time. + // Isn't called if no bounds are available + private BufferedImage renderType3Glyph(PDType3Font font, int index) throws IOException + { + PDDocument doc = new PDDocument(); + int scale = 1; + if (fontBBox.getWidth() < 72 || fontBBox.getHeight() < 72) + { + // e.g. T4 font of PDFBOX-2959 + scale = (int) (72 / Math.min(fontBBox.getWidth(), fontBBox.getHeight())); + } + PDPage page = new PDPage(new PDRectangle(fontBBox.getWidth() * scale, fontBBox.getHeight() * scale)); + page.setResources(resources); + PDPageContentStream cs = new PDPageContentStream(doc, page); + cs.transform(Matrix.getTranslateInstance(-fontBBox.getLowerLeftX(), -fontBBox.getLowerLeftY())); + try + { + AffineTransform at = font.getFontMatrix().createAffineTransform(); + if (!at.isIdentity()) + { + at.invert(); + cs.transform(new Matrix(at)); + } + } + catch (NoninvertibleTransformException ex) + { + // "shouldn't happen" + } + cs.beginText(); + cs.setFont(font, scale); + //TODO support type3 font encoding in PDType3Font.encode + cs.appendRawCommands(String.format("<%02X> Tj\n", index).getBytes(Charsets.ISO_8859_1)); + cs.endText(); + cs.close(); + doc.addPage(page); + BufferedImage bim = new PDFRenderer(doc).renderImage(0); + doc.close(); + return bim; + } + private String getEncodingName(PDSimpleFont font) { return font.getEncoding().getClass().getSimpleName();