【问题标题】:Get the font height of a character in PDFBox获取PDFBox中字符的字体高度
【发布时间】:2013-06-14 20:11:04
【问题描述】:

PDFBox 的字体类 PDFont 中有一个名为 getFontHeight 的方法,听起来很简单。但是我不太了解文档以及参数代表什么。

getFontHeight 这将获得字符的字体宽度。

参数:

  • c - 获取宽度的字符代码。
  • offset - 数组中的偏移量。长度
  • 数据的长度。

返回:宽度为1000个文本空间单位,即333或777

此方法是否适合用于获取 PDFBox 中字符的高度,如果可以,如何?我可以使用字体高度和字体大小之间的某种关系吗?

【问题讨论】:

    标签: java fonts font-size pdfbox


    【解决方案1】:

    我认为标记为正确的答案需要进一步澄清。 getHeight() 的每种字体都没有“错误”,因此我认为手动猜测每种新字体的系数并不是一个好习惯。 猜猜它可能对您的目的很好,只需使用 CapHeight 而不是 Height。

    float height = ( font.getFontDescriptor().getCapHeight()) / 1000 * fontSize;
    

    这将返回与您尝试通过将 Helvetica 的高度校正为 0.865 来获得的值相似的值。但它对任何字体都是通用的。

    PDFBox 文档没有过多解释它是什么。但是您可以查看维基百科 Cap_height 文章中的图像,以更好地了解它是如何工作的,并选择适合您特定任务的参数。

    https://en.wikipedia.org/wiki/Cap_height

    【讨论】:

      【解决方案2】:

      编辑:帽高是我要找的。查看接受的答案。

      在挖掘 PDFBox 的源代码后,我发现这应该可以计算字体高度。

      int fontSize = 14;
      PDFont font = PDType1Font.HELVETICA;
      font.getFontDescriptor().getFontBoundingBox().getHeight() / 1000 * fontSize
      

      虽然方法并不完美。如果您绘制一个高度为 200 的矩形和一个字体大小为 200 的 Y,您会得到使用上述方法计算的字体高度 231.2,即使它实际上打印得比矩形小。

      每种字体都有不同的错误,但对于 helvetica,它接近 13.5%,与字体大小无关。因此,要为 helvetica 获得正确的字体高度,这是可行的......

      font.getFontDescriptor().getFontBoundingBox().getHeight() / 1000 * fontSize * 0.865
      

      【讨论】:

        【解决方案3】:

        也许用这个?

        http://pdfbox.apache.org/apidocs/org/apache/pdfbox/util/TextPosition.html

        似乎是文本的环绕实用程序。不过,如果它导致字体错误,我还没有查看源代码。

        【讨论】:

          【解决方案4】:

          这是一种分割文本并求高度的工作方法

          public float heightForWidth(float width) throws IOException {
              float height = 0;
          
              String[] split = getTxt().split("(?<=\\W)");
              int[] possibleWrapPoints = new int[split.length];
              possibleWrapPoints[0] = split[0].length();
              for (int i = 1; i < split.length; i++) {
                  possibleWrapPoints[i] = possibleWrapPoints[i - 1] + split[i].length();
              }
          
              float leading = font.getFontDescriptor().getFontBoundingBox().getHeight() / 1000 * fontSize;
              int start = 0;
              int end = 0;
              for (int i : possibleWrapPoints) {
                  float w = font.getStringWidth(getTxt().substring(start, i)) / 1000 * fontSize;
                  if (start < end && w > width) {
                      height += leading;
                      start = end;
                  }
                  end = i;
              }
          
              height += leading;
              return height + 3;
          }
          

          【讨论】:

            【解决方案5】:

            对于导入的 True Type 字体,字体的总高度为

            (org.apache.pdfbox.pdmodel.font.PDFont.getFontDescriptor().getDescent() + org.apache.pdfbox.pdmodel.font.PDFont.getFontDescriptor().getAscent() + org.apache.pdfbox.pdmodel.font.PDFont.getFontDescriptor().getLeading()) * point size * org.apache.pdfbox.pdmodel.font.PDFont.getFontMatrix().getValue(0, 0)

            您会发现font.getFontDescriptor().getFontBoundingBox().getHeight() 比上面的值大 20%,因为它在上面的值上包含了 20% 的前导,但是如果你取顶部的值并删除 20%,字体也会紧挨着每个其他

            【讨论】:

            • 您的公式中有多个问题:(A) Descent 是负数;为了使您的公式有意义,应使用其绝对值(即-...getFontDescriptor().getDescent())。 (B) 为了确定 Ascent,不包括重音字符的字形高度;因此,如果您将重音字符视为字体的一部分,则公式不可能正确。此外,您包括point size 而不解释它。这个值不是微不足道的。
            猜你喜欢
            • 2011-08-01
            • 2016-11-17
            • 1970-01-01
            • 2010-09-18
            • 2017-03-15
            • 2014-01-18
            • 2014-03-09
            • 2015-12-14
            • 2014-11-13
            相关资源
            最近更新 更多