# 機能設計書 74-Pen

## 概要

本ドキュメントは、Avaloniaフレームワークにおけるペン機能（Pen）の設計仕様を記述する。Penは、線や図形の輪郭を描画するためのストロークスタイルを定義し、太さ、色、破線パターン、端点スタイルなどを制御する。

### 本機能の処理概要

Penは、図形や線の描画における輪郭線（ストローク）の外観を定義するグラフィックスコンポーネントである。ブラシによる色指定、線の太さ、破線スタイル、線端のキャップスタイル、線結合スタイル、マイター制限など、線描画に必要なすべての属性を一元管理する。

**業務上の目的・背景**：図形描画において、塗りつぶし（Fill）だけでなく輪郭線（Stroke）の制御も重要である。Penシステムにより、様々な線スタイル（実線、破線、点線など）や端点処理（丸、角、平ら）を柔軟に設定でき、グラフ、チャート、図形エディタなど多様なアプリケーションで高品質な線描画を実現できる。

**機能の利用シーン**：Shape.StrokeプロパティからのPen生成、DrawingContext.DrawLine()での線描画、DrawingContext.DrawGeometry()での輪郭描画、カスタム描画でのペン指定など。

**主要な処理内容**：
1. ブラシ（Brush）による線色の管理
2. 線の太さ（Thickness）の管理
3. 破線スタイル（DashStyle）の管理
4. 線端キャップ（LineCap）の管理
5. 線結合スタイル（LineJoin）の管理
6. マイター制限（MiterLimit）の管理

**関連システム・外部連携**：DrawingContext、Shape系コントロール（Rectangle、Ellipse、Line、Path等）、Compositor描画システムと連携する。

**権限による制御**：本機能は純粋な描画機能であり、特別な権限制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 73 | Drawing | 補助機能 | 図形描画時のストローク指定 |

## 機能種別

グラフィックス基盤 / ストロークスタイル定義

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Brush | IBrush? | No | 線の色を定義するブラシ | null可（描画なし） |
| Thickness | double | No | 線の太さ | デフォルト: 1.0 |
| DashStyle | IDashStyle? | No | 破線パターン | null可（実線） |
| LineCap | PenLineCap | No | 線端のスタイル | デフォルト: Flat |
| LineJoin | PenLineJoin | No | 線結合のスタイル | デフォルト: Miter |
| MiterLimit | double | No | マイター結合の制限値 | デフォルト: 10.0 |

### PenLineCap列挙値

| 値 | 説明 |
|---|------|
| Flat | 線端を平らに切り落とす |
| Round | 線端を丸くする |
| Square | 線端を四角くする（線幅分延長） |

### PenLineJoin列挙値

| 値 | 説明 |
|---|------|
| Miter | 鋭角で結合（マイター） |
| Bevel | 面取りで結合（ベベル） |
| Round | 丸く結合（ラウンド） |

### 入力データソース

- Shape.StrokeThickness/Stroke/StrokeDashArrayなどのプロパティ
- プログラムによる直接インスタンス化
- TryModifyOrCreateメソッドによる効率的な生成

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| IPen | IPen | ペンインターフェースとしての自身 |
| ImmutablePen | ImmutablePen | 不変ペンへの変換（ToImmutable） |

### 出力先

- DrawingContextへのストロークパラメータとして渡される
- Compositorシステムへのリソースとして登録

## 処理フロー

### 処理シーケンス

```
1. Penインスタンス生成
   └─ コンストラクタまたはTryModifyOrCreate
2. プロパティ設定
   └─ Brush/Thickness/DashStyle/LineCap/LineJoin/MiterLimit
3. 描画時の適用
   └─ DrawingContext.DrawLine()等に渡される
4. レンダリング
   └─ GPUシェーダーでストローク実行
```

### フローチャート

```mermaid
flowchart TD
    A[Pen生成要求] --> B{TryModifyOrCreate?}
    B -->|Yes| C{Brush == null?}
    C -->|Yes| D[pen = null を返す]
    C -->|No| E{ImmutableBrush?}
    E -->|Yes| F[ImmutablePen生成]
    E -->|No| G[mutablePen更新]
    B -->|No| H[new Pen()]
    H --> I[プロパティ設定]
    F --> J[描画使用]
    G --> J
    I --> J
    D --> K[描画スキップ]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-74-01 | デフォルト太さ | Thicknessのデフォルト値は1.0 | 常時 |
| BR-74-02 | デフォルトマイター | MiterLimitのデフォルト値は10.0 | 常時 |
| BR-74-03 | Brush null時 | Brushがnullの場合、ストロークは描画されない | 描画時 |
| BR-74-04 | Thickness 0時 | Thicknessが0以下の場合、ストロークは描画されない | 描画時 |

### 計算ロジック

ストロークの可視性判定:
```
isVisible = (pen?.Brush != null) && (pen.Thickness > 0)
```

マイター結合の制限:
- 2つの線の角度が鋭い場合、マイターが長くなりすぎる
- MiterLimitを超えた場合、Bevel結合に切り替わる

## データベース操作仕様

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 特別なエラーケースなし | - |

### リトライ仕様

本機能にリトライ仕様は存在しない。

## トランザクション仕様

本機能にトランザクション管理は存在しない。

## パフォーマンス要件

- TryModifyOrCreateで既存Penの再利用を推奨
- ImmutablePenは共有可能で効率的
- DashStyle変更時のみCompositorに通知

## セキュリティ考慮事項

本機能は描画処理のみを担当するため、特別なセキュリティ考慮事項は存在しない。

## 備考

- PenはAvaloniaObjectを継承し、依存関係プロパティシステムを使用
- DashStyleの変更は弱イベント購読で監視される
- TryModifyOrCreateメソッドでPenの効率的な再利用が可能

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: インターフェースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | IPen.cs | `src/Avalonia.Base/Media/IPen.cs` | ペンの基本契約 |

**読解のコツ**: IPenはBrush、Thickness、DashStyle、LineCap、LineJoin、MiterLimitを定義。

#### Step 2: メインクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Pen.cs | `src/Avalonia.Base/Media/Pen.cs` | ペン実装クラス |

**主要処理フロー**:
- **22-53行目**: StyledPropertyの定義（Brush、Thickness、DashStyle、LineCap、LineJoin、MiterLimit）
- **73-105行目**: コンストラクタ（複数オーバーロード）
- **168-180行目**: ToImmutableメソッド
- **194-243行目**: TryModifyOrCreateメソッド（効率的なペン生成）
- **250-260行目**: OnPropertyChangedでのCompositor通知

#### Step 3: 関連クラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | DashStyle.cs | `src/Avalonia.Base/Media/DashStyle.cs` | 破線パターン定義 |
| 3-2 | ImmutablePen.cs | `src/Avalonia.Base/Media/Immutable/ImmutablePen.cs` | 不変ペン |

### プログラム呼び出し階層図

```
Shape.Render()
    │
    └─ Pen.TryModifyOrCreate()
           │
           ├─ ImmutablePen生成（ImmutableBrush使用時）
           │
           └─ Pen更新（MutableBrush使用時）
                  │
                  └─ Compositor.SerializeChanges()
```

### データフロー図

```
[入力]                    [処理]                    [出力]

Brush ───────▶ Pen ───────▶ DrawingContext.DrawLine()
Thickness ───▶    │               │
DashStyle ───▶    │               ▼
LineCap ─────▶    │        GPUストローク描画
LineJoin ────▶    │
MiterLimit ──▶    │
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Pen.cs | `src/Avalonia.Base/Media/Pen.cs` | ソース | ペン実装クラス |
| IPen.cs | `src/Avalonia.Base/Media/IPen.cs` | ソース | ペンインターフェース |
| ImmutablePen.cs | `src/Avalonia.Base/Media/Immutable/ImmutablePen.cs` | ソース | 不変ペン |
| DashStyle.cs | `src/Avalonia.Base/Media/DashStyle.cs` | ソース | 破線スタイル |
| ImmutableDashStyle.cs | `src/Avalonia.Base/Media/Immutable/ImmutableDashStyle.cs` | ソース | 不変破線スタイル |
| PenLineCap.cs | `src/Avalonia.Base/Media/PenLineCap.cs` | ソース | 線端スタイル列挙 |
| PenLineJoin.cs | `src/Avalonia.Base/Media/PenLineJoin.cs` | ソース | 線結合スタイル列挙 |
