TextMarginFinder to verify printability

后端 未结 1 1988
面向向阳花
面向向阳花 2021-01-27 06:26

I am attempting to use TextMarginFinder to prove that odd and even pages back up correctly when printing. I have based my code on: http://itextpdf.com/examples/iia.php?id=280

相关标签:
1条回答
  • 2021-01-27 06:37

    In the PDF the OP pointed to (margins.pdf from the iText samples themselves) indeed the box is not flush with the text:

    enter image description here

    If you look into the PDF Content, though, you'll see that many of the lines have a trailing space character, e.g. the first line:

    (s I have worn out since I started my ) Tj
    

    These trailing space characters are part of the text and, therefore, the box does not flush with the visible text but it does with the text including such space characters.

    If you want to ignore such space characters, you can try doing so by filtering such trailing spaces (or for the sake of simplicity all spaces) before they get fed into the TextMarginFinder. To do this I'd explode the TextRenderInfo instances character-wise and then filter those which trim to empty strings.

    A helper class to explode the render info objects:

    import com.itextpdf.text.pdf.parser.ImageRenderInfo;
    import com.itextpdf.text.pdf.parser.RenderListener;
    import com.itextpdf.text.pdf.parser.TextRenderInfo;
    
    public class TextRenderInfoSplitter implements RenderListener
    {
        public TextRenderInfoSplitter(RenderListener strategy) {
            this.strategy = strategy;
        }
    
        public void renderText(TextRenderInfo renderInfo) {
            for (TextRenderInfo info : renderInfo.getCharacterRenderInfos()) {
                strategy.renderText(info);
            }
        }
    
        public void beginTextBlock() {
            strategy.beginTextBlock();
        }
    
        public void endTextBlock() {
            strategy.endTextBlock();
        }
    
        public void renderImage(ImageRenderInfo renderInfo) {
            strategy.renderImage(renderInfo);
        }
    
        final RenderListener strategy;
    }
    

    Using this helper you can update the iText sample like this:

    RenderFilter spaceFilter = new RenderFilter() {
        public boolean allowText(TextRenderInfo renderInfo) {
            return renderInfo != null && renderInfo.getText().trim().length() > 0;
        }
    };
    
    PdfReader reader = new PdfReader(src);
    PdfReaderContentParser parser = new PdfReaderContentParser(reader);
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(RESULT));
    for (int i = 1; i <= reader.getNumberOfPages(); i++) {
        TextMarginFinder finder = new TextMarginFinder();
        FilteredRenderListener filtered = new FilteredRenderListener(finder, spaceFilter);
        parser.processContent(i, new TextRenderInfoSplitter(filtered));
        PdfContentByte cb = stamper.getOverContent(i);
        cb.rectangle(finder.getLlx(), finder.getLly(), finder.getWidth(), finder.getHeight());
        cb.stroke();
    }
    stamper.close();
    reader.close();
    

    The result:

    enter image description here

    In case of slug area text etc you might want to filter more, e.g. anything outside the crop box.

    Beware, though, there might be fonts in which the space character is not invisible, e.g. a font of boxed characters. Taking the spaces out of the equation in that case would be wrong.

    0 讨论(0)
提交回复
热议问题