aminophen / dviout-util

Subset of DVIOUT utilities
Other
0 stars 0 forks source link

dvispc: 再発行する pdf:bann の位置 #8

Open aminophen opened 6 years ago

aminophen commented 6 years ago

tests/longspec.dvi を dvipdfmx にそのまま通すと annotation rectangle が各行の「A」をバラバラに囲むが,dvispc で「修正」してから dvipdfmx に通すと annotation rectangle が合体する。

20181012-dvispc-bann-120181012-dvispc-bann-2

dvispc で「修正」した後の 2 ページ目冒頭を見ると以下のようになっている。

 [2]
bop 2 0 0 0 0 0 0 0 0 0 42
xxx4 282 'pdf:bann<</Type/Annot/Subtype/Link/Border[0 0 1]/H/I/C[0 1 1]/A<</S/URI/URI(https://www.tug.org/svn/texlive/trunk/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.formats.functions.code.tex?revision=20236&view=markup)>>>>'
push
down3 982795
push
right3 3997451
xxx1 51 'pdf:dest (page.2) [@thispage /XYZ @xpos @ypos null]'
pop
pop
down4 41484288
push
push
down4 -39649280
down4 37683200
push
down4 -35389440          (<- 1)
push                     (<- 2)
right3 4063232           (<- 3)
fntnum7
setchar65
 "A"
pop

となる(ここで (<-1), (<-2), (<-3) は説明のためにつけた)。この「bop 直後の xxx4」が dvispc によって直前の 1 ページ目から持ち越されたものだが,この場所に pdf:bann があると dvipdfmx はアノテーションを合体させてしまうらしい。さらに調べてみると

らしい。

aminophen commented 6 years ago

どうやら「DVI ファイルの中の同じスタック (push ... pop) 階層の場所」で発行される必要があるらしい(※)。それより外の階層で発行してしまうと,内側の階層を全部囲んでしまう。従って,

[案A]

とする?(ただし,これだと dvipdfmx 的にはかなり冗長になる;なぜなら dvipdfmx は「DVI スタックが同じ階層である限り,何度でも以前のスタックに存在した pdf:bann を持ち越してくれる」から。これは多分 pdfdoc.c の breaking_state.annot_dict が退避-復帰を繰り返しているからのようだ。)

[案B] この冗長性を取り除いて page-independent にするなら

だろうか?

なお,(※) の仕様は結構重要で,dvipdfmx で pdf:bann 〜 pdf:eann の内部に割り込んでいるはずのページノンブルにリンクが付かないのは,「DVI スタックで見た時,本文中の pdf:bann 〜 pdf:eann よりも一階層上にノンブルがあるから」ということらしい。

aminophen commented 6 years ago

ちょっと調べてみてわかったが,難易度的には #4 の方がこちらよりはいくぶん簡単そう(dvi のスタックを数える必要がないという意味で)。ただ #4 #6 いずれも,ページ冒頭・末尾に special を発行するルーチンしかなかったところに,ページ途中の special 増設ルーチンを追加しないといけず,結構厄介。