Hi list! Attempting to render an SVG file read from Batik onto an exported PDF document has encountered a few problems, including:
- Font rasterization - Font weights - Grid marks - Colour *Versions* - Apache PDFBox 2.0.22 - Apache Batik 1.14 - Rototor's PDF Graphics 2D 0.31 - OpenJDK 15 - Linux kernel 5.9.14, XFCE on Arch *Fonts* - Roboto, Roboto Thin - https://fonts.google.com/specimen/Roboto?preview.text_type=custom - Daggersquare - https://www.dafont.com/daggersquare.font *Comparison* In the following image, PDFBox export is on the left and Inkscape export on the right, but sourced from the same SVG and font files: https://i.ibb.co/pdxrf06/pdfbox-inkscape.png Notice that: - the word WANTED is discoloured (not a big issue); - fine lines grid the entire image (especially visible against the WANTED text); - all text is rasterized; - the font weight (Roboto thin) is not honoured; and - the file sizes differ by a fair margin (also not a huge issue). inkscape-poster.pdf is 23,481 bytes pdfbox-poster.pdf is 493,896 bytes *Question* How do you force the font subsets to be embedded (to reduce PDF file size and avoid rasterizing glyphs)? *SSCCE* The SSCCE transcodes /tmp/poster.svg to /tmp/pdfbox-poaster.pdf: // SOF import de.rototor.pdfbox.graphics2d.PdfBoxGraphics2D; import org.apache.batik.anim.dom.SAXSVGDocumentFactory; import org.apache.batik.bridge.BridgeContext; import org.apache.batik.bridge.DocumentLoader; import org.apache.batik.bridge.GVTBuilder; import org.apache.batik.bridge.UserAgentAdapter; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.common.PDRectangle; import java.io.File; import java.util.Map; import static java.awt.RenderingHints.*; import static java.awt.geom.AffineTransform.getScaleInstance; import static java.nio.file.Files.newOutputStream; import static java.nio.file.StandardOpenOption.*; import static org.apache.batik.util.XMLResourceDescriptor.getXMLParserClassName; public class Main { public static void main( final String[] args ) throws Exception { // Gain direct access to Batik graphics context. final var userAgent = new UserAgentAdapter(); final var loader = new DocumentLoader( userAgent ); final var context = new BridgeContext( userAgent, loader ); context.setDynamic( false ); // Read the SVG file to render as PDF. final var factory = new SAXSVGDocumentFactory( getXMLParserClassName() ); final var svg = factory.createSVGDocument( "/tmp/poster.svg" ); final var node = new GVTBuilder().build( context, svg ); // Ensure that small bounds are enlarged. final var bounds = node.getPrimitiveBounds(); final var w = (float) bounds.getWidth(); final var h = (float) bounds.getHeight(); final var scale = (w < 1 || h < 1) ? 100 : 1; // Create the PDF document model. final var pageSize = new PDRectangle( w * scale, h * scale ); final var page = new PDPage( pageSize ); final var document = new PDDocument(); document.addPage( page ); // Ask Batik to render upon the PDF's graphics context. final var graphics = new PdfBoxGraphics2D( document, w, h ); node.setRenderingHints( RENDERING_HINTS ); node.paint( graphics ); graphics.dispose(); // Instruct PDFBox to apply the drawn nodes. try( var writer = new PDPageContentStream( document, page ) ) { final var xform = graphics.getXFormObject(); xform.setMatrix( getScaleInstance( scale, scale ) ); writer.drawForm( xform ); } // Export the PDFBox document to a file. final var pdfFile = new File( "/tmp/pdfbox-poster.pdf" ); final var fos = newOutputStream( pdfFile.toPath(), WRITE, CREATE, TRUNCATE_EXISTING ); document.save( fos ); document.close(); fos.close(); System.out.println( "Created: " + pdfFile ); } private static final Map<Object, Object> RENDERING_HINTS = Map.of( KEY_ANTIALIASING, VALUE_ANTIALIAS_ON, KEY_ALPHA_INTERPOLATION, VALUE_ALPHA_INTERPOLATION_QUALITY, KEY_COLOR_RENDERING, VALUE_COLOR_RENDER_QUALITY, KEY_DITHERING, VALUE_DITHER_DISABLE, KEY_FRACTIONALMETRICS, VALUE_FRACTIONALMETRICS_ON, KEY_INTERPOLATION, VALUE_INTERPOLATION_BICUBIC, KEY_RENDERING, VALUE_RENDER_QUALITY, KEY_STROKE_CONTROL, VALUE_STROKE_PURE, KEY_TEXT_ANTIALIASING, VALUE_TEXT_ANTIALIAS_ON ); } // EOF I can provide the graphics off-list, if needed. Thank you!

