なぜ BDF か
メモリ・CPU・消費電力の実測
同じApple M3のMacで、GoとLibreOffice → PDF → PopplerをAC電源で再計測しました。Officeファイルの変換と256 pxの先頭ページサムネイル生成を比較しています。Goは2026-10-09に再計測し、LibreOffice / Popplerは2026-10-06の値です。
| 入力 | RSS: LibreOffice / Go (MiB) | 経過時間: LibreOffice / Go (秒) | CPU時間: LibreOffice / Go (秒) |
|---|---|---|---|
| 小さい DOCX | 161.8 / 43.4 | 0.69 / 0.05 | 0.67 / 0.06 |
| 小さい PPTX | 147.3 / 38.2 | 1.01 / 0.03 | 1.02 / 0.04 |
| 小さい XLSX | 123.7 / 36.0 | 0.65 / 0.04 | 0.63 / 0.04 |
| 合成 XLSX(4シート×3,000行) | 288.3 / 48.7 | 1.55 / 0.23 | 1.62 / 0.30 |
| 合成 PPTX(100スライド) | 1918.9 / 40.8 | 56.38 / 0.12 | 68.30 / 0.19 |
時間・メモリはウォームアップ後の各5回の中央値。RSSは各プロセスの最大常駐メモリ、CPU時間はuser + system、経過時間は起動・変換・保存を含む実時間です。LibreOfficeとPopplerは順番に動くため、ピークメモリは2段階の大きい方、時間は合計です。出力形式と表示結果は異なります。
推定SoC電力量は LibreOffice 4.267 J/文書(ラウンド範囲 3.295〜7.155)、Go 0.242 J/文書(0.241〜0.248)。両実装を同じAC電源で3ラウンド測定しました。
最新結果と測定条件、再計測手順。生ログはGitに保存せず、ローカルの結果ディレクトリに置きます。
オフィススイートを動かさなくてよい
Office のファイルをブラウザでプレビューするには、サーバーで LibreOffice や OpenOffice をヘッドレスで動かして PDF にするのが定番です。プロセスの起動・維持・隔離も必要で、壊れたファイル 1 つでプロセスが詰まることもあります。
BDF の変換器は cgo も外部プログラムも使わない Go のパッケージで、下の表の多くの形式を 1 つのバイナリで変換します。同じコードを WebAssembly にすればブラウザの中でも変換でき(PDF 用が gzip で約 7.3 MB、Office 系・draw.io・CAD・KiCad・フォント用が約 7.8 MB)、ファイルをアップロードする必要すらありません。サムネイルと検索用のテキストも同じプロセスで作れます。ページを描くのは純 Go のラスタライザで、サーバー側にもブラウザは要りません。
必要な変換器だけを選んで組み込める
形式はたくさんありますが、全部を抱える必要はありません。変換器は形式ごとに独立した Go のパッケージで、import されたときに自分の形式を登録します。PDF と Office の文書だけを扱うサービスなら converter/pdf、converter/docx、converter/xlsx、converter/pptx だけを import すれば、バイナリにリンクされるのもそれだけです(全部入りは converter/all)。ブラウザ用の WebAssembly も、PDF 用、Office 系・CAD・KiCad・音楽・フォント用、HTML・Markdown・EPUB 用、画像と音声ファイル用とビルドタグで分かれていて、ページは開いたファイルに要るモジュールだけを取得します。
内容に合った形で見せる
PDF はすべてを紙に切り分けます。スプレッドシートを印刷したページでは、横に長い表がページをまたいで分断されて行を追えず、目当てのセルも見つけにくくなります。固定した見出しや枠線は消え、ブックの中で切り替えていたシートは一続きのページになります。Word の文書もページ単位でしか読めません。
BDF は内容の種類ごとに、3 つのレイアウトモデルを使い分けます。
- 固定サイズのページ — スライド、図面、PDF、アートボード。ページごとに決まった大きさを持ちます。
- 無限平面 — ワークシート。タイルで描き、ウィンドウ枠の固定、行・列見出し、枠線がつきます。シートが印刷ページに切り分けられることはありません。
- フロー — ワープロ文書。ページとしても一続きのスクロールとしても読め、本文の幅で 1 本の長い列に組み直した、ページのない表示も持てます。
1 つの文書は複数の View を持てます。ブックのシート、draw.io の図のページ、DXF のモデル空間とレイアウト、KiCad の回路図のシートと基板の各層はそれぞれ 1 つの View になり、ビューアは表計算ソフトのシートタブのようなタブで切り替えます。文書から別の View へのリンク(#view=ID)も張れます。draw.io のページから別のページへ、KiCad の階層シートから親シートへ、といった具合です。
対応形式
似た性質の形式はまとめて 1 行にしています。拡張子は主なものだけで、すべての拡張子と変換のオプションは対応形式の各ページにあります。
| 形式と主な拡張子 | 表示 | 特徴 |
|---|---|---|
| 文書と本 PDF、EPUB .pdf、.epub |
ページ。本は見開きで開いてめくる | PDF は埋め込みフォントとタグ付き PDF の構造を保つ。EPUB はリフロー型(和文の縦書きも)を本のページに組み、固定レイアウトのマンガは 1 枚ずつのページに |
| 文章 Word、HTML、Markdown .docx、.html、.mhtml、.md |
ページ、または一続きのスクロール | 1 つの組版エンジンで組む。縦書き、数式。HTML はリーダー表示 |
| スライド PowerPoint .pptx |
ページ | マスターとレイアウト、表、グラフ、SmartArt、数式 |
| 表 Excel、CSV・TSV、Apache Parquet .xlsx、.csv、.tsv、.parquet |
シート(無限平面)。シートはタブで | ウィンドウ枠の固定、行・列見出し、条件付き書式。セルを選んで表計算ソフトに貼り付けられる |
| ページレイアウト InDesign .idml |
ページ。綴じ方向どおりに見開きで開く | 連結したフレームをページをまたいで流れるストーリー、マスターページ、和文の縦書き。配置画像は文書と一緒に渡す |
| 図 Visio、draw.io .vsdx、.drawio(図を埋め込んだ .svg、.png も) |
ページ。ページはタブで | 背景ページとレイヤー、ページ間のリンク、AWS などのアイコン |
| CAD の図面とプロット AutoCAD DXF、Jw_cad、SXF、CGM、HP-GL/2 .dxf、.jww、.p21、.sfc、.cgm、.plt |
ページ。モデル空間とレイアウトはタブで | 画層・線種・線の太さをプロッタが描くとおりに |
| 電子回路 KiCad、Gerber・Excellon .kicad_sch、.kicad_pcb、.kicad_pro、.gbr、.drl、それらの ZIP |
ページ。回路図のシート、基板の表・裏・各層はタブで | 基板は基材・銅箔・マスク・シルク・穴の実物の見た目で。階層シートのリンク |
| デザインと画像 Illustrator、Photoshop、TIFF、Windows メタファイル、画像 .ai、.psd、.psb、.tif、.emf、.wmf、.png、.jpg、.svg など |
ページ。アートボードごとに 1 ページ | 画像はデコードせずそのまま格納。SVG は拡大してもぼけない |
| 楽譜 MML、MIDI、MusicXML .mml、.mid、.kar、.musicxml、.mxl |
ページ(五線譜) | ビューアで演奏し、演奏している段をカーソルで追う |
| 音声 MP3、M4A、FLAC、Ogg、WAV、AIFF .mp3、.m4a、.aac、.flac、.ogg、.opus、.wav、.aiff |
再生できる 1 ページのカード | カバーアート、タグ、歌詞と章。ビューアで再生し、歌っている行を示す。サムネイルはカバー、タグはメタデータに |
| フォント TrueType、OpenType、WOFF .ttf、.otf、.ttc、.woff、.woff2 |
スクロール。概要・文字・グリフ・フィーチャーはタブで | 文字とグリフの一覧、OpenType フィーチャーが実際にすること |
パスワード付きの Office 文書と PDF も変換でき、出力は同じパスワードで暗号化します(パスワードと保護モード)。どの形式も同じレンダラで描くので、この下に挙げるページめくり、検索、読み上げは形式を問わず同じように働きます。
ページを読む、めくる
デモビューアはページをスクロールで並べるほか、1 ページずつ、または見開き(左開き・右開き)で表示して、本のようにめくれます。ページは、キー、ページボタン、タップ(綴じ目の先なら次へ、手前なら前へ)、ページの角や外側の端のドラッグでめくれ、めくる動きは WebGL で描きます(前後のページを先にテクスチャとして描いておきます)。システムが視差効果を減らす設定なら、アニメーションなしで切り替わります。めくる途中でなければ、ページの中のテキストはいつでも選択できます。
右綴じの本(direction: "rtl"。縦書きの日本語、右から読むマンガ)は右から左へめくり、EPUB は最初から見開きで開きます(?layout=pages・single・spread・spread-rtl で最初からその表示にできます)。楽譜はビューアで演奏でき、演奏している段にカーソルを示して、それに合わせてページをめくり、スクロールします。
検索と選択
文字は画像に焼き込んでいません。ページの絵の上に、同じ位置・同じ幅で透明なテキストを重ねています。
- ビューアの全文検索は Worker の中で文書全体を探します。行をまたいでも見つかり、NFKC とかなの正規化で、全角と半角、ひらがなとカタカナの違いを越えて見つけ、すべてのヒットの矩形を返します。
- ブラウザ自身のページ内検索(Ctrl+F・⌘F)も、表示しているページの文字を見つけます。
- テキスト選択とコピーは、テキストの層が持つ目印から空白と改行を復元します。ページをまたいでも、連続スクロールの表示でも働きます。
- 表のセルはセル単位で選べます。あるセルから別のセルへドラッグすると、その間の矩形のセルが選ばれます。シート(Excel、CSV、Parquet)は表計算ソフトと同じように、ドラッグ、Shift、行・列の見出し、矢印キーで選べます。コピーするとタブ区切りの値と HTML の表をクリップボードに置くので、表計算ソフトには画像ではなくセルとして貼り付けられます。
アクセシビリティ
構造の層が、見出し・リスト・表・代替テキスト付きの図・リンク・言語をスクリーンリーダーに伝えます。これはタグ付き PDF、PowerPoint と Word の構造、Excel・CSV・Parquet のセルと表の見出し、HTML・Markdown・EPUB の要素から変換したものです。Windows のハイコントラスト表示でも透明な文字が描画に重ならず、ページはキーボードでめくれます。
ブラウザ表示に特化している
命令セットは Canvas 2D と 1 対 1 に対応します。フォントは FontFace に渡す WOFF2、画像はブラウザがデコードできる形式で、Part の圧縮は DecompressionStream で展開できる形式です。pdf.js のような PDF ビューアが数万行かけて実装しているフォントのラスタライズ、画像のデコード、展開はブラウザに任せ、BDF のデコーダとレンダラは TypeScript で約 3,400 行です(レンダラの Worker は gzip で 21 KB)。描画は Worker の OffscreenCanvas で行い、メインスレッドはビットマップを置くだけです。Part は内容アドレスなので、マスターや繰り返し現れる要素は 1 度だけ格納され、ビューアは表示中のページに要る Part だけを Range リクエストや CDN 上の分割形式から取得します。ブラウザ内で変換する PDF は、表示中のページを優先して変換できたページから表示します。
各変換器が何を保ち、どうレイアウトするかは対応形式を、変換と描画がどうつながっているかはアーキテクチャを参照してください。