TextMarginFinder to verify printability

为君一笑 提交于 2019-12-02 16:40:05

问题


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

The issue I have is that on odd pages I am looking for the box to be aligned to the left showing a 1CM back margin for example, and on an even page I would expect the page box to be aligned to the right also showing a 1CM back margin. Even in the example above this is not the case, but when printed the text does back up perfectly because the Trim Box conforms.

In summary I believe on certain PDF files the TextMarginFinder is incorrectly locating the text width, usually on Even pages. This is evident by the width being greater than the actual text. This is usually the case if there are slug marks outside of the Media Box area.


回答1:


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

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:

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.



来源:https://stackoverflow.com/questions/25132274/textmarginfinder-to-verify-printability

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!