ドイツより大きなPDFを作る
(alexwlchan.net)- インターネット上で広まっている「PDFの最大サイズは381km × 381km」という話は、PDF形式自体の限界ではなく、Adobe Acrobat 7.0の実装上の制限に由来する値
- PDF 1.6以降では
/UserUnitによって基本単位である 1/72インチを大きくでき、Acrobat 7.0の最大値75,000が15,000,000インチという上限を作っている - 手作業で作るPDFは
%PDF-1.6、オブジェクト一覧、xref、trailer、startxref、%%EOFで構成され、ページサイズは/MediaBoxと/UserUnitの組み合わせで決まる - Acrobatは
/MediaBoxが14,400、または/UserUnitが75,000を超えても 15,000,000インチとして表示し、/UserUnitの超過は警告なしに無視する - macOS Preview.appは
/UserUnitを無視するが、/MediaBoxにはAcrobatのような上限を設けていないため、宇宙より大きなPDFのように表示されるファイルも作れる
381kmという制限はどこから来たのか
- PDF文書の最大サイズが 381km × 381km だという主張は、昔からインターネット上で繰り返し広まっている
- この数字はPDF形式の限界ではなく、Adobe Acrobatの実装上の制限に由来する
- PDF 1.7仕様によると、ページサイズの制限は次のように整理される
- PDF 1.6以前では、デフォルトのユーザー空間単位は 1/72インチ に固定されていた
- Acrobat 5.0以降のデフォルトページサイズの最大値は
14,400 × 14,400単位、つまり 200 × 200インチ - PDF 1.6以降では、ページ辞書の
/UserUnitでデフォルトのユーザー空間単位の大きさを設定できる - Acrobat 7.0は
/UserUnitの最大値75,000をサポートし、最大ページ寸法 15,000,000インチ を作れる
15,000,000インチは約 381km であり、「PDF version 7」という表現はPDFのバージョンではなく、Adobe Acrobat 7.0に由来するものとみられる
手作業で作るPDFの基本構造
- PDFファイルは先頭にバージョン番号、末尾にEOF表示を持つ
- 例:
%PDF-1.6 - 終端表示:
%%EOF
- 例:
- バージョン番号の後には、ページ、テキスト、グラフィックなどを表すオブジェクト一覧が続く
xrefはオブジェクトの位置を示す相互参照テーブル- PDFリーダーは各オブジェクトがファイルの先頭から何バイト離れているかを確認する
trailerは文書全体のメタデータを含む- ページ数
- 暗号化の有無
- 文書ルートオブジェクト
startxrefはxrefテーブルの開始位置を指す- PDFリーダーはファイル末尾で
startxrefの値を見つけ、xrefテーブルへ移動する
- PDFリーダーはファイル末尾で
- 簡単なPDFファイルを作る記事を参考にすると、赤い四角形のあるPDFを手作業で作れる
オブジェクトとページ定義
- サンプルPDFは4つの主要オブジェクトで構成される
- オブジェクト1: 赤い四角形を描画する streamオブジェクト
- オブジェクト2: 単一ページを定義する
Pageオブジェクト - オブジェクト3: 複数ページの情報を含む
Pagesオブジェクト - オブジェクト4: 文書の主要構造を提供する
Catalogオブジェクト
Pageオブジェクトは、ページ内容を別のオブジェクト参照でつなぐ1 0 Rはオブジェクト番号1、世代番号0を参照する3 0 Rはページ集合であるPagesオブジェクトを参照する
- 手作業でPDFを書くと、オブジェクト位置が変わるたびに
xrefテーブルの値を合わせ直す必要があり、非常に面倒 - 2025年4月16日の更新で、サンプルコードの
xref 0 4が誤った値として訂正された- 実際の相互参照テーブルには5つの項目があるため、
xref 0 5が正しい
- 実際の相互参照テーブルには5つの項目があるため、
/MediaBox と /UserUnit でページを大きくする
- PDFのページサイズは各
Pageオブジェクトで設定される /MediaBox [0 0 300 300]は幅と高さがそれぞれ 300単位 のページを作る- デフォルト単位は1/72インチ
- 300単位は約 4.17インチ
/MediaBoxを600 600に変えると、Acrobatはページを8.33 x 8.33 inと表示する- Acrobatで許容される
/MediaBoxの最大値14400 14400は 200 × 200インチ と表示される- この値を超えるとAcrobatで警告が発生する
/UserUnitを追加すると、デフォルトのユーザー空間単位を大きくできる/UserUnit 2はページの両辺の寸法を2倍にする/MediaBox [0 0 14400 14400]と/UserUnit 2を併用すると、Acrobatは400.00 x 400.00 inと表示する
/UserUnit 75000を適用すると、Acrobatはページを 15,000,000.00 × 15,000,000.00インチ と表示する- これは約381km × 381kmで、元の主張と一致する
- サンプルファイル: biggest.pdf
AcrobatとPreviewの処理の違い
- Acrobatは
/MediaBoxや/UserUnitをさらに大きく設定しても、ページサイズを 15,000,000インチ と表示し続ける /UserUnitの値を75000より大きく設定すると、警告やエラーなしに値が制限される/UserUnitは実際の利用例が多くないようだ- Stack Overflowの回答でも、この値は広く使われていないとしている
- オンラインで例を見つけるのは難しかった
- macOS Preview.appは
/UserUnitをサポートしていない- すべてのPDFをデフォルト単位 1/72インチ として処理する
- その代わり、Preview.appはAcrobatと異なり、
/MediaBoxに大きな上限を設けていない1の後に0が12個付いた幅も受け入れる- この幅は、おおよそ地球と月の間の距離に相当する
- さらに大きな
/MediaBoxの値を入れると、Previewが約 37兆光年四方 のサイズのPDFとして表示するファイルも作れる- サンプルファイル: universe.pdf
- 文書の大部分は空白で、印刷しないよう警告が付いている
1件のコメント
Hacker News のコメント
PDFは技術的にはいろいろな意味でひどいものの、自分の手元に保存しておける自己完結した静的ファイルである点は、いつ消えてもおかしくないユーザー敵対的な動的/SaaSウェブサイトと対照的で素晴らしい
PDF/Aは本当のPDFに近く、危険な余計物の大半を取り除いてくれる
奇妙なPDFのお遊びが好きなら、PDF/Aであり、CSVでもあり、同時にAmiga soundtracker modのサウンドトラックでもあるポリグロットファイルがある: https://www.lab6.com/6
https://www.nytimes.com/2009/07/18/technology/companies/18am...
多くの人はJavaScriptの実行を心配する一方で、PDFファイルは特に問題視せずに使っている
任意のPDFをオープンソースソフトウェアでPDF/Aに変換するには、GhostscriptでPostScriptにしてから戻す方法しかないようだが、GhostscriptはAfferoライセンスなので、いろいろ問題が付いてくる可能性がある
古いGPL版もあり、ほとんどのPDFで動くが、15年ほど前のものだ
以前の職場でPDF/Aを扱わなければならなかったが、まったく楽しいものではなかった
段落を再構成するだけでも大変な労力がかかり、表のパースは言うまでもない
事実上の標準である割には、もっと良くなるべきだし、PDFのマニュアルも本当にひどい
比較としてPNGを分析してみると、最大幅と高さは2147483647、つまり2^31 - 1である
pHYsチャンクで指定できる最低密度は1メートルあたり1ピクセルなので、20億メートルは太陽の直径1.39ギガメートルより大きい: https://en.wikipedia.org/wiki/Orders_of_magnitude_(length)#g...
sCALチャンクはASCII浮動小数点を使うため、はるかに大きな物理サイズも表現できる
1:10,000,000縮尺の世界地図はpHYs基準では幅10m未満だが、sCAL基準では約40,000km幅になる
PDFの幅をキロメートル単位で測り始めた瞬間、自分が良い技術記事を読んでいるのだと分かる
10年以上前にGame of LifeのPostScript実装で作ったPDFを思い出した
まだ動作するようだが、macOS Previewをクラッシュさせる: https://andrewcutler.net/docs/joke/life.pdf
ただしアニメーションは表示されず最終状態だけが見え、FirefoxのPDFビューアでは少しアニメーションが見える
SkimもPreviewに似ているが、グリッドは表示しない
この記事はUmberto Ecoの知的遊戯を思い起こさせる
特に「On the Impossibility of Drawing a Map of the Empire on a Scale of 1 to 1」を思い出す: https://s3.amazonaws.com/arena-attachments/881694/cb6119367b...
https://en.wikipedia.org/wiki/On_Exactitude_in_Science
PreviewはMediaBoxに入れられる値の上限がAcrobatとは違ってなく、1の後ろに0を12個付けた幅も受け入れる
書類インスペクタにはページサイズが352777777777.78 x 10.59cmと表示され、この幅はおおよそ地球と月の間の距離くらいになる
太陽系の全惑星を横一列に並べても、この文書の中に余裕で収まる
結局、定規が必要だったわけだ
352777777777.78cmは3,527,777.7777778kmである
面白い実験だ、alexwlchan
記事には小さな誤りが2つあって、「15,000,000,000.00 in」と「ページサイズが150億インチ」と書いている部分は、1500万インチが正しい
テキストの書式指定が難しいと言っていたが、「Hello World」という2語だけのPDF例なら、フォントオブジェクトを定義し、ストリーム内で
Tfでフォントを使い、Tdで位置を指定し、Tjでテキストを書けばよいテキスト例もありがとう。自分が試していたものと似ているように見えるが、どこかでミスしていたに違いない
仕様上は必要なように見える
このあたりでSteven Wrightを言い換えたくなる
「アメリカの地図を1枚持っている。実物大だ」
地図の上が自分の進んでいる方向なのか北なのか分からないし、昔の地図はいつも北が上だったのに、Google Mapsはそうではないように見えて混乱する
90度回ると地図も一緒に回るのだが、回ったのが地図なのか自分なのかも分からなくなる
止まっていると、どこへ向かっているのか地図には分からないので、方角を知るにはまず動かなければならないようだ
スマートフォンを目の前に掲げると地図の上は空を向くが、地図は上から見下ろすべきなのかも分からない
携帯電話でGoogle Mapsをうまく使うコツが気になる
https://s3.amazonaws.com/arena-attachments/881694/cb6119367b...
https://scomedy.com/quotes/10779
「印刷しないでください」は、プリント爆弾になる準備ができた言葉のように聞こえる
最後にプリンターを使ったとき、Windowsで印刷ジョブをキャンセルするのはほぼ不可能だった
Wi-Fiプリンターが開放されていたり、セキュリティが甘かったりした時代は面白かった
私が見つけた唯一信頼できる方法は、プリンターの電源を切ってキューから印刷ジョブを削除すること
プリンターがすぐそばにないとだめで、なぜこんなに難しいのか分からない
約30年前、Microsoftの夏季インターン面接で、面接官がExcelについてこれと非常によく似た質問をした
こういうテーマは、人の好奇心と潜在的な問題を分解する能力を見るのに、いつでも良い題材になる