# 機能設計書 8-TextBlock

## 概要

本ドキュメントは、Avaloniaフレームワークにおけるテキスト表示コントロールである`TextBlock`の機能設計を記述する。`Control`を継承し、テキストのレンダリング、フォント設定、テキスト配置、折り返し、トリミングなどの機能を提供する。

### 本機能の処理概要

`TextBlock`クラスは、読み取り専用のテキストを表示するための基本的なコントロールであり、以下の機能を提供する：
- **テキスト表示**：Textプロパティによる単純テキスト表示
- **インラインコンテンツ**：InlineCollectionによる複合テキスト表示
- **フォント制御**：FontFamily、FontSize、FontStyle、FontWeight、FontStretch
- **テキスト配置**：TextAlignment（Start、Center、End、Justify）
- **折り返し制御**：TextWrapping（NoWrap、Wrap、WrapWithOverflow）
- **トリミング制御**：TextTrimming（None、CharacterEllipsis、WordEllipsis）
- **装飾**：TextDecorations（下線、取り消し線等）
- **行制御**：LineHeight、LineSpacing、MaxLines

**業務上の目的・背景**：ラベル表示、説明文、見出しなど、ほぼすべてのアプリケーションで必要とされる基本的なテキスト表示機能を提供する。

**機能の利用シーン**：
- フォームラベル
- 説明テキスト
- タイトル/見出し
- 複合テキスト（太字、イタリック等を含む）

**主要な処理内容**：
1. `Text`プロパティまたは`Inlines`による表示内容管理
2. `TextLayout`によるテキストレンダリング
3. `MeasureOverride`/`ArrangeOverride`によるレイアウト計算
4. `Render`メソッドによる描画

**関連システム・外部連携**：
- `TextLayout`：テキストレイアウト計算・描画
- `InlineCollection`：インラインコンテンツ管理
- `TextRunProperties`：テキスト描画プロパティ
- `GenericTextParagraphProperties`：段落プロパティ

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| S-01 | MainWindow | 表示 | ラベル・説明テキスト表示 |

## 機能種別

UIコントロール / テキスト表示

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Text | string? | No | 表示テキスト | - |
| Inlines | InlineCollection? | No | インラインコンテンツ | [Content]属性 |
| FontFamily | FontFamily | No | フォントファミリー | 継承プロパティ |
| FontSize | double | No | フォントサイズ | 継承プロパティ |
| FontStyle | FontStyle | No | フォントスタイル | 継承プロパティ |
| FontWeight | FontWeight | No | フォントウェイト | 継承プロパティ |
| FontStretch | FontStretch | No | フォントストレッチ | 継承プロパティ |
| Foreground | IBrush? | No | 前景色 | 継承プロパティ |
| Background | IBrush? | No | 背景色 | - |
| Padding | Thickness | No | パディング | - |
| TextAlignment | TextAlignment | No | テキスト配置 | デフォルト: Start |
| TextWrapping | TextWrapping | No | 折り返し設定 | デフォルト: NoWrap |
| TextTrimming | TextTrimming | No | トリミング設定 | デフォルト: None |
| TextDecorations | TextDecorationCollection? | No | テキスト装飾 | - |
| FontFeatures | FontFeatureCollection? | No | フォントフィーチャー | - |
| LineHeight | double | No | 行の高さ | 継承プロパティ、> 0 or NaN |
| LineSpacing | double | No | 行間 | 継承プロパティ |
| LetterSpacing | double | No | 文字間隔 | 継承プロパティ |
| MaxLines | int | No | 最大行数 | 継承プロパティ、>= 0 |
| BaselineOffset | double | No | ベースラインオフセット | 添付プロパティ |

### 入力データソース

- Textプロパティへの直接設定
- データバインディング
- InlineCollectionへのインライン要素追加

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| TextLayout | TextLayout | テキストレイアウト（読み取り専用） |

### 出力先

- 画面への描画出力
- TextLayoutプロパティ（計算結果の取得）

## 処理フロー

### 処理シーケンス

```
1. テキスト設定
   └─ TextプロパティまたはInlines設定
   └─ OnPropertyChanged
   └─ InvalidateTextLayout
   └─ InvalidateMeasure

2. レイアウト計算（MeasureOverride）
   └─ Padding計算
   └─ 制約サイズから利用可能サイズ計算
   └─ HasComplexContent確認
   ├─ True: InlinesからTextRuns構築
   └─ TextLayout作成
   └─ サイズ返却

3. 配置計算（ArrangeOverride）
   └─ Padding計算
   └─ TextLayout再作成
   └─ 複合コンテンツの場合：EmbeddedControlRun配置
   └─ サイズ返却

4. 描画（Render）
   └─ RenderCore
   └─ Background描画
   └─ VerticalAlignment考慮したオフセット計算
   └─ RenderTextLayout
   └─ TextLayout.Draw
```

### フローチャート

```mermaid
flowchart TD
    A[Text/Inlines設定] --> B[OnPropertyChanged]
    B --> C[InvalidateTextLayout]
    C --> D[InvalidateMeasure]
    D --> E[MeasureOverride]
    E --> F{HasComplexContent?}
    F -->|Yes| G[BuildTextRuns from Inlines]
    F -->|No| H[SimpleTextSource作成]
    G --> I[CreateTextLayout]
    H --> I
    I --> J[サイズ計算]
    J --> K[ArrangeOverride]
    K --> L[TextLayout再作成]
    L --> M{HasComplexContent?}
    M -->|Yes| N[EmbeddedControlRun配置]
    M -->|No| O[Render]
    N --> O
    O --> P[RenderCore]
    P --> Q[Background描画]
    Q --> R[TextLayout.Draw]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ClipToBoundsデフォルト | ClipToBoundsがデフォルトでtrue | 静的コンストラクタで設定 |
| BR-02 | TextとInlinesの排他 | Textプロパティ設定時にInlinesをクリア | HasComplexContent時 |
| BR-03 | MaxLines検証 | MaxLinesは0以上 | IsValidMaxLines |
| BR-04 | LineHeight検証 | LineHeightはNaNまたは0より大きい値 | IsValidLineHeight |
| BR-05 | LineSpacing検証 | LineSpacingはNaN/Infinityでない | IsValidLineSpacing |
| BR-06 | 添付プロパティ継承 | TextAlignment等は子要素に継承 | inherits: true |
| BR-07 | BypassFlowDirectionPolicies | FlowDirectionポリシーをバイパス | BypassFlowDirectionPolicies = true |

### 計算ロジック

**MeasureOverride サイズ計算**：
```csharp
return new Size(textLayout.WidthIncludingTrailingWhitespace, textLayout.Height).Inflate(padding);
```

**TextLayout作成**：
```csharp
var typeface = new Typeface(FontFamily, FontStyle, FontWeight, FontStretch);
var defaultProperties = new GenericTextRunProperties(typeface, FontSize, TextDecorations, Foreground, fontFeatures: FontFeatures);
var paragraphProperties = new GenericTextParagraphProperties(...);
return new TextLayout(textSource, paragraphProperties, TextTrimming, maxSize.Width, maxSize.Height, MaxLines);
```

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ArgumentNullException | 添付プロパティのcontrolがnull | 例外スロー |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- TextLayoutは制約変更時のみ再作成（キャッシュ利用）
- OnMeasureInvalidatedでTextLayoutを破棄しメモリ効率化
- 制約が同じ場合はTextLayoutを再利用
- UseLayoutRoundingによるピクセルスナッピング

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

- 入力テキストのサニタイズなし（表示専用のため安全）
- オートメーション対応（TextBlockAutomationPeer）

## 備考

- WPFのTextBlockと高い互換性
- IInlineHostインターフェースを実装し、複合コンテンツをサポート
- AffectsRenderでBackground、Foreground変更時に再描画

---

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

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

### 推奨読解順序

#### Step 1: クラス定義とプロパティを理解する

テキストブロックの基本構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TextBlock.cs | `src/Avalonia.Controls/TextBlock.cs` | 18行目：クラス定義（Control継承、IInlineHost実装） |
| 1-2 | TextBlock.cs | `src/Avalonia.Controls/TextBlock.cs` | 23-159行目：プロパティ定義 |
| 1-3 | TextBlock.cs | `src/Avalonia.Controls/TextBlock.cs` | 169-174行目：静的コンストラクタ（ClipToBounds、AffectsRender） |

**読解のコツ**:
- `Control`を継承し、`IInlineHost`を実装
- 多くのプロパティは`TextElement`からAddOwnerで継承
- 添付プロパティはinherits: trueで子要素に継承

#### Step 2: テキストレイアウト作成を理解する

TextLayoutの作成処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | TextBlock.cs | `src/Avalonia.Controls/TextBlock.cs` | 654-691行目：CreateTextLayoutメソッド |
| 2-2 | TextBlock.cs | `src/Avalonia.Controls/TextBlock.cs` | 915-942行目：SimpleTextSource構造体 |
| 2-3 | TextBlock.cs | `src/Avalonia.Controls/TextBlock.cs` | 945-991行目：InlinesTextSource構造体 |

**主要処理フロー**:
- Typefaceの作成（FontFamily、FontStyle、FontWeight、FontStretch）
- GenericTextRunPropertiesの作成
- GenericTextParagraphPropertiesの作成
- ITextSource（SimpleTextSourceまたはInlinesTextSource）の選択
- TextLayoutインスタンスの作成

#### Step 3: レイアウト処理を理解する

MeasureOverride/ArrangeOverrideを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TextBlock.cs | `src/Avalonia.Controls/TextBlock.cs` | 711-753行目：MeasureOverride |
| 3-2 | TextBlock.cs | `src/Avalonia.Controls/TextBlock.cs` | 755-814行目：ArrangeOverride |
| 3-3 | TextBlock.cs | `src/Avalonia.Controls/TextBlock.cs` | 702-709行目：OnMeasureInvalidated |

**主要処理フロー**:
- **711-753行目**: MeasureOverrideでTextLayoutを作成しサイズを計算
- **755-814行目**: ArrangeOverrideでEmbeddedControlRunを配置
- **702-709行目**: OnMeasureInvalidatedでTextLayoutを破棄

#### Step 4: 描画処理を理解する

Render/RenderCoreを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | TextBlock.cs | `src/Avalonia.Controls/TextBlock.cs` | 589-592行目：Renderメソッド（sealed） |
| 4-2 | TextBlock.cs | `src/Avalonia.Controls/TextBlock.cs` | 595-629行目：RenderCoreメソッド |
| 4-3 | TextBlock.cs | `src/Avalonia.Controls/TextBlock.cs` | 631-634行目：RenderTextLayoutメソッド |

**主要処理フロー**:
- **595-629行目**: 背景描画、VerticalAlignment考慮、Padding計算
- **631-634行目**: TextLayout.Drawでテキスト描画

#### Step 5: プロパティ変更処理を理解する

OnPropertyChangedを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | TextBlock.cs | `src/Avalonia.Controls/TextBlock.cs` | 821-867行目：OnPropertyChanged |
| 5-2 | TextBlock.cs | `src/Avalonia.Controls/TextBlock.cs` | 875-896行目：OnInlinesChanged |
| 5-3 | TextBlock.cs | `src/Avalonia.Controls/TextBlock.cs` | 696-700行目：InvalidateTextLayout |

**主要処理フロー**:
- **821-867行目**: プロパティ変更時にInvalidateTextLayout呼び出し
- **875-896行目**: Inlines変更時のLogicalChildren/InlineHost設定

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

```
TextBlock
    │
    ├─ Control（コントロール基盤）
    │      └─ InputElement → Layoutable → Visual
    │
    ├─ IInlineHost
    │      ├─ Invalidate
    │      └─ VisualChildren
    │
    ├─ TextLayout（テキストレイアウト）
    │      ├─ CreateTextLayout
    │      ├─ TextLines
    │      └─ Draw
    │
    ├─ ITextSource
    │      ├─ SimpleTextSource（単純テキスト）
    │      └─ InlinesTextSource（複合コンテンツ）
    │
    └─ InlineCollection
           └─ BuildTextRun
```

### データフロー図

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

Text/Inlines設定
        │
        ▼
   OnPropertyChanged ──────▶ InvalidateTextLayout
        │                       │
        ▼                       ▼
   InvalidateMeasure ──────▶ MeasureOverride
        │                       │
        ▼                       ▼
   CreateTextLayout ────────▶ TextLayout生成
        │                       │
        ▼                       ▼
   ArrangeOverride ─────────▶ EmbeddedControl配置
        │                       │
        ▼                       ▼
   Render ──────────────────▶ DrawingContext
                                │
                                ▼
                           画面表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TextBlock.cs | `src/Avalonia.Controls/TextBlock.cs` | ソース | テキストブロックコントロール |
| Control.cs | `src/Avalonia.Controls/Control.cs` | ソース | コントロール基底クラス |
| TextLayout.cs | `src/Avalonia.Media/TextFormatting/TextLayout.cs` | ソース | テキストレイアウト |
| InlineCollection.cs | `src/Avalonia.Controls/Documents/InlineCollection.cs` | ソース | インラインコレクション |
| Inline.cs | `src/Avalonia.Controls/Documents/Inline.cs` | ソース | インライン基底クラス |
| TextElement.cs | `src/Avalonia.Controls/Documents/TextElement.cs` | ソース | テキスト要素基底 |
| GenericTextRunProperties.cs | `src/Avalonia.Media/TextFormatting/GenericTextRunProperties.cs` | ソース | テキストラン描画プロパティ |
| GenericTextParagraphProperties.cs | `src/Avalonia.Media/TextFormatting/GenericTextParagraphProperties.cs` | ソース | 段落プロパティ |
| TextBlockAutomationPeer.cs | `src/Avalonia.Controls/Automation/Peers/TextBlockAutomationPeer.cs` | ソース | オートメーション対応 |
