Hi,
I think the problem is with PDF graphics 2d, not with PDFBox.
I can tell you if the fonts are really not embedded if you upload the
PDF to a sharehoster.
Tilman
Am 14.03.2021 um 19:27 schrieb Thangalin:
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!
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]