首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用pdfbox -如何从COSName获取字体?

使用pdfbox -如何从COSName获取字体?
EN

Stack Overflow用户
提问于 2017-10-11 13:54:33
回答 2查看 1.4K关注 0票数 0

如何从COSName中获取字体?

我正在寻找的解决方案看起来是这样的:

代码语言:javascript
运行
复制
COSDictionary dict = new COSDictionary();
dict.add(fontname, something); // fontname COSName from below code
PDFontFactory.createFont(dict);

如果你需要更多的背景资料,我把整个故事加在下面:

我试图替换pdf中的一些字符串。这是成功的(只要所有文本都存储在一个令牌中)。为了保持格式,我喜欢对文本进行重新居中。据我所知,我可以通过获得旧字符串和新字符串的宽度来做到这一点,做一些琐碎的计算并设置新的位置。

我在堆栈溢出中找到了一些替代https://stackoverflow.com/a/36404377的灵感(是的,它有一些问题,但适用于我的简单pdf。和How to center a text using PDFBox )。不幸的是,本例使用了字体常量。

因此,使用第一个链接的代码,我得到了运算符'Tj‘和'TJ’的处理。

代码语言:javascript
运行
复制
  PDFStreamParser parser = new PDFStreamParser(page);
  parser.parse();
  java.util.List<Object> tokens = parser.getTokens();
  for (int j = 0; j < tokens.size(); j++)
  {
    Object next = tokens.get(j);
    if (next instanceof Operator)
    {
      Operator op = (Operator) next;
      // Tj and TJ are the two operators that display strings in a PDF
      if (op.getName().equals("Tj"))
      {
        // Tj takes one operator and that is the string to display so lets
        // update that operator
        COSString previous = (COSString) tokens.get(j - 1);
        String string = previous.getString();
        String replaced = prh.getReplacement(string);
        if (!string.equals(replaced))
        { // if changes are there, replace the content
          previous.setValue(replaced.getBytes());
          float xpos = getPosX(tokens, j);
          //if (true) // center the text
          if (6 * xpos > page.getMediaBox().getWidth()) // check if text starts right from 1/xth page width
          {
            float fontsize = getFontSize(tokens, j);
            COSName fontname = getFontName(tokens, j);
            // TODO
            PDFont font = ?getFont?(fontname);
            // TODO
            float widthnew = getStringWidth(replaced, font, fontsize);
            setPosX(tokens, j, page.getMediaBox().getWidth() / 2F - (widthnew / 2F));
          }
          replaceCount++;
        }
      }

考虑到TODO标记之间的代码,我将从令牌列表中获得所需的值。(是的,这段代码很糟糕,但现在让我们集中讨论主要问题)

拥有字符串、大小和字体,我应该能够调用getWidth(.)从示例代码中获取。

不幸的是,我在用COSName变量创建字体时遇到了麻烦。

PDFont不提供按名称创建字体的方法。PDFontFactory看起来很好,但是请求一个COSDictionary。这就是我放弃的观点,并请求你的帮助。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-11 16:04:03

名称与页面资源中的字体对象相关联。

假设您使用的是PDFBox 2.0.x,并且page是一个PDPage实例,则可以使用以下方法解析名称fontname

代码语言:javascript
运行
复制
PDFont font = page.getResources().getFont(fontname);

但是,从评论到您所引用的问题的警告仍然存在:这种方法只适用于非常简单的PDF,甚至可能会损坏其他PDF。

票数 2
EN

Stack Overflow用户

发布于 2018-09-30 04:08:44

代码语言:javascript
运行
复制
try {
    //Loading an existing document 
    File file = new File("UKRSICH_Mo6i-Spikyer_z1560-FAV.pdf");
    PDDocument document = PDDocument.load(file);

    PDPage page = document.getPage(0);
    PDResources pageResources = page.getResources();

            System.out.println(pageResources.getFontNames() );

    for (COSName key : pageResources.getFontNames())
    {
    PDFont font = pageResources.getFont(key);

            System.out.println("Font: " + font.getName());
    }


    document.close();
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46690057

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档