itextpdf字体未嵌入Linux中

itextpdf字体未嵌入Linux中,linux,pdf,fonts,itext,embedding,Linux,Pdf,Fonts,Itext,Embedding,我有一个简单的Java程序,它使用iTextPDF创建一个简单的“Hello World”文件,使用的字体不是iTextPDF的原生字体(COOPBL.TTF,直接从Windows获得) 在Windows7-64上运行时,它运行良好,创建了一个pdf文件,文件中嵌入了库珀黑字体的子集,反映在文件外观上 在Linux上运行完全相同的类文件(无需重新编译),它不嵌入任何内容并使用Helvetica 节目如下: import java.io.ByteArrayInputStream; import j

我有一个简单的Java程序,它使用iTextPDF创建一个简单的“Hello World”文件,使用的字体不是iTextPDF的原生字体(COOPBL.TTF,直接从Windows获得)

在Windows7-64上运行时,它运行良好,创建了一个pdf文件,文件中嵌入了库珀黑字体的子集,反映在文件外观上

在Linux上运行完全相同的类文件(无需重新编译),它不嵌入任何内容并使用Helvetica

节目如下:

import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfWriter;

import com.itextpdf.tool.xml.XMLWorkerHelper;


public class iTextTest {
  private void doit(String sOut) {
    Document doc = new Document(PageSize.LETTER);

    try {
      FileOutputStream fOut = new FileOutputStream(sOut);

      // Register a non-native font.
      String sFontDir = ".";
      int iResult = FontFactory.registerDirectory(sFontDir);
      if(iResult == 0) {
        System.out.println("TestPDF(): Could not register font directory " + sFontDir);
      } else {
        System.out.println("TestPDF(): Registered font directory " + sFontDir);
      }
      System.out.println("  Fonts registered:");
      for(String sFont:FontFactory.getRegisteredFonts()) {
        System.out.println("    " + sFont);
      }

      PdfWriter pdfWriter = PdfWriter.getInstance(doc, fOut);

      doc.open();

      XMLWorkerHelper helper = XMLWorkerHelper.getInstance();

      String htmlContent;
      htmlContent  = "<HTML><HEAD></HEAD><BODY>";
      htmlContent += "<P style=\"font-family: cooperblack;\">";
      htmlContent += "Hello World!";
      htmlContent += "</P>";
      htmlContent += "</BODY></HTML>";
      helper.parseXHtml(pdfWriter, doc, new ByteArrayInputStream(htmlContent.getBytes()));

    } catch(IOException e) {
      e.printStackTrace();
    } catch(DocumentException e) {
      e.printStackTrace();
    }

    if(doc != null) {
      doc.close();
    }
  }


  public static void main(String[] args) {
    if(args.length != 1) {
      System.out.println("Usage: iTextTest outfile");
      return;
    }

    iTextTest test = new iTextTest();
    test.doit(args[0]);
  }
}
import java.io.ByteArrayInputStream;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入com.itextpdf.text.FontFactory;
导入com.itextpdf.text.Document;
导入com.itextpdf.text.PageSize;
导入com.itextpdf.text.DocumentException;
导入com.itextpdf.text.pdf.PdfWriter;
导入com.itextpdf.tool.xml.XMLWorkerHelper;
公共类iTextTest{
私有void doit(字符串sOut){
文档文档=新文档(页面大小.字母);
试一试{
FileOutputStream fOut=新的FileOutputStream(sOut);
//注册非本机字体。
字符串sFontDir=“.”;
int-iResult=FontFactory.registerDirectory(sFontDir);
如果(iResult==0){
System.out.println(“TestPDF():无法注册字体目录”+sFontDir);
}否则{
System.out.println(“TestPDF():注册字体目录”+sFontDir);
}
System.out.println(“字体注册:”;
对于(字符串sFont:FontFactory.getRegisteredFonts()){
System.out.println(“+sFont”);
}
PdfWriter PdfWriter=PdfWriter.getInstance(doc,fOut);
doc.open();
XMLWorkerHelper=XMLWorkerHelper.getInstance();
字符串htmlContent;
htmlContent=“”;
htmlContent+=“

”; htmlContent+=“你好,世界!”; htmlContent+=“

”; htmlContent+=“”; parseXHtml(pdfWriter、doc、newbytearrayinputstream(htmlContent.getBytes()); }捕获(IOE异常){ e、 printStackTrace(); }捕获(文档异常){ e、 printStackTrace(); } 如果(doc!=null){ doc.close(); } } 公共静态void main(字符串[]args){ 如果(args.length!=1){ System.out.println(“用法:iTextTest outfile”); 返回; } iTextTest=新的iTextTest(); test.doit(args[0]); } }
我正在使用: itextpdf-5.5.0 xmlworker-5.5.0 Windows Java 1.6.0_21 Linux Java 1.6.0_23

我会包括字体的副本和生成的pdf,但看不到明显的方法。对于我的测试,我只是简单地将\Windows\font\COOPBL.TTF复制到测试目录中,包括Windows测试和Linux测试

为了它的价值: -调整字体文件中的保护/属性标志没有任何区别。 -我知道这不是一种公共域字体。我只是用它来测试

我洗耳恭听任何评论

谢谢,
Chuck

在Windows和Linux(Windows Ecplise和console jdb-ack!)上并行调试之后,我发现了问题所在。这似乎要么是文档缺陷,要么是我的疏忽。我想我应该在这里发布修复程序,以防其他人有类似的问题

问题是,如果要使用XMLWorkerHelper解析文件,我不应该使用默认的FontFactory来注册字体。我在第一个代码示例中使用的XMLWorkerHelper.parseXHtml()的风格创建了自己的FontFactoryImp,即XMLWorkerFontProvider。该提供程序忽略默认FontFactory执行的任何注册

解决方案有两个方面:
1) 创建您自己的XMLWorkerFontProvider。使用将字体目录作为输入参数的构造函数。
2) 将该提供程序传递到parseXHtml(),而不是使用较短的调用

我还使用FontFactory.setFontImp()设置默认的FontFactory提供程序。我还没有研究这一行动的微妙含义,但跳过这一步还是很容易的

值得一提的是,原始程序在Windows中工作的唯一原因是,在我最初对parseXHtml()的调用中提供的默认XMLWorkerFontProvider注册了所有系统目录中的所有字体。因为,在Windows端,我使用的字体已经是C:/Windows/fonts中的字体,这是正在拾取的字体,而不是本地目录中的文件。如果我使用了未在Windows中注册的新字体,Windows测试也会失败

这是可行的解决方案。它在Windows和Linux上生成相同的pdf文件:

注意:如果您使用的是XMLParser.parse()而不是XMLWorkerHelper.parseXHtml(),请查看此代码块后面的其他注释

import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.File;

import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfWriter;

import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;


public class iTextTest {
  private void doit(String sOut) {
    Document doc = new Document(PageSize.LETTER);

    try {
      FileOutputStream fOut = new FileOutputStream(sOut);

      // Register non-native fonts in a directory.
      String sFontDir = ".";
      XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(sFontDir, null);
      FontFactory.setFontImp(fontImp);

      System.out.println("  Fonts registered before parsing:");
      for(String sFont:FontFactory.getRegisteredFonts()) {
        System.out.println("    " + sFont);
      }

      PdfWriter pdfWriter = PdfWriter.getInstance(doc, fOut);

      doc.open();

      XMLWorkerHelper helper = XMLWorkerHelper.getInstance();

      String htmlContent;
      htmlContent  = "<HTML><HEAD></HEAD><BODY>";
      htmlContent += "<P style=\"font-family: cooperblack;\">";
      htmlContent += "Hello World!";
      htmlContent += "</P>";
      htmlContent += "</BODY></HTML>";
      helper.parseXHtml(pdfWriter,
                        doc,
                        new ByteArrayInputStream(htmlContent.getBytes()),
                        XMLWorkerHelper.class.getResourceAsStream("/default.css"),
                        null,
                        fontImp);

    } catch(IOException e) {
      e.printStackTrace();
    } catch(DocumentException e) {
      e.printStackTrace();
    }

    if(doc != null) {
      doc.close();
    }
  }


  public static void main(String[] args) {
    if(args.length != 1) {
      System.out.println("Usage: iTextTest outfile");
      return;
    }

    iTextTest test = new iTextTest();
    test.doit(args[0]);
  }
}
import java.io.ByteArrayInputStream;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.io.File;
导入com.itextpdf.text.FontFactory;
导入com.itextpdf.text.Document;
导入com.itextpdf.text.PageSize;
导入com.itextpdf.text.DocumentException;
导入com.itextpdf.text.pdf.PdfWriter;
导入com.itextpdf.tool.xml.XMLWorkerHelper;
导入com.itextpdf.tool.xml.XMLWorkerFontProvider;
公共类iTextTest{
私有void doit(字符串sOut){
文档文档=新文档(页面大小.字母);
试一试{
FileOutputStream fOut=新的FileOutputStream(sOut);
//在目录中注册非本机字体。
字符串sFontDir=“.”;
XMLWorkerFontProvider fontImp=新的XMLWorkerFontProvider(sFontDir,null);
FontFactory.setFontImp(fontImp);
System.out.println(“解析前注册的字体:”);
对于(字符串sFont:FontFactory.getRegisteredFonts()){
System.out.println(“+sFont”);
}
PdfWriter PdfWriter=PdfWriter.getInstance(doc,fOut);
doc.open();
XMLWorkerHelper=XMLWorkerHelper.getInstance();
字符串htmlContent;
htmlContent=“”;
htmlContent+=“

”;

  htmlContext = new HtmlPipelineContext(new CssAppliersImpl(fontImp));
  htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());

  pdfImageProvider = new PDFImageProvider();  // Optional
  htmlContext.setImageProvider(pdfImageProvider);  // Optional

  Pipeline<?> pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext, new PdfWriterPipeline(doc, pdfWriter)));
  xmlWorker = new XMLWorker(pipeline, true);
  xmlParser = new XMLParser(true, xmlWorker, charsetUTF8);