# Cursor プロジェクト説明(iText7 で PDF に「メモ用レイヤー」を 2 つ追加) ## 目的 既存の PDF に **OCG(Optional Content Group=レイヤー)を 2 つ** 追加し、後からそのレイヤーにメモ(テキスト/図形/注釈)を書き込めるようにします。 Acrobat の「レイヤー」パネルで表示・非表示を切り替えられる **「メモ1」「メモ2」** を作成します。 ## ゴール/受け入れ基準 * 既存 PDF を入力に取り、出力 PDF のカタログに **OCProperties/OCGs** が作成されていること(2 つの OCG)。 * Acrobat / PDF-XChange 等で **レイヤー「メモ1」「メモ2」** が確認でき、ON/OFF 切り替えが可能。 * 追加サンプルとして、各レイヤーに 1 行テキストを描画(または四角形)できること。 * 既存ページのコンテンツは変更しない(上に重ねるだけ)。 ## 技術ポイント(PDF 構造) * iText7 では `PdfLayer`(= OCG)を生成し、`PdfCanvas.beginLayer(layer) ... endLayer()` の間で描画したコンテンツはそのレイヤーに属します。 * 既存 PDF を開いてレイヤーを「追加」するだけなら、iText が **Catalog/OCProperties** を自動で拡張してくれます。 * 初期表示状態(ON/OFF)は `layer.setOn(true/false)` で制御可能。 ## 環境 * 言語:Java 17(推奨 11+) * ビルド:Maven もしくは Gradle * ライブラリ:iText7(kernel / layout) * Maven: ```xml com.itextpdf kernel 8.0.2 com.itextpdf layout 8.0.2 ``` * Gradle: ```gradle implementation "com.itextpdf:kernel:8.0.2" implementation "com.itextpdf:layout:8.0.2" ``` ## プロジェクト構成(推奨) ``` pdf-memo-layers/ ├─ README.md ├─ build.gradle or pom.xml ├─ src/ │ └─ main/java/ │ └─ co/jp/techsor/pdf/ │ ├─ App.java // CLI エントリ │ ├─ PdfMemoLayerService.java // レイヤー作成・描画の中核 │ ├─ LayerDrawingOptions.java // 文字/図形の描画オプション │ └─ util/ │ └─ PdfUtils.java // 共通ユーティリティ └─ samples/ ├─ input.pdf └─ output.pdf (生成物) ``` ## 主要ユースケース 1. **レイヤーだけを追加**(後で編集者が注釈・図形を載せる) 2. **レイヤーにテキスト/図形を同時に配置**(例:右下に “Memo Layer”) 3. **初期状態の切替**(メモ1=ON、メモ2=OFF など) ## CLI 仕様(例) ``` java -jar pdf-memo-layers.jar \ --in samples/input.pdf \ --out samples/output.pdf \ --layer1 "メモ1" --layer2 "メモ2" \ --draw "text:1,100,700,メモ1のサンプル" \ --draw "rect:2,50,50,200,60" \ --l2-on=false ``` * `--draw` は複数指定可。形式: * `text:,,,` * `rect:,,,,` * `--l2-on=false` のように初期表示を切替。 ## 実装概略(擬似コード) ```java try (PdfDocument pdf = new PdfDocument(new PdfReader(inPath), new PdfWriter(outPath))) { // 1) レイヤー(OCG)作成 PdfLayer memo1 = new PdfLayer("メモ1", pdf); memo1.setOn(true); // 初期表示 ON PdfLayer memo2 = new PdfLayer("メモ2", pdf); memo2.setOn(false); // 初期表示 OFF(例) // 2) 必要に応じて描画(各ページの上に重ねる) PdfPage page1 = pdf.getPage(1); PdfCanvas canvas1 = new PdfCanvas(page1); canvas1.beginLayer(memo1); // テキスト描画(iText7 layout を使う場合は Canvas を併用) try (Canvas c = new Canvas(canvas1, page1.getPageSize())) { c.showTextAligned("メモ1のサンプル", 100, 700, TextAlignment.LEFT); } canvas1.endLayer(); PdfPage page2 = pdf.getPage(2); PdfCanvas canvas2 = new PdfCanvas(page2); canvas2.beginLayer(memo2); canvas2.rectangle(50, 50, 200, 60); canvas2.stroke(); canvas2.endLayer(); } ``` ## テスト手順 1. `samples/input.pdf` を用意し、CLI で実行して `samples/output.pdf` を生成。 2. Acrobat で `output.pdf` を開き、**表示 → ナビゲーションパネル → レイヤー** を表示。 3. 「メモ1」「メモ2」の存在と ON/OFF の切り替えで描画が出入りすることを確認。 ## エッジケースと対策 * **暗号化 PDF**:所有者パスワードが必要。`ReaderProperties`/`WriterProperties` で設定。 * **透明度・ブレンド**:必要なら `PdfExtGState` を併用して半透明表現。 * **注釈に載せたい**:注釈は OCG 直付けできないため、描画をレイヤーに、注釈は通常オブジェクトとして扱う(見た目同期が必要)。 * **長文テキスト**:`layout` の `Paragraph` を使用し、行送りとフォント設定を行う。 ## ライセンス注意 iText 7 は AGPL もしくは商用ライセンスです。社内/顧客配布要件に合わせてライセンス選定を行ってください。