【问题标题】:iTextSharp v. 5.5.3 to 5.5.6 - error flattening TextFieldiTextSharp v. 5.5.3 到 5.5.6 - 展平 TextField 时出错
【发布时间】:2015-08-17 06:30:09
【问题描述】:

我有问题。我使用 iTextSharp v.(5.5.3 到 5.5.6)。 我有一个 PDF 文件和 1 页。 在一边,我有 4 个 TextField(旋转:0、90、180、270)和一个红色多边形 我的页面旋转设置为 270

我可以展平页面

在代码中,我设置

stamper.AnnotationFlattening = true;
stamper.FormFlattening = true;

展平后我的 2 TextField 旋转不正确

原始 PDF 的图 1:

图片 2 有错误:

PDF:

http://www.pdf-archive.com/2015/08/20/wyslac/

【问题讨论】:

  • 请分享有问题的 PDF。您可以通过公开共享(例如在 google drive 或 Dropbox 上)执行此操作,然后在此处发布链接。
  • 添加PDF文件链接
  • 我在回答中提到的解决方法对您有用吗?
  • 是的。有用。谢谢

标签: itextsharp textfield


【解决方案1】:

如果pdfStamper.AcroFields.GenerateAppearancestrue,则通过Matrix 属性将现有外观旋转的表单字段展平时,iText(Sharp) 中会出现问题。

原版

GenerateAppearances == true 展平后看起来像这样:

解决方法

由于文档已有外观流,您可以关闭GenerateAppearances

stamper.AcroFields.GenerateAppearances = false;
stamper.AnnotationFlattening = true;
stamper.FormFlattening = true;

你现在得到的结果:

问题

如果GenerateAppearances == true,则 iTextSharp(在展平表单时)首先查看字段是否已经有外观。如果该字段有一个,iTextSharp 只会尝试将现有外观整齐地适合表单字段的矩形。不幸的是,它 (a) 忽略了现有的表单字段 Matrix 条目,并且 (b) 用一个新的矩阵替换它来进行拟合。如果外观通过其Matrix 进行旋转,则该旋转将丢失,而是将值拉伸以适合方向错误的矩形。

if (acroFields.GenerateAppearances) {
    if (appDic == null || as_n == null) {
        [...]
    } else if (as_n.IsStream()) {
        PdfStream stream = (PdfStream) as_n;
        PdfArray bbox = stream.GetAsArray(PdfName.BBOX);
        PdfArray rect = merged.GetAsArray(PdfName.RECT);
        if (bbox != null && rect != null) {
            float rectWidth = rect.GetAsNumber(2).FloatValue - rect.GetAsNumber(0).FloatValue;
            float bboxWidth = bbox.GetAsNumber(2).FloatValue - bbox.GetAsNumber(0).FloatValue;
            float rectHeight = rect.GetAsNumber(3).FloatValue - rect.GetAsNumber(1).FloatValue;
            float bboxHeight = bbox.GetAsNumber(3).FloatValue - bbox.GetAsNumber(1).FloatValue;
            float widthCoef = Math.Abs(bboxWidth != 0 ? rectWidth / bboxWidth : float.MaxValue);
            float heightCoef = Math.Abs(bboxHeight != 0 ? rectHeight / bboxHeight : float.MaxValue);

            if (widthCoef != 1 || heightCoef != 1)
            {
                NumberArray array = new NumberArray(widthCoef, 0, 0, heightCoef, 0, 0);
                stream.Put(PdfName.MATRIX, array);
                MarkUsed(stream);
            }
        }
    }
}

(PdfStamperImp 方法FlatFields)

背景

iTextSharp之所以忽略矩阵的外观是因为在表单填写过程中的外观生成不应该使用这样的矩阵值:

对于非富文本字段,外观流(与所有外观流一样,是一个表单 XObject)的表单字典的内容初始化如下:

  • 资源字典 (Resources) 应使用交互式表单字典的 DR 条目中的资源创建(参见表 218)。

  • 边界框(BBox)的左下角设置为表单坐标系中的坐标(0, 0)。框的顶部和右侧坐标取自注释矩形的尺寸(小部件注释字典中的 Rect 条目)。

  • 外观流的表单字典中的所有其他条目都设置为其默认值(参见 8.10,“表单 XObjects”)。

ISO 32000-1 的第 12.7.3.3 节“可变文本”)

这意味着矩阵

Matrix 数组 (可选) 一个包含六个数字的数组,指定表单矩阵,将表单空间映射到用户空间(参见 8.3.4,“转换矩阵”) .默认值:单位矩阵[1 0 0 1 0 0]。

(表 95 – 特定于类型 1 表单字典的附加条目 - 在第 8.10.2 节“表单字典”中,ibidem

因此,根据规范在填写期间创建的表单字段外观流可以假定具有标识 Matrix 值,并且没有旋转。

所以 iTextSharp 中的问题实际上只是反映了表单字段出现是由于表单填写而产生的假设。

【讨论】:

    猜你喜欢
    • 2018-08-04
    • 1970-01-01
    • 2021-01-23
    • 2015-11-21
    • 2019-04-01
    • 2013-10-23
    • 2015-01-19
    • 1970-01-01
    相关资源
    最近更新 更多