gpt4 book ai didi

java - 如何使用嵌入式字体通过 iText(DefaultFontMapper?)调用 Graphics2D.drawString(...)

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:26:22 25 4
gpt4 key购买 nike

要生成有效的 PDF/X 文档,必须嵌入所有字体。不知何故,我无法在 Graphics2D 上下文中使用这些字体。

这个单元测试显示了问题(注释行是我做的一些测试):

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() 实现并发现将使用 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;
}
}

单元测试基于this example来自 iText in Action 一书。 Here是关于 FontMapper 的一些其他示例。

要运行单元测试,您需要此依赖项:

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

您找到的自定义字体(位于“.”)here .

控制台输出向我展示了这一点(以识别字体名称):

Comicate: ./COMICATE.TTF

最佳答案

我不确定更正代码中错误的确切方法,但有一些简单的解决方法:

解决方法 1) 创建一个 BufferedImage 来绘制所有图形。然后你可以使用所有普通的 java.awt.Graphics 函数,比如 drawStringsetColor 而不管 iText,当你完成后只绘制图像到 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 的方法。如果这没有帮助,那么我相信 Bruno 会给出答案。

关于java - 如何使用嵌入式字体通过 iText(DefaultFontMapper?)调用 Graphics2D.drawString(...),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12642051/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com