With our August release of JPedal we have added a new option to improve the rendering of shapes with our library. This was done by supporting Soft Clipping, a form of clipping not supported in Java’s rendering methods. Until now we have been using Hard Clipping and would modify the clip to give the best possible. Recently we found that to improve the rendering any further would require a new form of clipping.
Soft Clip? Hard Clip? What’s the difference?
As you may know clipping allows you to specify a stencil which is used to control what is drawn by only drawing the content that falls within the stencil. Soft and Hard clipping treats the stencil in slightly different ways.
Hard Clipping picks pixels as either in the clip or out. If a line of a clip passes through a pixel a decision is made as to whether to include it or not. This leads to jagged edges as each pixel is either in or out of the clip.
Soft Clipping follows the same approach of Hard Clipping except in the way partial pixels are handled at the edge of the clip. With Soft Clipping any pixel that is partially contained can be drawn to but with a blending (similar to anti-aliasing) to give a smoother edge.
What Does Adobe do?
By default Adobe Reader uses a smoothing technique on the shapes in a PDF to improve its appearance. This smoothing is similar to soft clipping and is controlled by a preference called Smooth Line Art. In the various test files we have access to it appears that this option uses a soft clipping effect on shapes.
When it is turned off the clipping appears to be a very aggressive form of Hard Clipping which gives a more jagged appearance (top image).
When it is turned on the clipping appears to be Soft Clipping. The shapes appear thinner due to the transparency at the edges of the clip and they are smoother (bottom image).
What did JPedal do?
Up until now JPedal has done some clever manipulation of the clip in order to allow it to appear similar to Adobe Readers handling. This was achieved by expanding the clip slightly to increase the amount o the shape would be visible. Unfortunately this code has a small performance hit that in some cases (such as one example containing over 6000 clips) the small performance hit adds up to a big performance hit.
Also with us using an expanded Hard Clip I have found a small amount of examples that appear slightly incorrect but due to the nature of the previous approach the difference is a pixel or less.
What does Java do?
Java uses Hard Clipping when you set a Clip to a Graphics object. There have been requests to add support for Soft Clipping to the API for some time but these requests have been turned down as it goes against the way Javas rendering is intended to work. However there are ways to give something the appearance of having had a Soft Clip applied. This is what we have implemented in our most recent version.
How do I use Soft Clipping?
The new soft clipping options shows several changes in rendered pages.
The most prominent of these is that the shapes clips are handled faster and with less memory. Also, as Java does not support sub-pixel rendering the original clipping approach would render the shapes as close as possible. The new soft clipping is able to render these shapes much closer to its correct position.
The new soft clipping can be turned on / off using the PdfDecoder.modifyNonstaticJPedalParameters method, an example of its use is below.
HashMap<Integer, Object> map = new HashMap();
map.put(JPedalSettings.USE_SOFTCLIP_FOR_SHAPES, false);
pdfDecoder.modifyNonstaticJPedalParameters(map);
The JPedal PDF library allows you to solve these problems in Java
Viewer viewer = new Viewer();
viewer.setupViewer();
viewer.executeCommand(ViewerCommands.OPENFILE, "pdfFile.pdf");
//Convenience static method (see class for additional options)
ExtractClippedImages.writeAllClippedImagesToDir("inputFileOrDirectory", "outputDir", "outputImageFormat", new String[] {"imageHeightAsFloat", "subDirectoryForHeight"});
//Convenience static method (see class for additional options)
ExtractTextAsWordList.writeAllWordlistsToDir("inputFileOrDirectory", "outputDir", -1);
//Convenience static method (see class for additional options)
ArrayList resultsForPages = FindTextInRectangle.findTextOnAllPages("/path/to/file.pdf", "textToFind");
PrintPdfPages print = new PrintPdfPages("C:/pdfs/mypdf.pdf");
if (print.openPDFFile()) {
print.printAllPages("Printer Name");
}
//Convenience static method (see class for additional options)
ExtractClippedImages.writeAllClippedImagesToDir("inputFileOrDirectory", "outputDir", "outputImageFormat", new String[] {"imageHeightAsFloat", "subDirectoryForHeight"});
Why do developers choose JPedal over alternatives?
- Actively developed commercial library with full support and no third party dependencies.
- Simple licensing options and source code access for OEM users.
- Process PDF files up to 3x faster than alternative Java PDF libraries.