2012-09-28 9 views
6

Aby wygenerować prawidłowy dokument PDF/X, wszystkie czcionki muszą być osadzone. W jakiś sposób nie mogę używać tych czcionek w kontekście Graphics2D.Jak używać osadzonych czcionek do wywoływania Graphics2D.drawString (...) z iText (DefaultFontMapper?)

tej Unittests przedstawia problem (komentowane linie są pewne testy zrobiłem):

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

} 

To wygeneruje PdfXConformanceException z komunikatem: „. Wszystkie czcionki muszą być osadzony ten nie jest: Helvetica.

już przejrzysz chociaż klasa PdfGraphics2D sprawdzić realizację setFont() i okazało się, że FontMapper zostaną wykorzystane. i to już dodany do unittest powyżej.

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 jest oparty na this example z książki iText w Action. Here to inne przykłady dotyczące FontMapper.

Aby uruchomić unittest trzeba tę zależność: ("" znajdujący się)

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

Zwyczaj Czcionka znaleźć here.

Konsola Wyjście pokazuje mi to (w celu identyfikacji fontName):

Comicate: ./COMICATE.TTF 

Odpowiedz

2

nie jestem pewien dokładnie sposób poprawić błąd w kodzie, ale istnieją proste sposoby ich obejścia:

Obejście 1) Utwórz obraz BufferedImage, aby wykonać wszystkie prace graficzne. Następnie możesz użyć wszystkich normalnych funkcji , takich jak drawString i setColor, niezależnie od iText, a kiedy skończysz, po prostu narysuj obrazek do pliku PDF. OSTRZEŻENIE zrobić luźne jakość tekstu podczas powiększania, ale tutaj jest przykład:

//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); 

Obejście 2) wykorzystuje możliwości itext narysować ciągi, bez konieczności tworzenia żadnych obiektów graficznych, czcionka jest załatwione za pomocą BaseFont następująco:

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

wiem, że to nie daje odpowiedzi, której szukasz, jednak jeśli tylko rysunek niewielką ilość tekstu potem obejść 2 działa super, użyłem coś podobnego do obejście 2 przed. Jeśli to nie pomoże, jestem pewien, że Bruno będzie miał odpowiedź.

+0

Cześć, dziękuję za sugestię. Niestety nie mogę użyć ciebie obejścia :(To nie ja nazywam g2d.drawText (...), to JFreechart. – d0x

1

Definiując nowe BaseFont (y) i implementując interfejs FontMapper() >>> public BaseFont awtToPdf (czcionka java.awt.Font). To zastosuje awt.font (s) jako osadzone w pliku pdf.

W poniższym przykładzie I "drukuj" g2D (w tym metoda "drawString") narysowana w klasie zewnętrznej. Wynikiem jest eksportowany plik wektorowy w formacie PDF z wbudowanymi czcionkami "ArialMT" i "Arial-BoldMT".

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

jedyne działające rozwiązanie do tworzenia pliku PDF z 'itext', umieszczanie plików .tff wewnątrz działającego słoika – AntJavaDev

Powiązane problemy