# 機能設計書 82-GlyphRun

## 概要

本ドキュメントは、Avaloniaフレームワークにおける低レベルテキストレンダリング機能「GlyphRun」の設計仕様を記述する。GlyphRunクラスは、単一フォントフェース・単一サイズ・単一レンダリングスタイルのグリフシーケンスを表現し、高性能なテキスト描画を実現する。

### 本機能の処理概要

GlyphRunは、テキストレンダリングの最も低レベルな表現単位である。単一のGlyphTypeface（フォントフェース）から取得された一連のグリフ（文字の視覚的表現）を、指定されたサイズとスタイルで描画するための情報を保持する。TextFormatterやFormattedTextの内部で使用され、最終的なテキスト描画に直接関与する。

**業務上の目的・背景**：高性能なテキストレンダリングを実現するため、フォント情報とグリフ情報を効率的に管理する必要がある。GlyphRunは、シェイピング（文字→グリフ変換）後のグリフシーケンスを保持し、プラットフォーム固有の描画APIに渡すためのブリッジとして機能する。国際化対応、双方向テキスト（BiDi）、複雑なスクリプト（アラビア語、タイ語等）のサポートも担う。

**機能の利用シーン**：テキストコントロールでの文字描画、キャレット位置計算、テキスト選択範囲のヒットテスト、テキストからジオメトリへの変換で利用される。

**主要な処理内容**：
1. GlyphTypefaceとグリフ情報リスト（GlyphInfo）の管理
2. グリフメトリクス（幅、高さ、ベースライン）の計算
3. キャラクターヒット計算（文字位置↔描画位置の変換）
4. グリフジオメトリの構築
5. プラットフォーム固有のIGlyphRunImplへの変換

**関連システム・外部連携**：GlyphTypeface、Typeface、IPlatformRenderInterface、SkiaのGlyphRunImplと連携する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 77 | GlyphRun | 主画面 | GlyphRun描画のデモ。低レベルテキストレンダリング |

## 機能種別

計算処理 / テキストレンダリング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| glyphTypeface | GlyphTypeface | Yes | グリフタイプフェース | - |
| fontRenderingEmSize | double | Yes | レンダリングemサイズ | - |
| characters | ReadOnlyMemory<char> | Yes | 元のUTF16文字列 | - |
| glyphInfos | IReadOnlyList<GlyphInfo> | Yes | グリフ情報リスト | - |
| baselineOrigin | Point? | No | ベースライン原点 | - |
| biDiLevel | int | No | 双方向ネストレベル（デフォルト0） | - |

### 入力データソース

TextFormatterやFormattedTextからの内部呼び出し、またはカスタム描画コードからの直接使用

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Bounds | Rect | グリフランの境界矩形 |
| InkBounds | Rect | インク領域の境界矩形 |
| Metrics | GlyphRunMetrics | メトリクス情報（幅、高さ、ベースライン等） |
| BaselineOrigin | Point | ベースライン原点 |
| IsLeftToRight | bool | 左から右への方向かどうか |

### 出力先

プラットフォーム固有のレンダリングAPI（Skia等）

## 処理フロー

### 処理シーケンス

```
1. GlyphRunインスタンス生成
   └─ GlyphTypeface、emSize、characters、glyphInfosを設定
   └─ baselineOrigin、biDiLevelをオプション設定

2. グリフ情報の準備（glyphIndicesコンストラクタの場合）
   └─ CreateGlyphInfosでglyphIndicesからGlyphInfo配列を生成
   └─ 各グリフのadvance幅を計算

3. メトリクス取得（遅延計算）
   └─ Metricsプロパティアクセス時にCreateGlyphRunMetricsを実行
   └─ 幅、高さ、ベースライン、クラスタ情報を計算

4. キャラクターヒット計算
   └─ GetDistanceFromCharacterHit: 文字位置→距離
   └─ GetCharacterHitFromDistance: 距離→文字位置
   └─ GetNextCaretCharacterHit/GetPreviousCaretCharacterHit

5. ジオメトリ構築/描画
   └─ BuildGeometry: グリフのパスジオメトリを構築
   └─ PlatformImpl: プラットフォーム固有実装を取得
```

### フローチャート

```mermaid
flowchart TD
    A[GlyphRun生成] --> B{glyphIndicesで指定?}
    B -->|Yes| C[CreateGlyphInfos]
    C --> D[GlyphInfo配列生成]
    B -->|No| D
    D --> E[プロパティ保持]
    E --> F{メトリクス要求?}
    F -->|Yes| G[CreateGlyphRunMetrics]
    G --> H[FirstCluster/LastCluster計算]
    H --> I[幅/高さ計算]
    I --> J[GlyphRunMetrics返却]
    F -->|ヒットテスト| K[GetDistanceFromCharacterHit等]
    K --> L[FindGlyphIndex]
    L --> M[距離/位置計算]
    F -->|描画| N[PlatformImpl取得]
    N --> O[CreateGlyphRunImpl]
    O --> P[プラットフォーム描画]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | BiDiレベル判定 | BiDiLevel & 1 == 0 の場合は左から右、それ以外は右から左 | テキスト方向判定時 |
| BR-002 | クラスタマッピング | 複数グリフが1文字に対応する場合、同じGlyphCluster値を持つ | 複雑スクリプト処理時 |
| BR-003 | トレイリング空白 | 末尾の空白文字は別途カウントし、Widthから除外される | メトリクス計算時 |
| BR-004 | プラットフォーム実装遅延生成 | PlatformImplは初回アクセス時に生成される | 描画時 |

### 計算ロジック

**スケール計算**:
```
Scale = FontRenderingEmSize / GlyphTypeface.Metrics.DesignEmHeight
```

**ベースライン計算**:
```
Ascent = GlyphTypeface.Metrics.Ascent * Scale
LineGap = GlyphTypeface.Metrics.LineGap * Scale
Baseline = -Ascent + LineGap * 0.5
```

**幅計算**:
```
WidthIncludingTrailingWhitespace = Sum(glyphInfos[i].GlyphAdvance)
Width = WidthIncludingTrailingWhitespace - トレイリング空白幅
```

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

該当なし（メモリ上での処理のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | InvalidOperationException | PlatformImplの作成に失敗した場合 | グリフ情報とタイプフェースを確認 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- GlyphRunMetricsは遅延計算でキャッシュされる
- プロパティ変更時は_platformImplと_glyphRunMetricsを無効化
- CreateGlyphInfosではstackallocを使用（256要素以下の場合）

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

特になし

## 備考

GlyphRunはIDisposableを実装しており、PlatformImplのリソースを適切に解放する必要がある。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | GlyphRun.cs | `src/Avalonia.Base/Media/GlyphRun.cs` | フィールド定義（16-25行目）: _platformImpl, _fontRenderingEmSize, _glyphRunMetrics等 |
| 1-2 | GlyphInfo.cs | `src/Avalonia.Base/Media/GlyphInfo.cs` | グリフ情報構造体（GlyphIndex, GlyphCluster, GlyphAdvance） |
| 1-3 | GlyphRunMetrics.cs | `src/Avalonia.Base/Media/GlyphRunMetrics.cs` | メトリクス構造体 |

**読解のコツ**: GlyphInfoはグリフインデックス、クラスタ（元の文字位置）、アドバンス幅の3つの値を保持する。クラスタはBiDi対応で重要。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | GlyphRun.cs | `src/Avalonia.Base/Media/GlyphRun.cs` | コンストラクタ（41-52行目, 63-82行目）: 2種類のコンストラクタ |

**主要処理フロー**:
1. **41-52行目**: glyphIndicesを受け取るコンストラクタ（CreateGlyphInfosを呼び出し）
2. **63-82行目**: glyphInfosを受け取るコンストラクタ（直接設定）
3. **84-90行目**: 内部コンストラクタ（プラットフォーム実装から作成）

#### Step 3: グリフ情報変換処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | GlyphRun.cs | `src/Avalonia.Base/Media/GlyphRun.cs` | CreateGlyphInfos（92-113行目）: glyphIndicesからGlyphInfo配列を生成 |

**主要処理フロー**:
- **96-102行目**: stackallocの最適化
- **104行目**: TryGetHorizontalGlyphAdvancesでadvance幅を取得
- **106-109行目**: GlyphInfo配列を構築

#### Step 4: メトリクス計算処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | GlyphRun.cs | `src/Avalonia.Base/Media/GlyphRun.cs` | CreateGlyphRunMetrics（666-732行目）: メトリクス計算 |
| 4-2 | GlyphRun.cs | `src/Avalonia.Base/Media/GlyphRun.cs` | GetTrailingWhitespaceLength（734-798行目）: トレイリング空白計算 |

**主要処理フロー**:
- **670-679行目**: FirstCluster/LastClusterの決定
- **688-698行目**: 幅の計算
- **717-719行目**: ベースラインの計算

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | GlyphRun.cs | `src/Avalonia.Base/Media/GlyphRun.cs` | GetDistanceFromCharacterHit（249-328行目）: 文字位置→距離 |
| 5-2 | GlyphRun.cs | `src/Avalonia.Base/Media/GlyphRun.cs` | GetCharacterHitFromDistance（339-416行目）: 距離→文字位置 |
| 5-3 | GlyphRun.cs | `src/Avalonia.Base/Media/GlyphRun.cs` | FindGlyphIndex（476-550行目）: 文字インデックス→グリフインデックス |

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

```
GlyphRun
    │
    ├─ Constructor (glyphIndices版)
    │      └─ CreateGlyphInfos
    │             └─ GlyphTypeface.TryGetHorizontalGlyphAdvances
    │
    ├─ Metrics (プロパティ)
    │      └─ CreateGlyphRunMetrics
    │             ├─ GetTrailingWhitespaceLength
    │             │      └─ GetTrailingWhitespaceLengthRightToLeft
    │             └─ GlyphRunMetrics生成
    │
    ├─ GetDistanceFromCharacterHit
    │      └─ FindGlyphIndex
    │
    ├─ GetCharacterHitFromDistance
    │      └─ FindNearestCharacterHit
    │
    ├─ BuildGeometry
    │      └─ IPlatformRenderInterface.BuildGlyphRunGeometry
    │
    └─ PlatformImpl
           └─ CreateGlyphRunImpl
                  └─ IPlatformRenderInterface.CreateGlyphRun
```

### データフロー図

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

GlyphTypeface ─────────▶ GlyphRun ──────────────────▶ GlyphRunMetrics
GlyphIndices/GlyphInfos       │                         (Width, Height等)
FontRenderingEmSize           │
                              ▼
                        CreateGlyphInfos ───────────▶ GlyphInfo[]
                        (グリフ情報変換)                (Index,Cluster,Advance)
                              │
                              ▼
                        PlatformImpl ───────────────▶ 描画出力
                        (プラットフォーム実装)          (Skia等)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| GlyphRun.cs | `src/Avalonia.Base/Media/GlyphRun.cs` | ソース | メインクラス実装 |
| GlyphInfo.cs | `src/Avalonia.Base/Media/GlyphInfo.cs` | ソース | グリフ情報構造体 |
| GlyphRunMetrics.cs | `src/Avalonia.Base/Media/GlyphRunMetrics.cs` | ソース | メトリクス構造体 |
| GlyphTypeface.cs | `src/Avalonia.Base/Media/GlyphTypeface.cs` | ソース | グリフタイプフェース |
| CharacterHit.cs | `src/Avalonia.Base/Media/CharacterHit.cs` | ソース | キャラクターヒット構造体 |
| IGlyphRunImpl.cs | `src/Avalonia.Base/Platform/IGlyphRunImpl.cs` | ソース | プラットフォーム抽象化 |
| GlyphRunImpl.cs | `src/Skia/Avalonia.Skia/GlyphRunImpl.cs` | ソース | Skia実装 |
