# 機能設計書 203-PushClipRect

## 概要

本ドキュメントは、ImGuiライブラリにおける `PushClipRect` 関数の機能設計を定義する。この関数は、クリッピング矩形をスタックにプッシュし、描画領域とマウスホバー判定領域を制限するために使用される。

### 本機能の処理概要

PushClipRect関数は、ImGuiのロジック（ヒットテスト等）と低レベルのImDrawList描画の両方に影響するクリッピング矩形をプッシュする。これにより、指定した矩形内のみで描画とインタラクションが行われるようになる。

**業務上の目的・背景**：GUIアプリケーションでは、特定の領域内のみでウィジェットを表示・操作可能にする必要がある場面が多い。スクロール領域、オーバーレイ表示、カスタム描画領域など、描画とインタラクションの範囲を制限することで、意図しない領域への描画やクリック検出を防止する。PushClipRectは、この領域制限を実現するための基本機能である。

**機能の利用シーン**：
- スクロール可能な子ウィンドウの描画領域制限
- カスタムキャンバスでの描画制限
- オーバーレイUIの表示領域制御
- 複雑なレイアウトでのウィジェット配置
- テキストやグラフィックのクリッピング表示

**主要な処理内容**：
1. ウィンドウの描画リスト（DrawList）にクリップ矩形をプッシュ
2. ウィンドウのClipRectをDrawListのクリップ矩形スタックの最新値に更新
3. 以降の描画とヒットテストが指定矩形内に制限される

**関連システム・外部連携**：ImDrawList、ウィンドウシステム、マウスホバー検出システムと連携する。ImDrawList::PushClipRectとは異なり、ロジック（ヒットテスト）にも影響する。

**権限による制御**：本機能自体に権限制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 20 | Custom Rendering | 主画面 | カスタム描画領域でのクリッピング |
| 24 | Layout | 参照画面 | レイアウト制御でのクリッピング使用 |

## 機能種別

描画制御 / クリッピング / スタック操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| clip_rect_min | const ImVec2& | Yes | クリップ矩形の左上座標（画面絶対座標） | なし |
| clip_rect_max | const ImVec2& | Yes | クリップ矩形の右下座標（画面絶対座標） | なし |
| intersect_with_current_clip_rect | bool | Yes | 現在のクリップ矩形と交差させるかどうか | なし |

### 入力データソース

プログラムコードからの直接呼び出し。座標はGetCursorScreenPos()やGetWindowPos()等から計算される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| なし | void | 戻り値なし |

### 出力先

- ImDrawListのクリップ矩形スタック
- ImGuiWindowのClipRect
- 以降の描画コマンドとヒットテスト判定

## 処理フロー

### 処理シーケンス

```
1. 現在のウィンドウを取得
   └─ GetCurrentWindow()を呼び出し
2. DrawListにクリップ矩形をプッシュ
   └─ window->DrawList->PushClipRect()を呼び出し
3. ウィンドウのClipRectを更新
   └─ DrawListのクリップ矩形スタックの最新値をwindow->ClipRectに設定
```

### フローチャート

```mermaid
flowchart TD
    A[PushClipRect呼び出し] --> B[GetCurrentWindow]
    B --> C[DrawList->PushClipRect]
    C --> D{intersect_with_current?}
    D -->|Yes| E[現在の矩形と交差計算]
    D -->|No| F[指定矩形をそのまま使用]
    E --> G[ClipRectStack更新]
    F --> G
    G --> H[window->ClipRect更新]
    H --> I[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-203-1 | ペア呼び出し | PushClipRectはPopClipRectと必ずペアで呼び出す | 常時 |
| BR-203-2 | 座標系 | 座標は画面絶対座標（スクリーン座標）で指定 | 常時 |
| BR-203-3 | 整数値推奨 | 正確なレンダリングのため座標は整数値に丸めることを推奨 | 常時 |
| BR-203-4 | 交差オプション | intersect_with_current_clip_rect=trueで親のクリップ矩形を尊重 | 交差モード時 |

### 計算ロジック

クリップ矩形の交差計算（intersect_with_current_clip_rect=true時）：
```
結果矩形.min.x = max(指定矩形.min.x, 現在矩形.min.x)
結果矩形.min.y = max(指定矩形.min.y, 現在矩形.min.y)
結果矩形.max.x = min(指定矩形.max.x, 現在矩形.max.x)
結果矩形.max.y = min(指定矩形.max.y, 現在矩形.max.y)
```

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

### 操作別データベース影響一覧

本機能はデータベース操作を行わない（純粋なUI制御機能）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| なし | アサーション | PopClipRectなしでフレーム終了 | スタック不整合を検出。対応するPopClipRectを追加 |

### リトライ仕様

リトライ機能なし（即時処理）

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

トランザクション管理なし（UI状態のスタック操作）。PushClipRect/PopClipRectは必ずペアで使用する。

## パフォーマンス要件

- 軽量な処理（スタックプッシュとポインタ更新のみ）
- 描画コマンドの増加による間接的な影響あり（クリップ矩形の変更で描画コマンドが分割される）

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

- クリッピングはレンダリング上の制限であり、データアクセスの制限ではない
- ヒットテストへの影響は想定通りの動作

## 備考

- ImDrawList::PushClipRectとは異なり、本関数はロジック（ヒットテスト）にも影響する
- 子ウィンドウはBeginChild/EndChildで自動的にクリッピングが適用される
- カスタム描画領域でのみ直接使用することが多い

---

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

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

### 推奨読解順序

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

まず、クリッピング機能で使用されるデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui.h | `imgui.h` | ImVec2構造体の定義 |
| 1-2 | imgui.h | `imgui.h` | ImDrawListの_ClipRectStack（3296行目付近） |

**読解のコツ**: ImVec2は2次元座標を表す基本構造体。ImDrawListはクリップ矩形をImVec4としてスタック管理する。

#### Step 2: API宣言を理解する

公開APIの宣言とドキュメントコメントを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui.h | `imgui.h` | PushClipRect関数の宣言（988-990行目） |

**主要処理フロー**:
- **988-989行目**: クリッピング機能のコメント説明
- **990行目**: PushClipRect関数宣言

#### Step 3: 実装を理解する

PushClipRect関数の実装詳細を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui.cpp | `imgui.cpp` | PushClipRect関数の実装（5833-5838行目） |

**主要処理フロー**:
- **5833行目**: 関数定義の開始
- **5835行目**: GetCurrentWindow()で現在のウィンドウを取得
- **5836行目**: DrawList->PushClipRectの呼び出し
- **5837行目**: window->ClipRectの更新

#### Step 4: DrawListの実装を理解する

低レベルのクリップ矩形処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | imgui_draw.cpp | `imgui_draw.cpp` | ImDrawList::PushClipRectの実装 |

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

```
ImGui::PushClipRect(min, max, intersect)
    │
    ├─ GetCurrentWindow()
    │
    ├─ window->DrawList->PushClipRect(min, max, intersect)
    │      │
    │      └─ _ClipRectStack.push_back()
    │             └─ 交差計算（intersect=true時）
    │
    └─ window->ClipRect = _ClipRectStack.back()
```

### データフロー図

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

clip_rect_min ────────▶ PushClipRect() ───────▶ DrawList._ClipRectStack
clip_rect_max ────────▶       │ ───────────────▶ window.ClipRect
intersect_flag ───────▶       │
                              │
現在のClipRect ───────▶ 交差計算 ───────────────▶ 結果ClipRect
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダ | 公開API宣言 |
| imgui.cpp | `imgui.cpp` | ソース | ImGui::PushClipRect実装 |
| imgui_draw.cpp | `imgui_draw.cpp` | ソース | ImDrawList::PushClipRect実装 |
| imgui_internal.h | `imgui_internal.h` | ヘッダ | 内部データ構造定義 |
| imgui_demo.cpp | `imgui_demo.cpp` | ソース | 使用例（5167-5170行目） |
