2012-09-28 7 views
6

有効なPDF/Xドキュメントを生成するには、すべてのフォントを埋め込む必要があります。どうにか私はGraphics2Dコンテキストでこれらのフォントを使用することはできません。埋め込みフォントを使用してGraphics2D.drawString(...)をiTextで呼び出す方法(DefaultFontMapper?)

このユニットテストは(コメント行は、私が作ったいくつかのテストです)問題を示しています

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(); 
    } 

} 

それはメッセージで​​がスローされます:「すべてのフォントが埋め込まれている必要がありますこの1つはありません:ヘルベチカ。

私はすでにsetFont()実装をチェックするPdfGraphics2Dクラスものの閲覧と私はすでに上でユニットテストにこれを追加しました。FontMapperが使用されること、が分かった。

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の本のthis exampleに基づいています。 Hereは、FontMapperの他の例です。ユニットテストを実行するには

あなたはこの依存関係が必要になります(「」にあります)

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

カスタムフォントあなたがhereを見つけます。

コンソール出力が私にこの(たfontNameを識別するために)示しています

Comicate: ./COMICATE.TTF 

答えて

2

を私はあなたのコード内のエラーを修正する正確な方法がわからないけど、簡単な回避策があります。

回避策1)BufferedImageを作成して、すべてのグラフィックペイントを行います。 iTextに関係なく、通常のjava.awt.Graphics関数(drawStringsetColorなど)をすべて使用できます。完了したら、イメージをPDFに描画します。あなたがここにズームするとき、テキストの緩い品質を行いますが、警告は一例です:

//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次のように:

//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を回避するために同様のものを使用している、これはあなたが探していた答えを与えるものではありません知っています前。これが助けにならないなら、私はブルーノが答えを得られると確信しています。

+0

こんにちは、あなたの提案に感謝。残念ながら私はあなたの回避策を利用することはできません:(それはg2d.drawText(...)を呼び出すのではなく、JFreechartです。 – d0x

1

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

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

preview img

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(); 
    } 
+0

'itext'を使ってPDFを作成し、.tffファイルを実行可能なJarの中に置く唯一の実用的な解決策です – AntJavaDev

関連する問題