# 機能設計書 39-Viewbox

## 概要

本ドキュメントは、Avalonia UIフレームワークにおけるViewbox（ビューボックス）の機能設計を定義するものである。Viewboxは単一の子要素を利用可能なスペースに合わせてスケーリングするコンテナを提供する。

### 本機能の処理概要

Viewboxは、子要素を利用可能なスペースに合わせてスケーリング（拡大・縮小）するコンテナを提供する。Stretchプロパティで伸縮モード、StretchDirectionでスケーリング方向を制御できる。

**業務上の目的・背景**：アイコン、グラフィック、ベクター画像などを表示する際、コンテナサイズに合わせて自動的にスケーリングするニーズがある。Viewboxは、アスペクト比を維持しながら（または維持せずに）コンテンツをスケーリングする機能を提供し、レスポンシブなUI設計を支援する。

**機能の利用シーン**：
- アイコンの表示（サイズ自動調整）
- SVGやベクター画像のスケーリング
- コンテンツのレスポンシブ表示
- プレビュー機能での縮小表示

**主要な処理内容**：
1. Stretchによる伸縮モードの指定（None/Fill/Uniform/UniformToFill）
2. StretchDirectionによる伸縮方向の制御（UpOnly/DownOnly/Both）
3. スケーリング変換の計算と適用
4. ViewboxContainerを介した子要素のホスト

**関連システム・外部連携**：Controlを継承。内部でViewboxContainerを使用してスケーリング変換を適用。

**権限による制御**：特になし。UIコンポーネントとしてアプリケーション側で必要に応じて実装。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | Viewboxはスケーリングが必要な画面で使用される |

## 機能種別

装飾 / スケーリングコンテナ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Stretch | Stretch | No | 伸縮モード（デフォルト: Uniform） | None/Fill/Uniform/UniformToFill |
| StretchDirection | StretchDirection | No | 伸縮方向（デフォルト: Both） | UpOnly/DownOnly/Both |
| Child | Control? | No | スケーリング対象の子要素 | - |

### Stretch列挙型

| 値 | 説明 |
|-----|------|
| None | スケーリングなし（元サイズ） |
| Fill | アスペクト比を無視してフィット |
| Uniform | アスペクト比を維持して収まるようにフィット |
| UniformToFill | アスペクト比を維持して領域を埋める |

### StretchDirection列挙型

| 値 | 説明 |
|-----|------|
| UpOnly | 拡大のみ（縮小しない） |
| DownOnly | 縮小のみ（拡大しない） |
| Both | 拡大・縮小両方 |

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DesiredSize | Size | Stretch設定に基づいて計算されたサイズ |
| スケーリング変換 | ITransform | 子要素に適用されるスケール変換 |

## 処理フロー

### 処理シーケンス

```
1. MeasureOverrideフェーズ
   ├─ 子要素を無限大サイズで計測
   └─ Stretch.CalculateSizeでDesiredSize計算
2. ArrangeOverrideフェーズ
   ├─ Stretch.CalculateScalingでスケール係数計算
   ├─ スケール変換を生成・適用
   └─ 子要素を元サイズで配置
```

### フローチャート

```mermaid
flowchart TD
    A[MeasureOverride開始] --> B[child.Measure Infinity]
    B --> C[childSize取得]
    C --> D[Stretch.CalculateSize]
    D --> E[DesiredSize返却]

    F[ArrangeOverride開始] --> G[childSize取得]
    G --> H[Stretch.CalculateScaling]
    H --> I[scale計算]
    I --> J[Matrix.CreateScale]
    J --> K[InternalTransform設定]
    K --> L[child.Arrange 元サイズ]
    L --> M[childSize * scale返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-39-01 | 無限大計測 | 子要素はSize.Infinityで計測（制約なし） | 常時 |
| BR-39-02 | スケール適用 | スケール変換はViewboxContainerのRenderTransformに適用 | 常時 |
| BR-39-03 | ClipToBounds | デフォルトtrueでスケール後のはみ出しをクリップ | 常時 |
| BR-39-04 | UseLayoutRounding | デフォルトtrueでピクセル境界に丸める | 常時 |

### 計算ロジック

**スケール計算（Uniform）**:
```
scaleX = availableWidth / childWidth
scaleY = availableHeight / childHeight
scale = Min(scaleX, scaleY)  // アスペクト比維持
```

**スケール計算（UniformToFill）**:
```
scaleX = availableWidth / childWidth
scaleY = availableHeight / childHeight
scale = Max(scaleX, scaleY)  // 領域を埋める
```

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

該当なし（UIコンポーネントのためDB操作は行わない）

## エラー処理

特になし

## パフォーマンス要件

- スケーリング計算は軽量
- ImmutableTransformでの効率的な変換適用

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

特になし

## 備考

- ViewboxContainerは内部クラスとして定義
- 子要素のRenderTransformとは独立してスケーリング適用可能

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Stretch.cs | `src/Avalonia/Media/Stretch.cs` | Stretch列挙型とCalculateSize/CalculateScalingメソッド |
| 1-2 | StretchDirection.cs | `src/Avalonia/Media/StretchDirection.cs` | StretchDirection列挙型 |

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Viewbox.cs | `src/Avalonia.Controls/Viewbox.cs` | メインクラス |

**主要処理フロー**:
- **10行目**: `Viewbox`クラス定義。`Control`を継承
- **12行目**: `_containerVisual` - 子要素をホストする内部コンテナ
- **17-24行目**: Stretch/StretchDirectionプロパティ定義
- **29-30行目**: ChildProperty - Decorator.ChildPropertyのAddOwner
- **32-37行目**: 静的コンストラクタ - ClipToBounds=true, UseLayoutRounding=true

#### Step 3: コンストラクタとChild管理

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Viewbox.cs | `src/Avalonia.Controls/Viewbox.cs` | コンストラクタ/OnPropertyChanged（42-116行目） |

**主要処理フロー**:
- **42-50行目**: コンストラクタ - ViewboxContainer作成、VisualChildrenに追加
- **47行目**: RenderTransformOrigin = TopLeft（スケール基点）
- **92-116行目**: OnPropertyChanged - Child変更時のlogical parent/children管理

#### Step 4: MeasureOverride/ArrangeOverride

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Viewbox.cs | `src/Avalonia.Controls/Viewbox.cs` | レイアウトメソッド（119-145行目） |

**主要処理フロー**:
- **123行目**: `child.Measure(Size.Infinity)` - 無限大で計測
- **127行目**: `Stretch.CalculateSize` - DesiredSize計算
- **138行目**: `Stretch.CalculateScaling` - スケール係数計算
- **140行目**: `ImmutableTransform` - スケール変換生成
- **142行目**: `child.Arrange` - 元サイズで配置

#### Step 5: ViewboxContainer内部クラス

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Viewbox.cs | `src/Avalonia.Controls/Viewbox.cs` | ViewboxContainerクラス（150-173行目） |

**読解のコツ**: ViewboxContainerは子要素をvisual childとしてホストするが、logical parentはViewbox。これにより、スケール変換を子要素の変換とは独立して適用できる。

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

```
Viewbox (スケーリングコンテナ)
    │
    ├─ コンストラクタ
    │      └─ ViewboxContainer作成
    │             └─ VisualChildren.Add
    │
    ├─ OnPropertyChanged(Child)
    │      ├─ oldChild.SetParent(null)
    │      ├─ LogicalChildren管理
    │      └─ _containerVisual.Child = newChild
    │
    ├─ MeasureOverride()
    │      ├─ _containerVisual.Measure(Infinity)
    │      └─ Stretch.CalculateSize()
    │
    └─ ArrangeOverride()
           ├─ Stretch.CalculateScaling()
           ├─ InternalTransform = new ImmutableTransform(Matrix.CreateScale)
           └─ _containerVisual.Arrange()
```

### データフロー図

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

Child ───────────────────▶ ViewboxContainer.Child設定
                              │
                              ▼
availableSize ───────────▶ MeasureOverride()
                              │
Stretch ──────────────────▶ Stretch.CalculateSize()
StretchDirection ─────────▶ │
                              │
                              ▼
                     DesiredSize
                              │
                              ▼
finalSize ────────────────▶ ArrangeOverride()
                              │
                    ┌─────────┴─────────┐
                    ▼                   ▼
         CalculateScaling()    Matrix.CreateScale()
                    │                   │
                    └─────────┬─────────┘
                              ▼
                     InternalTransform設定
                              │
                              ▼
                     _containerVisual.Arrange()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Viewbox.cs | `src/Avalonia.Controls/Viewbox.cs` | ソース | メインクラス、ViewboxContainer内部クラス |
| Stretch.cs | `src/Avalonia/Media/Stretch.cs` | ソース | Stretch列挙型、計算メソッド |
| StretchDirection.cs | `src/Avalonia/Media/StretchDirection.cs` | ソース | StretchDirection列挙型 |
| ImmutableTransform.cs | `src/Avalonia/Media/Immutable/ImmutableTransform.cs` | ソース | 不変変換クラス |
