6

有効な PDF/X ドキュメントを生成するには、すべてのフォントを埋め込む必要があります。どういうわけか、これらのフォントを Graphics2D コンテキストで使用することはできません。

この Unittests は問題を示しています (コメント行は私が作成したいくつかのテストです):

import java.awt.Font;
import java.awt.Graphics2D;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.Map.Entry;

import org.junit.Test;

import com.itextpdf.awt.DefaultFontMapper;
import com.itextpdf.awt.DefaultFontMapper.BaseFontParameters;
import com.itextpdf.awt.PdfGraphics2D;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfWriter;

public class TestFont
{

    @Test
    public void shouldBeAbleToAddFountsAndDrawOnCanvas() throws FileNotFoundException, DocumentException
    {
        final DefaultFontMapper mapper = new DefaultFontMapper();
        mapper.insertDirectory(".");

        final PrintStream out2 = new PrintStream(System.out);
        for (final Entry<String, BaseFontParameters> entry : mapper.getMapper().entrySet())
        {
            out2.println(String.format("%s: %s", entry.getKey(), entry.getValue().fontName));
        }
        out2.flush();

        final float width = 150;
        final float height = 150;

        final Document document = new Document(new Rectangle(width, height));
        final PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("fonts.pdf"));
        writer.setPDFXConformance(PdfWriter.PDFX32002);

        document.open();
        final Graphics2D g2d = new PdfGraphics2D(writer.getDirectContent(), width, height, mapper);

        g2d.setFont(new Font("Comicate", Font.PLAIN, 12));

        g2d.drawString("Hello world", 5, 24);

        g2d.dispose();

        document.close();
    }

}

PdfXConformanceException「すべてのフォントを埋め込む必要があります。これは Helvetica ではありません。

PdfGraphics2Dクラスを参照して実装を確認したところsetFont()、 aFontMapperが使用されることがわかりました。私はすでにこれを上記の Unittest に追加しました。

public void setFont(Font f) {
    if (f == null)
        return;
    if (onlyShapes) {
        font = f;
        return;
    }
    if (f == font)
        return;
    font = f;
    fontSize = f.getSize2D();
    baseFont = getCachedBaseFont(f);
}

private BaseFont getCachedBaseFont(Font f) {
    synchronized (baseFonts) {
        BaseFont bf = (BaseFont)baseFonts.get(f.getFontName());
        if (bf == null) {
            bf = fontMapper.awtToPdf(f);
            baseFonts.put(f.getFontName(), bf);
        }
        return bf;
    }
}

Unittest は、iText in Action ブックのこの例に基づいています。FontMapperに関するその他の例を次に示します。

Unittest を実行するには、次の依存関係が必要です。

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.3.2</version>
</dependency>

カスタム フォント ("." にあります) はこちらにあります

コンソール出力には、次のように表示されます (fontName を識別するため)。

Comicate: ./COMICATE.TTF
4

2 に答える 2

2

コードのエラーを修正する正確な方法はわかりませんが、簡単な回避策があります。

回避策 1) BufferedImage を作成して、すべてのグラフィック ペイントを行います。次に、iTextに関係なく、iText などのすべての通常のjava.awt.Graphics機能を使用できます。完了したら、画像を PDF に描画するだけです。ズームするとテキストの品質が低下することを警告しますが、ここに例を示します。drawStringsetColor

//create doccument and writer    
Rectangle pagesize = new Rectangle(200, 100);
Document document= new Document(pagesize);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("C:\\sample.pdf"));

BufferedImage bf = new BufferedImage(BorderWidth, BorderHeight, BorderWidth);
//Do all graphics code here, draw strings and images etc
    //Some code to set font (java.awt.Font)
    //Some code to draw string
    //Some code to draw image?

//Convert BufferedImage to Image
Image img = (Image)bf;
//draw image to PDF using writer
writer.getDirectContentUnder().addImage(img);

回避策 2) これは iText 機能を使用して文字列を描画します。グラフィック オブジェクトを作成する必要はありません。フォントはBaseFont次のように a を使用して処理されます。

//create doccument and writer    
Rectangle pagesize = new Rectangle(200, 100);
Document document= new Document(pagesize);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("C:\\sample.pdf"));

document.open();
//This sample uses the "GOTHIC.TTF" font file located in the "Template" package
BaseFont bf = BaseFont.createFont(GUI.class.getClass().getResource("/Template/GOTHIC.TTF") + "", BaseFont.WINANSI, BaseFont.EMBEDDED);

//set font type, size and color
Font font = new Font(bf, 13.5f);

PdfContentByte canvas = writer.getDirectContent();

canvas.beginText();
canvas.setFontAndSize(bf, 10);
//Method Usage: showTextAligned(Align, String, x, y, rotation);
canvas.showTextAligned(Element.ALIGN_TOP, "My Text Here", 75, 40, 0);
canvas.endText();

document.close();

これであなたが探していた答えが得られないことはわかっていますが、少量のテキストを描画するだけの場合は、回避策 2 がうまく機能します。以前に回避策 2 に似たものを使用しました。これが役に立たない場合は、ブルーノが答えを持っていると確信しています.

于 2012-10-02T23:09:54.373 に答える
1

新しい BaseFont を定義し、FontMapper() のインターフェイスを実装する >>> public BaseFont awtToPdf(java.awt.Font font)。これにより、pdf に埋め込まれた awt.font(s) が適用されます。

以下の例では、外部クラスで描画された g2D (「drawString」メソッドを含む) を「印刷」します。結果は、「ArialMT」および「Arial-BoldMT」フォントのみが埋め込まれたベクトル PDF としてエクスポートされます。

プレビュー画像

    PdfWriter pdfWriter = null;
    try {
        pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(file));
        document.open();
        BaseFont fontRegular = BaseFont.createFont("C:\\Windows\\Fonts\\arial_0.ttf", "Cp1251", BaseFont.EMBEDDED);
        BaseFont fontBold = BaseFont.createFont("C:\\Windows\\Fonts\\arialbd_0.ttf", "Cp1251", BaseFont.EMBEDDED);
        FontMapper fontMapper = new FontMapper() {

            @Override
            public java.awt.Font pdfToAwt(BaseFont arg0, int arg1) {
                // TODO Auto-generated method stub
                return null;
            }

            @Override
            public BaseFont awtToPdf(java.awt.Font font) {
                if (font.equals(Fonts.getFontRegular10()) || font.equals(Fonts.getFontRegular12())){
                    return fontRegular;
                }
                else {
                    return fontBold;
                }
            }
        };
        PdfContentByte cb = pdfWriter.getDirectContent();
        PdfTemplate template = cb.createTemplate(MainFrame.getFRAME_WIDTH(), MainFrame.getFRAME_HEIGHT());
        Graphics2D g2D = new PdfGraphics2D(template, MainFrame.getFRAME_WIDTH(), MainFrame.getFRAME_HEIGHT(), fontMapper);
        MainFrame.getPanel().print(g2D);
        g2D.dispose();
        cb.addTemplate(template, 0, 0);
    }
    catch (Exception e1) {
        e1.printStackTrace();
    }
    finally {
        document.close();
    }
于 2016-06-23T15:38:36.847 に答える