Adobe PDF规范中是否有文本字符串变量类型?

时间:2014-11-23 18:57:54

标签: pdf pdf-generation

在下面的示例中(来自gnupdf.org/Introduction_to_PDF;也相关:How to generate plain-text source-code PDF examples that work in a document viewer?),文字是使用以下方式逐字撰写的:

(Hello, world!) Tj

有没有办法存储这个“Hello,world!”在一个变量(字典?)中,比如/MyStringVar,然后使用类似的东西输出多个地方:

(/MyStringVar) Tj

(我已尝试过上述内容,无法使其正常工作; /MyStringVar逐字解释)

以下是代码hello.pdf

%PDF-1.4

1 0 obj  % entry point
<<
  /Type /Catalog
  /Pages 2 0 R
>>
endobj

2 0 obj
<<
  /Type /Pages
  /MediaBox [ 0 0 200 200 ]
  /Count 1
  /Kids [ 3 0 R ]
>>
endobj

3 0 obj
<<
  /Type /Page
  /Parent 2 0 R
  /Resources <<
    /Font <<
      /F1 4 0 R
    >>
  >>
  /Contents 5 0 R
>>
endobj

4 0 obj
<<
  /Type /Font
  /Subtype /Type1
  /BaseFont /Times-Roman
>>
endobj

5 0 obj  % page content
<<
  /Length 44
>>
stream
BT
70 50 TD
/F1 12 Tf
(Hello, world!) Tj
ET
endstream
endobj

xref
0 6
0000000000 65535 f
0000000010 00000 n
0000000079 00000 n
0000000173 00000 n
0000000301 00000 n
0000000380 00000 n
trailer
<<
  /Size 6
  /Root 1 0 R
>>
startxref
492
%%EOF

2 个答案:

答案 0 :(得分:1)

PDF没有像PostScript那样的变量。可能接近你想要实现的东西(输出相同的文本多个位置)是一个表单XObject。就像页面一样,它有一个带有图形对象的内容流,例如(Hello, world!) Tj,它可以通过图形Do运算符在页面(或另一个XObject)上绘制。其操作数对应于页面的Resources字典中的XObject字典中的键。 PDF看起来像这样。 (请注意,流长度,交叉引用表和预告片或不再有效,因此请考虑此伪PDF。)

%PDF-1.4

1 0 obj  % entry point
<<
  /Type /Catalog
  /Pages 2 0 R
>>
endobj

2 0 obj
<<
  /Type /Pages
  /MediaBox [ 0 0 200 200 ]
  /Count 1
  /Kids [ 3 0 R ]
>>
endobj

3 0 obj
<<
  /Type /Page
  /Parent 2 0 R
  /Resources <<
    /Font <<
          /F1 4 0 R
    >>
    /XObject  <<
              /A 6 0 R  % XObject /A is obj 6 0
    >>
  >>                    % /Resources must close here
  /Contents 5 0 R
>>
endobj

4 0 obj
<<
  /Type /Font
  /Subtype /Type1
  /BaseFont /Times-Roman
>>
endobj

5 0 obj  % page content
<<
  /Length 44
>>
stream
BT
70 50 TD    % this has no effect on `/A Do` - only on the "manual" `Tj`
/A Do       % do the drawing of XObject A
/F1 12 Tf   % without this line: "Error: No font in show;"
% if without TD, then the next text is just appended
%-10 50 TD
0 0 TD      % "Td/TD move to the start of next line"; but here like \r
(Hello, world - manual!) Tj
ET
endstream
endobj

6 0 obj
  << /Type /XObject
     /Subtype /Form
     /FormType 1
     /BBox [ 0 0 1000 1000 ]
     /Matrix [ 1 0 0 1 0 0 ]
     /Resources << /ProcSet [ /PDF ] >>
     /Length 58
  >>
stream
  %70 50 TD     % without this `TD` setting, `/A Do` places this in 0,0 - bottom left corner
  /F1 12 Tf
  (Hello, world!) Tj
endstream
endobj

xref
0 7
0000000000 65535 f
0000000010 00000 n
0000000079 00000 n
0000000173 00000 n
0000000301 00000 n
0000000380 00000 n
0000000450 00000 n
trailer
<<
  /Size 7
  /Root 1 0 R
>>
startxref
600
%%EOF

evince中的输出:

hello-evince.png

编辑 XObject形式的文本出现在左下角,因为当前转换矩阵等于show string操作时的单位矩阵。 XObject形式的初始CTM等于[调用Do时父流中的CTM]和[XObject字典形式中的Matrix条目]的串联。在这种情况下哪个是身份。文本矩阵不会从父流传播到表单XObject。

答案 1 :(得分:0)

作为@Frank答案的附录:

偏差

答案中PDF中的PDF specification存在一些偏差。

    页面内容流(对象5)中的
  • 从文本对象中提取XObject A

    BT
    70 50 TD    % this has no effect on `/A Do` - only on the "manual" `Tj`
    /A Do       % do the drawing of XObject A
    

    这是不允许的,参见8.2节,特别是figure 9的结尾:XObjects只能插入页面内容或XObject的页面描述级别。

  • 在XObject内容流(对象6)中引用了一种字体

    /F1 12 Tf
    

    但没有定义字体资源:

    /Resources << /ProcSet [ /PDF ] >>
    

    这是不允许的, Tf 运算符应指定字体资源的名称 - 即当前资源的 Font 子字典中的条目字典(规范的第9.2.2节),这里是XObject的资源字典,而不是页面。

    在PDF格式的早期版本中,如果省略资源条目,XObject可以继承页面的资源...此构造已过时,不应由符合编写者使用(PDF规范的第7.8.3节)和当前的示例中,资源条目甚至都没有被省略。

  • 在XObject内容流(对象6)中,显示运算符 Tj 的文本在文本对象外使用:

    stream
      %70 50 TD     % without this `TD` setting, `/A Do` places this in 0,0 - bottom left corner
      /F1 12 Tf
      (Hello, world!) Tj
    endstream
    

    这是不允许的,参见第8.2节,特别是figure 9的结尾:显示运算符的文本只允许在文本对象中,并且由于XObject不能在文本对象中使用,因此不能将此流视为一个。

尽管它显示了XObject,但是,对于PDF有效性问题,evince似乎相当宽容,甚至比Adobe Reader更宽容,因为Adobe Reader已经非常宽容但是将PDF显示为:

hello.pdf as displayed by Acrobat Reader

即。它根本不显示XObject。

改编样本

本节包含一个更接近规范的改编样本。

此外,OP还希望更自由地定位XObject:

%PDF-1.4

1 0 obj  % entry point
<<
  /Type /Catalog
  /Pages 2 0 R
>>
endobj

2 0 obj
<<
  /Type /Pages
  /MediaBox [ 0 0 200 200 ]
  /Count 1
  /Kids [ 3 0 R ]
>>
endobj

3 0 obj
<<
  /Type /Page
  /Parent 2 0 R
  /Resources <<
    /XObject  <<
        /A 6 0 R
    >>
  >>
  /Contents 5 0 R
>>
endobj

4 0 obj
<<
  /Type /Font
  /Subtype /Type1
  /BaseFont /Times-Roman
>>
endobj

5 0 obj  % page content
<<
  /Length 588
>>
stream
 % draw xobject at 0, 0
 /A Do
 % draw xobject at 20, 180
 q
  1 0 0 1 20 180 cm
  /A Do
 Q
 % draw xobject at 100, 100, with different scales and rotations applied
 q
  1 0 0 1 100 100 cm
  /A Do
  0.7 0.5 -0.5 0.7 0 0 cm
  /A Do
  0.7 0.5 -0.5 0.7 0 0 cm
  /A Do
  0.7 0.5 -0.5 0.7 0 0 cm
  /A Do
  0.7 0.5 -0.5 0.7 0 0 cm
  /A Do
  0.7 0.5 -0.5 0.7 0 0 cm
  /A Do
  0.7 0.5 -0.5 0.7 0 0 cm
  /A Do
  0.7 0.5 -0.5 0.7 0 0 cm
  /A Do
  0.7 0.5 -0.5 0.7 0 0 cm
  /A Do
  0.7 0.5 -0.5 0.7 0 0 cm
  /A Do
 Q
 % draw xobject at 120, 180, skewed somewhat
 q
  1 0 0.3 1 120 180 cm
  /A Do
 Q
endstream
endobj

6 0 obj
  << /Type /XObject
     /Subtype /Form
     /FormType 1
     /BBox [ 0 0 1000 1000 ]
     /Matrix [ 1 0 0 1 0 0 ]
     /Resources <<
        /ProcSet [ /PDF ]
        /Font <<
          /F1 4 0 R
     >>
  >>
     /Length 130
  >>
stream
 BT
  /F1 12 Tf
  % To not cut off stuff below the base line, namely parts of the comma
  1 0 0 1 0 3 Tm
  (Hello, world!) Tj
 ET
endstream
endobj

xref
0 7
0000000000 65535 f
0000000010 00000 n
0000000079 00000 n
0000000173 00000 n
0000000301 00000 n
0000000380 00000 n
0000000450 00000 n
trailer
<<
  /Size 7
  /Root 1 0 R
>>
startxref
600
%%EOF

(交叉引用条目和流长度肯定是错误的。)

此结果(如Adobe Reader中所示):

Screenshot of adapted sample

所有&#34;你好,世界!&#34;实例是使用PDF的单个XObject生成的。