【问题标题】:iTextSharp GetWidthPoint() does not include the letter spacingiTextSharp GetWidthPoint() 不包括字母间距
【发布时间】:2016-10-19 11:06:55
【问题描述】:

考虑以下代码:

var path = AppDomain.CurrentDomain.BaseDirectory;
var filePath = Path.Combine(path, "test1.pdf");

using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite))
using (var document = new Document(new Rectangle(PageSize.A4.Width, PageSize.A4.Height)))
using (var writer = PdfWriter.GetInstance(document, stream))
{

    try
    {

        document.Open();

        const string value = "The quick brown fox";

        for (int i = 0; i < 4; i++)
        {

            var chunk = new Chunk(value);

            chunk.SetCharacterSpacing(i);

            var origin = new Phrase(chunk);
            var paragraph1 = new Paragraph(origin);

            document.Add(paragraph1);

            var widthPoint = chunk.GetWidthPoint();

            Debug.WriteLine(widthPoint);

        }

        writer.CloseStream = false;

    }
    finally
    {
        document.Close();
        stream.Close();
    }

}

我正在尝试将段落/块添加到新 PdfPTable 中的单个 PdfPCell。我们无法控制进入单元格的实际文本,并且文本可能会比可用空间长一点。文本要么分成多行,要么流出单元格并被隐藏。

我们的想法是自动减少文本的字母间距(最多为最小数量),以尝试减轻被裁剪的文本。基本上应用一个小的负字母间距,直到文本适合。问题是 widthPoint 的值始终相同,无论应用的字母间距如何。生成的 PDF 清晰地呈现了不同宽度的文本。

有没有办法用字母间距或它的容器来计算文本的实际宽度?块/段落是(我将描述为)盒模型类型元素。也就是说,它们填充了单元格并且始终具有相同的宽度。

不知道如何继续。

这是针对 iTextSharp 版本 5.5.9.0

【问题讨论】:

    标签: c# itext


    【解决方案1】:

    简单地说:你是对的。 Chunk.GetWidthPoint()只计算不带字符或字间距的宽度:

    virtual public float GetWidthPoint() {
        if (GetImage() != null) {
            return GetImage().ScaledWidth;
        }
        return font.GetCalculatedBaseFont(true).GetWidthPoint(Content, font.CalculatedSize) * HorizontalScaling;
    } 
    

    因此,

    有没有办法用字母间距或它的容器来计算文本的实际宽度?

    iTextSharp 5 没有提供开箱即用的功能。但是您可以像这样轻松计算出正确的值:

    float WidthWithCharSpacing = chunk.GetWidthPoint() + chunk.GetCharacterSpacing() * (chunk.Content.Length - 1);
    

    【讨论】:

    • 老实说,我可以发誓我试过了!嘎!谢谢。
    【解决方案2】:

    您可能正在寻找考虑字符间距的GetWidthPointKerned 方法。

    【讨论】:

    • 字距调整是不是问题的全部字符间距。
    • 我不确定你的意思,根据en.wikipedia.org/wiki/Kerning它说“在排版中,字距调整是调整比例字体中字符间距的过程”,如果你想获得字符串宽度,包括字母之间的间距 'GetWidthPointKerned;确实有效,或者至少对我有用。 @Mkl 你能详细说明一下吗?
    • 如果您继续阅读这篇文章,您会发现在数字排版中,字距调整通常应用于字母对,这确实是您提出的GetWidthPointKerned 方法所考虑的:小基于单个字母对的字母间距变化。但是,正如您在 OP 的代码中看到的那样,他使用 chunk.SetCharacterSpacing(i) 将每对字母之间的间距更改为一个常数值,与所讨论的字母无关,并且您提出的 GetWidthPointKerned 方法忽略了此字符间距。
    • 因此,虽然字符间距可能抽象地也属于广义上的字距调整,但在 PDF 内容说明中,特别是在 iText 方法名称中,它们是单独的实体。
    • @mlk 感谢您的澄清,虽然我明白您的意思,但我认为此对话框中包含有价值的信息,对于不直接搜索 op 的其他人来说也是如此。
    猜你喜欢
    • 1970-01-01
    • 2012-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    相关资源
    最近更新 更多