# 画面設計書 112-メインウィンドウ

## 概要

本ドキュメントは、TextTestAppサンプルアプリケーションにおけるメインウィンドウの画面設計書である。このアプリケーションは、Avaloniaフレームワークのテキストレンダリング機能をテスト・可視化するために設計されており、テキストシェーピング、ヒットテスト、グリフ情報の詳細な分析が可能である。

### 本画面の処理概要

この画面は、テキストレンダリングのテスト・デバッグを行うメインウィンドウである。入力されたテキストに対して、文字単位のシェーピング結果、グリフ情報、ヒットテスト結果をリアルタイムで可視化する。

**業務上の目的・背景**：Avaloniaフレームワークにおけるテキストレンダリング機能の品質検証・デバッグを目的としている。開発者がテキストフォーマット、フォント機能、文字ヒットテストの動作を詳細に確認できるツールとして提供されている。多言語対応、複雑なテキストレイアウト（RTL言語、リガチャ等）の検証において重要な役割を果たす。

**画面へのアクセス方法**：TextTestAppアプリケーションを起動すると、このメインウィンドウが直接表示される。「+」ボタンをクリックすることで、新しいウィンドウインスタンスを追加で開くことも可能。

**主要な操作・処理内容**：
1. テキスト入力：テスト対象のテキストを入力フィールドに入力
2. フォント選択：システムフォントからフォントファミリーを選択
3. フォント機能指定：OpenTypeフォント機能（calt, clig, kern, liga等）を指定
4. フォントサイズ設定：描画サイズをポイント単位で指定
5. テキストレンダリング表示：InteractiveLineControlによる詳細なレンダリング可視化
6. シェーピングバッファ確認：グリフ単位の詳細情報（グリフID、アドバンス、オフセット等）を表示
7. キャラクターヒット確認：文字位置ごとの前方/後方/バックスペースヒット情報を表示
8. マウスポインターによるヒットテスト：ポインター位置に対応するテキスト位置を表示

**画面遷移**：
- 遷移元：アプリケーション起動
- 遷移先：「+」ボタンで新しいMainWindowを開く（自己複製）

**権限による表示制御**：特になし

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 42 | Window | 主機能 | テキストテストアプリのメインウィンドウ表示 |
| 81 | FormattedText | 主機能 | テキストレンダリングのテスト |

## 画面種別

テスト / 分析

## URL/ルーティング

該当なし（デスクトップアプリケーション）

## 入出力項目

| 項目名 | 種別 | データ型 | 必須 | 初期値 | 説明 |
|--------|------|----------|------|--------|------|
| Text | 入力 | string | - | "Hello!" | テスト対象テキスト |
| Font | 入力 | FontFamily | - | システムデフォルト | 使用するフォントファミリー |
| Features | 入力 | string | - | "calt clig kern liga" | OpenTypeフォント機能 |
| Size | 入力 | double | - | 64 | フォントサイズ（ポイント） |
| HitTestMethod | 入力 | bool | - | false | ヒットテストモード（Position/Range） |
| HitTestPoint | 出力 | Point | - | - | マウス位置座標 |
| TextPosition | 出力 | int | - | - | ヒットテストで検出されたテキスト位置 |

## 表示項目

| 項目名 | 表示位置 | 説明 |
|--------|----------|------|
| テキスト入力欄 | 上部ツールバー左 | テスト対象テキストの入力 |
| フォント選択 | 上部ツールバー右 | ComboBoxによるフォント選択 |
| フォント機能入力 | 上部ツールバー右 | OpenType機能の入力 |
| サイズ入力 | 上部ツールバー右 | フォントサイズの入力 |
| 新規ウィンドウボタン | 上部ツールバー右 | 「+」ボタン |
| InteractiveLineControl | 画面中央上部 | テキストレンダリング可視化 |
| Shaped Bufferタブ | 画面下部 | グリフ情報リスト |
| Character Hitsタブ | 画面下部 | 文字ヒット情報リスト |
| 座標表示 | 下部ステータスバー | HitTestPoint座標 |
| テキスト位置表示 | 下部ステータスバー | TextPosition値 |
| ヒットテストモード切替 | 下部ステータスバー | ToggleSwitch |

## イベント仕様

### 1-テキスト入力変更

テキストフィールドの内容が変更されると、レンダリングが更新される。

- **トリガー**：_text TextBoxのText変更
- **処理フロー**：
  1. InteractiveLineControlのTextプロパティにバインドされた値が更新
  2. InvalidateTextLine()が呼び出される
  3. TextLineとTextLayoutが再生成
  4. OnShapeBufferChanged()により下部リストが更新
  5. 表示が再描画される

### 2-フォント/サイズ/機能変更

フォント設定が変更されると、テキストプロパティが更新され再レンダリングされる。

- **トリガー**：_font ComboBox、_features TextBox、_size TextBoxの値変更
- **処理フロー**：
  1. InteractiveLineControlの対応プロパティが更新
  2. InvalidateTextRunProperties()が呼び出される
  3. テキストが再シェーピングされる

### 3-ポインター移動

マウスポインターがInteractiveLineControl上を移動すると、ヒットテスト情報が更新される。

- **トリガー**：PointerMoved イベント
- **処理フロー**（237-258行目）：
  1. ポインター位置を取得
  2. TextLayout.HitTestPoint()でテキスト位置を計算
  3. _coordinates, _hitテキストブロックを更新
  4. _hitsリストの該当項目を選択

### 4-新規ウィンドウ作成

「+」ボタンをクリックすると、新しいMainWindowインスタンスが開く。

- **トリガー**：Button Click
- **処理フロー**（33-37行目）：
  1. new MainWindow()で新インスタンスを生成
  2. Show()でウィンドウを表示

### 5-ヒットテストモード切替

ToggleSwitchでヒットテストモードを切り替える。

- **トリガー**：_hitRangeToggle IsCheckedChanged
- **処理フロー**（260-263行目）：
  1. IsCheckedがtrueならMultiple選択モード（TextRange）
  2. falseならSingle選択モード（TextPosition）

### 6-シェーピングバッファ選択

Shaped Bufferリストで項目を選択すると、該当グリフの境界が可視化される。

- **トリガー**：_buffer SelectionChanged
- **処理フロー**（321-336行目）：
  1. 選択されたアイテムからRect情報を取得
  2. SelectionAdornerに矩形を設定
  3. 赤い矩形でグリフ位置を表示

### 7-キャラクターヒット選択

Character Hitsリストで項目を選択すると、該当文字位置が可視化される。

- **トリガー**：_hits SelectionChanged
- **処理フロー**（265-319行目）：
  1. 選択されたインデックスを取得
  2. HitTestTextRangeまたはHitTestTextPositionで矩形を計算
  3. SelectionAdornerに矩形を設定

## データベース更新仕様

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

該当なし（データベースを使用しない）

## メッセージ仕様

該当なし

## 例外処理

| 状況 | 処理内容 |
|------|----------|
| 無効なフォントサイズ | 入力値の検証は行われず、そのまま適用される |
| 空のテキスト | 空の状態でも処理は継続（デフォルト表示） |

## 備考

- F5キーでレンダリングを手動更新可能
- Escキーでリスト選択を解除可能
- SubpixelAntialiasテキストレンダリングモードを使用
- EdgeModeはAliasedに設定されている（正確な境界表示のため）
- GridRowカスタムコントロールでテーブル表示を実現

---

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

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

### 推奨読解順序

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

テキストレンダリングで使用される主要なデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | InteractiveLineControl.cs | `samples/TextTestApp/InteractiveLineControl.cs` | TextRunProperties、TextParagraphProperties、TextLineの構造（235-330行目） |

**読解のコツ**: AvaloniaのTextFormatting名前空間のクラス群（TextLine、TextLayout、ShapedTextRun等）の関係を理解することが重要。

#### Step 2: UI定義を理解する

XAMLファイルでUIレイアウトとデータバインディングを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | MainWindow.axaml | `samples/TextTestApp/MainWindow.axaml` | DockPanel構造、InteractiveLineControlの配置、TabControlによるリスト切替 |

**主要処理フロー**:
- **7-20行目**: 下部ステータスバー（座標・ヒット情報表示）
- **22-35行目**: 上部ツールバー（テキスト・フォント設定）
- **37-56行目**: InteractiveLineControl（テキストレンダリング表示）
- **59-105行目**: TabControlでShaped Buffer/Character Hitsを切替表示

#### Step 3: エントリーポイントと初期化処理を理解する

MainWindowの初期化処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | MainWindow.axaml.cs | `samples/TextTestApp/MainWindow.axaml.cs` | コンストラクタでのSelectionAdorner設定、イベントハンドラの登録 |

**主要処理フロー**:
- **18-31行目**: SelectionAdornerの初期化とAdornerLayerへの設定
- **29-30行目**: TextLineChangedイベントの購読

#### Step 4: シェーピングバッファ処理を理解する

グリフ情報のリスト表示処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | MainWindow.axaml.cs | `samples/TextTestApp/MainWindow.axaml.cs` | ListBuffers()メソッド（77-110行目）でのShapedTextRun処理 |

**主要処理フロー**:
- **82-84行目**: TextLineからTextRunsを取得
- **87-109行目**: 各TextRunをShapedTextRunとして処理し、リストに追加

#### Step 5: ヒットテスト処理を理解する

ポインター位置からテキスト位置への変換処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | MainWindow.axaml.cs | `samples/TextTestApp/MainWindow.axaml.cs` | OnPointerMoved()メソッド（237-258行目） |

**主要処理フロー**:
- **243-244行目**: ポインター位置の取得と座標変換
- **247行目**: TextLayout.HitTestPoint()でヒットテスト実行
- **248-257行目**: 結果をUI要素に反映

#### Step 6: カスタム描画を理解する

InteractiveLineControlでのカスタム描画処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | InteractiveLineControl.cs | `samples/TextTestApp/InteractiveLineControl.cs` | Render()メソッド（474-622行目）での描画処理 |

**主要処理フロー**:
- **476-478行目**: TextLineの存在チェック
- **485-498行目**: インク境界とライン境界の計算
- **510-537行目**: テキスト境界とラン境界の描画
- **541-620行目**: ヒット情報の可視化

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

```
MainWindow (起動時)
    │
    ├─ InitializeComponent()
    │
    ├─ SelectionAdorner設定
    │
    └─ OnShapeBufferChanged() (TextLine変更時)
           │
           ├─ ListBuffers()
           │      │
           │      └─ TextLine.TextRuns処理
           │             │
           │             └─ ShapedTextRun → GridRow生成
           │
           └─ ListHits()
                  │
                  └─ 文字位置ごとのヒット情報生成

OnPointerMoved (マウス移動時)
    │
    └─ TextLayout.HitTestPoint()
           │
           └─ _hits.SelectedIndex更新

InteractiveLineControl.Render() (描画時)
    │
    ├─ TextLine.Draw()
    │
    ├─ TextBounds描画
    │
    └─ ヒット情報可視化
```

### データフロー図

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

テキスト入力 ───▶ TextSource生成 ───▶ TextFormatter.FormatLine()
                        │
                        ▼
                   TextLine生成
                        │
        ┌───────────────┼───────────────┐
        ▼               ▼               ▼
   ShapedBuffer    TextLayout      Render描画
        │               │               │
        ▼               ▼               ▼
   Bufferリスト    HitTest結果    画面表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| MainWindow.axaml | `samples/TextTestApp/MainWindow.axaml` | XAML | UIレイアウト定義 |
| MainWindow.axaml.cs | `samples/TextTestApp/MainWindow.axaml.cs` | ソース | イベント処理、リスト管理 |
| InteractiveLineControl.cs | `samples/TextTestApp/InteractiveLineControl.cs` | ソース | テキストレンダリング、カスタム描画 |
| GridRow.cs | `samples/TextTestApp/GridRow.cs` | ソース | テーブル行表示用カスタムコントロール |
| SelectionAdorner.cs | `samples/TextTestApp/SelectionAdorner.cs` | ソース | 選択範囲の可視化 |
