为何pdf文件无法复制?

为何pdf文件无法复制?

我遇到了一个有趣的问题。很久以前我创建了一个 pdf 文件。可以下载这里。现在,为了回忆一下它是如何生成的,我决定重复该过程并比较 pdf 文件。我快要成功了,但我无法让新旧 pdf 文件看起来一样。我记得我按照通常的方式做了所有事情,我只是改变了边距。

为何pdf文件无法复制?

这是生成新的pdf文件的过程:

1)从以下位置获取最新的 cweb 源ftp://ftp.cs.stanford.edu/pub/cweb/cweb-3.64ah.tgz

2)cwebmac.tex改为{NOS} fith手动{NOS} fitb或使用此命令

perl -i -pe 's/{NOS} fith/{NOS} fitb/' cwebmac.tex

3)将以下内容添加到cwebmac.tex

\let\Blue=\Black
\hoffset=1.52400970458984374999999999999cm
\pageshift=2in
\advance\pageshift by-\hoffset
\advance\hoffset by-1in
\advance\pageshift by-1in

4)构建cweave

touch *.c
make

5)cweave继续cweave.w

./cweave cweave.w

6)生成pdf文件:

SOURCE_DATE_EPOCH=1460880679 pdftex cweave.tex

7) 现在我们将旧 pdf 与新 pdf 进行比较。为此,我们必须解压缩 pdf 文件中的对象。

qpdf --qdf --object-streams=disable cweave.pdf cweave-long.pdf
qpdf --qdf --object-streams=disable cweave-old.pdf cweave-old-long.pdf
diff -u cweave-old-long.pdf cweave-long.pdf

我们在 diff 中看到,新 pdf 中的许多值比旧 pdf 中的值小 0.001。但我无法让这个 0.001 消失。如果我设置\hoffset1.52400970458984375,新 pdf 中的值将0.001大于旧 pdf 中的值。如果我设置\hoffset52400970458984374999999999999,新 pdf 中的值将比0.001旧 pdf 中的值小。我对此完全感到困惑。另外,我记得要设置\hoffset为一些简单的东西,比如1.5cm,而不是我通过反复比较 diff 凭经验构建的这个值。

此外,一些连字符也发生了变化。例如,新旧 pdf 文件中以下内容有所不同:

-/F13 9.9626 Tf 125.8 495.045 Td [(i)]TJ/F3 7.9701 Tf 13.837 0 Td [(Used)-354(in)-354(secti)-1(o)1(n)]TJ
+/F13 9.9626 Tf 125.799 495.045 Td [(i)]TJ/F3 7.9701 Tf 13.837 0 Td [(Used)-354(in)-354(se)-1(ction)]TJ

即如何

[(Used)-354(in)-354(secti)-1(o)1(n)]TJ

不同于

[(Used)-354(in)-354(se)-1(ction)]TJ

? 但更重要的是,为什么有什么不同吗?这个 pdf 代码到底是什么意思?

为何pdftex无法重现pdf文件?

这是下载差异文件的链接:https://www.dropbox.com/s/lvbijcn2689cuye/cweave.diff?dl=1

答案1

最后补充:什么时候<foo> cm = <bar> in对 TeX 成立?

传递数学细节和除非我的数学监督快的调查将 四舍五入为 的整数倍数会得出 ,并且是 的倍数,这是必要<foo>且充分的。f/655361/65536f127

只有这样,才会有某些<bar> in东西给出完全相同的 TeX 维度。将 舍入为的<bar>整数倍数将是的倍数。反之亦然。g/655361/65536g50

例如:我们寻找附近的这样一个维度。我们需要附近0.6in的倍数,因此或。前者是通过(和附近的小数)获得的,后者是通过(和附近的小数)获得的。500.6*65536=39321.639300393500.59967in0.60043in

事实上,对于 TeX,我们有

  • 0.59967in = 1.52316cm = 2840211sp
  • 0.60043in = 1.52510cm = 2843824sp
\number\dimexpr0.59967in\relax =\number\dimexpr1.52316cm \relax

\number\dimexpr0.60043in\relax =\number\dimexpr1.52510cm \relax

\bye

在此处输入图片描述

但是,正如 OP 的主要原因一样,0.6in没有使用cm单位的精确等价物。就单位而言,允许表示为和 的sp可能值是某个整数 的那些。上面,分别是和。N sp<foo> in<bar> cmN = int(3613.5*k)kk786787

更新:解释 TeX 如何扫描尺寸

下文和评论中已澄清,造成差异的原因在于您以前使用in为维度单位,而在重建尝试中使用。此外,使最初以 表示的两个维度之间的差异与直接以 表示结果cm并不完全相同,因为不是TeX 使用的最小单位 的整数。inin1insp

https://tex.stackexchange.com/a/231281/4686我解释了 TeX 如何处理像 这样的维度abc.xyz... pt。这来自tex.pdf(texdoc tex.pdf) 的 §452。事实证明该部分也适用于abc.xyz... in,因此我回想起了结果:

  1. 将分数 abc.xyz... 四舍五入(远离零的四舍五入)为 1/65536 的整数倍

  2. 在这个过程中,算法可能会丢弃(不影响理论结果)小数点后除前17位数字以外的所有数字。

假设我们得到了以对的形式解开的“解包”结果(n, f),它在此阶段表示分数(65536n+f)/65536

现在 TeX 考虑了维度单位。这在 的 §458 中进行了解释tex.pdf。简单的情况是pt(之前在 §453 中处理过),TeX 只是将其放入65536*n+f寄存器中。对于 的情况in,我们在道义上需要这样做(65536*n+f)*7227/100。当然,这里的问题是不要使用整数算术产生溢出。执行此操作的例程在 §107。让我们写x=65536*n+f。操作(这里简化了,没有符号,没有溢出截距)是

t<- (x mod 32768)*7227

u <- (x div 32768) * 7227 + (t div 32768)

v <- (u 模 100) * 32768 + (t 模 32768)

结果<- 32768 * (u div 100) + (v div 100)

澄清 准确地说,TeX 不是将此例程应用于整数x=65536 n + f,而是应用于(半字)整数n,上面的例程还返回“余数” v mod 100,然后将其与f和比例适当组合7227/100,这样几乎直到最后数据都保持形状,(N, F)表示N + F/65536精确值F被截断为整数;在最后一步,attach_fraction子例程将其放入y = 65536*N+F寄存器中。但这个最终整数y与上面的过程应用于完全相同x = 65536 n +f。由于算术溢出,这不可能直接实现。

按照步骤x = 32768 q + rt = 7227ru=7227q + int(7227r/32768) = 7727x/32768 - 7227r/32768 + int(7227r/32768)这意味着u(是整数)=7227x/32768 - d0<= d < 1。因此u = int(7227x/32768)。记u =100*(u div 100) + (u mod 100) = 100*(RESULT/32768 - (v div 100)/32768) + (v/ 32768 - (t mod 32768)/32768) = 100*RESULT/32768 + (v mod 100)/32768 - (t mod 32768)/32768,我们得到RESULT = x*7227/100 - 32768*d/100 - (v mod 100)/100 + (t mod 32768)/100。但dt/32768 - int(t/32768)= (t mod 32768)/32768,事实上。因此所有简化为RESULT= x*7227/100 - (v mod 100)/100。由于RESULT是整数,并且x*7227是整数,这意味着 ,确切地说RESULT是 截断x*7227/100为整数。

我们可以将整个事情总结为:

  1. 第一的圆形的将小数转换为的abc.xyz..整数倍。这样做时,我们只需保留输入的 17 位小数。x1/65536

  2. 乘以转换因子72.27,然后截短为整数单位sp

啊,该死的,我真想说明一下cm。那么,§458 中的转换系数就是7227/254,上面的所有内容都100替换为254

让我们这样看一下1.52400970458984374999999999999cm。首先,我们只需要小数点后 17 位数字。计算数字,看看我们是否可以将输入简化为1.52400970458984374。然后我们需要乘以65536并四舍五入。选择您喜欢的引擎。有些人喜欢 Maple 等。其他人喜欢xint

$ rlwrap etex -jobname worksheet
This is pdfTeX, Version 3.14159265-2.6-1.40.17 (TeX Live 2016) (preloaded format=etex)
 restricted \write18 enabled.
**xintexpr.sty
entering extended mode
(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xintexpr.sty
(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xintfrac.sty
(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xint.sty
(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xintcore.sty
(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xintkernel.sty))))
(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xinttools.sty))
*\def\x #1;{\message{\xinttheiexpr[40] #1\relax}}% (this rounds)

*\x 65536*1.52400970458984374;
99877.4999999999993446400000000000000000000000
*\x 65536*1.52400970458984375;
99877.5000000000000000000000000000000000000000
*

这里我们处于一个边界情况,第一种情况给出99877。然后我们执行第二步,即99877*7227/254

*\x 99877*7227/254;
2841775.9015748031496062992125984251968503937008

我们必须截断它:结果是2841775sp

在第二种情况下,我们首先通过四舍五入得到99878,然后我们必须评估99878*7227/254

*\x 99878*7227/254;
2841804.3543307086614173228346456692913385826772

因此结果是2841804sp

现在我们来看看规范的情况0.6 in。我们重复上面的操作。首先0.6*65536=39321.6将 舍入为39322。然后39322*7227/100 = 2841800.94将 截断为2841800sp

您将在下面找到所有这些值。

记录显示1.4in1.4*65536=91750.4,四舍五入为,91750然后91750*7227/100=6630772.5截断为6630772sp



这不是一个答案,但对于评论来说太长了

cm当时使用的是尺寸单位吗?

编辑我认为你正在使用0.6in。请参见底部。

cm作为尺寸单位存在(目前令我感到惊讶,因为我已经完全忘记了尺寸的 TeX 输入过程的细节)敏感性。

{

\dimen2=1.52400970458984374999999999999cm

\number\dimen2

\dimen2=1.52400970458984375cm

\number\dimen2

\dimen2=1.52400970458984374cm

\number\dimen2

}


\input xintexpr.sty

\xinttheiexpr [50] 1.52400970458984374999999999999*72.27/2.54*65536\relax

\xinttheiexpr [50] 1.52400970458984375*72.27/2.54*65536\relax


\xinttheiexpr [50] 1.52400970458984374*72.27/2.54*65536\relax


\bye

在此处输入图片描述


更新:

{

\dimen2=1.52400970458984374999999999999cm

\number\dimen2

\dimen2=1.52400970458984375cm

\number\dimen2

\dimen2=1.52400970458984374cm

\number\dimen2

}


\input xintexpr.sty

\xinttheiexpr [50] 1.52400970458984374999999999999*72.27/2.54*65536\relax

\xinttheiexpr [50] 1.52400970458984375*72.27/2.54*65536\relax


\xinttheiexpr [50] 1.52400970458984374*72.27/2.54*65536\relax


\number\dimexpr 2.54cm\relax


\number\dimexpr 1in\relax


\number\dimexpr 254cm\relax


\number\dimexpr 100in\relax



\xinttheiexpr [50] 1.52400970458984374/2.54\relax


{

\dimen2=0.6in

\number\dimen2

}

\bye

在此处输入图片描述

% TeX value

{

\dimen2=0.6in

\number\dimen2

}

% exact value:

\xinttheiexpr [10] 0.6*72.27*65536\relax

\bye

在此处输入图片描述

相关内容