iTextSharp v.5.5.3至5.5.6 - 错误展平TextField

时间:2015-08-17 06:30:10

标签: itextsharp textfield

我有问题。我使用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:

Image 1

图片2有错误:

PDF:

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

1 个答案:

答案 0 :(得分:0)

如果pdfStamper.AcroFields.GenerateAppearancestrue,则在展示已通过矩阵属性旋转现有外观的表单字段时,iText(夏普)中存在问题。

原文

Original top of page

GenerateAppearances == true展平后的

如下所示:

GenerateAppearances == true

解决方法

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

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

您现在获得的结果:

GenerateAppearances == false

问题

如果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忽略外观 Matrix 的原因是表单填充过程中的外观生成不应该使用这样的矩阵值:

  

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

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

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

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

  •   
     

ISO 32000-1第12.7.3.3节“变量文字”)

这意味着矩阵

  

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

     

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

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

因此,iTextSharp中的问题实际上仅仅反映了由于表单填写而生成表单字段外观的假设。