initial commit
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
# 02 全体アーキテクチャ
|
||||
|
||||
## 採用構成
|
||||
|
||||
Qt 6 / C++20 / Qt Quickをアプリケーション基盤とし、PDFは独立したPDFiumワーカー、HTML・EPUBはQt WebEngineで描画する。CMakeで構成し、両OSの依存バージョンを同じリリース単位で固定する。具体的なQtパッチ版・PDFiumコミットは実装開始時に選ぶ。
|
||||
|
||||
Qt PDFはアプリのPDF処理には使わない。PDFiumの公開APIにアクセスする窓口を一つにし、構造タグの読取りも同じワーカーに閉じ込める。Qt WebEngine内蔵のPDFビューアは無効化する。Qt WebEngine自身の内部依存に含まれるPDFiumまで配布物から除去できるとは想定しない。
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
UI[Qt Quick Reader Shell] --> APP[Application Services]
|
||||
APP --> BROKER[Main Process / File Broker]
|
||||
BROKER --> PDF[Sandboxed PDFWorker / PDFium]
|
||||
BROKER --> ARCHIVE[Sandboxed ArchiveWorker]
|
||||
BROKER --> WEB[Qt WebEngine / Isolated Content]
|
||||
APP --> STORE[Config and State Store]
|
||||
PDF --> UI
|
||||
ARCHIVE --> BROKER
|
||||
BROKER --> ROOT[Document Scoped Resources]
|
||||
ROOT --> WEB
|
||||
```
|
||||
|
||||
矢印は論理的な要求・応答を表す。PDFWorker・ArchiveWorkerは別OSプロセスであり、Qt WebEngineは独自のマルチプロセス構成を持つ。主プロセスから子プロセスを起動するだけではOSによるアクセス制限は成立しないため、07の隔離条件を別途満たす。
|
||||
|
||||
## 責務分割
|
||||
|
||||
| 層・要素 | 責務 | 保有しない責務 |
|
||||
|---|---|---|
|
||||
| Reader Shell | 本文領域、目次、一覧、ステータス、コマンド欄、アクセシブル名 | 形式固有の解析、任意ファイル読取り |
|
||||
| Input Router | モード・フォーカス・IMEを考慮したキー解釈、コマンド生成 | PDFページ番号への直接変換 |
|
||||
| Document Controller | セッション、遷移、位置、戻る/進む、エラーの統括 | 描画エンジンの内部API露出 |
|
||||
| Navigation Service | アダプターの目次・見出し・リンクを共通モデルへ変換 | 見た目だけによる見出しの推測 |
|
||||
| Render Scheduler | 可視域優先、先読み、取消し、キャッシュ、世代管理 | ファイルの権限判定 |
|
||||
| Format Adapter | PDF/HTML/EPUB固有の能力・位置・描画の変換 | 他形式の特例をUIへ要求すること |
|
||||
| File Broker | 開く操作で許可されたファイル、範囲読取り、仮想資源の提供 | PDF/XML/HTML/画像の主プロセス内解析 |
|
||||
| PDFWorker | PDFium初期化、文書解析、ページ描画、文字・構造・リンク抽出 | 外部通信、原本文書の書込み |
|
||||
| ArchiveWorker | ZIP検証・展開、EPUB XML解析、文書資源索引 | 任意パスへの書込み、外部実体参照 |
|
||||
| Web Content Host | docスキーム、通信遮断、DOMナビゲーション、本文表示 | アプリ全体の権限や設定へのアクセス |
|
||||
| Settings / State Store | 検証済み設定とローカル読書状態の保存 | 文書由来スクリプトの評価 |
|
||||
|
||||
依存の向きはUI→アプリケーション→抽象インターフェース。形式固有コードは抽象インターフェースを実装する。PDFium、WebEngine、OS APIはそれぞれの境界内へ閉じ込める。
|
||||
|
||||
## 文書を開く流れ
|
||||
|
||||
1. UIがOSファイル選択または明示されたローカルパスをFile Brokerへ渡す。Brokerは通常ファイル・権限・実体パス・容量を確認する。
|
||||
2. 拡張子と先頭の限定的なシグネチャを照合する。ZIPとEPUBの詳細判定はArchiveWorkerで行う。HTMLは拡張子/MIMEと文字コード情報から扱い、文書本文を主プロセスで解釈しない。
|
||||
3. 新しいsessionIdとgenerationを発行する。既存の文書は新文書の入口検証が済むまで保持し、失敗時に元の位置へ戻れるようにする。
|
||||
4. PDFは読取り専用ハンドルまたは範囲読取りチャネルをPDFWorkerへ渡す。HTMLは選択ファイルの親ディレクトリを許可ルート候補にし、ZIP/EPUBは検証済みのセッション用資源集合を構築する。
|
||||
5. 最初に必要な本文と最低限のメタデータを要求する。全ページのサムネイル、全文字抽出、全ファイルのハッシュ計算が終わるまで本文表示を待たせない。
|
||||
6. 初期本文が表示できた時点でReadyへ移行し、目次・見出し・先読みを低優先で進める。準備途中の目次は「読込中」とし、「目次なし」と区別する。
|
||||
7. 新文書のコミット後に旧セッションを破棄し、旧要求・共有メモリ・一時資源を解放する。旧generationの応答は採用しない。
|
||||
|
||||
複数文書を常駐させない。切替中の旧文書保持は一時的な例外とし、メモリ圧迫時は最後の表示画像と復帰位置だけを保つ。
|
||||
|
||||
## 描画・スケジューリング
|
||||
|
||||
PDFiumのAPI呼出しはワーカー内で直列化する。複数スレッドから無保護で呼び出さない。最初はアクティブ文書につきPDFWorker一つとし、追加並列化は性能実測後の変更とする。PDFiumのスレッド条件は[公開API](https://pdfium.googlesource.com/pdfium/+/refs/heads/main/public/fpdfview.h)を参照する。
|
||||
|
||||
優先度は「新しい可視ページ→可視ページの高解像度化→移動方向の隣接ページ→逆方向→サムネイル→検索索引/構造抽出」。先読みはまず前後1ページまでとし、キャッシュ余裕とキー操作から調整する。解析中にUIスレッドを同期的に待たせない。
|
||||
|
||||
拡大したページは512×512デバイスピクセルのタイルを基本とし、外周に2ピクセルの描画余白を持たせて表示時に切り落とす。CropBox、回転、倍率、DPRを含む変換行列をタイルとリンク・文字の当たり判定で共有する。タイルの継ぎ目・端の欠落は08の必須試験で確認する。
|
||||
|
||||
倍率変更中は既存画像を暫定拡大し、新しい倍率で再描画する。旧倍率の応答が新しい画面を上書きしないようgenerationとrenderRevisionを検証する。リサイズだけでは全文書を再解析しない。
|
||||
|
||||
PDFの段階描画を利用できる処理は短い区間で取消しを確認する。中断不能なデコードや解析はワーカー監視の期限で扱い、UI側の取消し完了とワーカーの実処理終了を同一視しない。
|
||||
|
||||
## キャッシュと資源管理
|
||||
|
||||
| 資源 | 方針 | 初期提案 |
|
||||
|---|---|---|
|
||||
| PDF画像タイル | バイト数基準LRU、可視タイル優先 | 256 MiB、設定可能 |
|
||||
| PDFページオブジェクト | 現在・前後を保持し不要分を閉じる | 前後1ページ |
|
||||
| サムネイル | パネル表示時に可視行から作る | 64 MiB以内で画像予算と調整 |
|
||||
| WebEngine | 文書セッション用off-the-record profile | 永続Cookie・遠隔cacheなし |
|
||||
| ZIP展開 | 安全検証済み専用ディレクトリ、一時資源 | 上限は03・07 |
|
||||
| 読書状態 | 小さなJSON、画像や本文は保存しない | 06を参照 |
|
||||
|
||||
PDFの画像キャッシュ予算はアプリ全体のRSS上限を意味しない。WebEngine、GPU、パーサー、一時バッファは別に消費するため、08で子プロセス込みの総使用量を測る。メモリ圧迫時は先読み停止→不可視キャッシュ解放→解像度抑制の通知→文書処理停止の順で対応する。
|
||||
|
||||
## 拡張の契約
|
||||
|
||||
新形式の追加はFormatAdapterの実装、型判定の登録、能力情報、位置型の追加、共通適合試験への登録で行う。UIは能力情報を見てページ一覧・見出し・検索の可否を決める。画面内へ形式名による条件分岐を散在させない。
|
||||
|
||||
キーはCommand Registry内の安定したcommandIdに対応する。新しい操作は同じ入口へ登録し、既定キーがない操作もコマンド欄から実行できる。設定ファイルはスキーマに定義された値だけを受け付ける。
|
||||
|
||||
初期版の拡張は配布元がビルド時に組み込むモジュールに限る。第三者の任意コードを読み込むプラグイン機構は将来設計とする。将来導入する場合も、文書がプラグインや設定を自動的に選択・実行することは許可しない。
|
||||
|
||||
## 主な依存とビルド境界
|
||||
|
||||
| 部分 | 採用案 | 管理単位 |
|
||||
|---|---|---|
|
||||
| UI・共通基盤 | Qt Core / Gui / Quick / Qml / Quick Controls、C++20 | 同一Qtリリース |
|
||||
| HTML・EPUB本文 | Qt WebEngine / WebEngineQuick | Qtと整合したChromium依存 |
|
||||
| PDF | PDFium公開C API、V8/XFA無効ビルドを基本 | 固定コミット・ビルドオプション |
|
||||
| ZIP・XML | 維持管理されているライブラリをArchiveWorkerへ組込み | G0でZIP64・文字コード・制限設定を確認し固定 |
|
||||
| 設定 | TOML 1.0互換パーサー、独自スキーマ検証 | parser版とschema_versionを別管理 |
|
||||
| IPC | 長さ付きCBORメッセージと制御された共有バッファ | protocolVersion |
|
||||
|
||||
ZIP・TOML等のライブラリ名は、制限付き処理・ライセンス・更新頻度を確認してG0で固定する。ライブラリ選定未了でも、受け入れるデータと制限は03・05・06・07で固定する。
|
||||
Reference in New Issue
Block a user