# 機能設計書 18-フォント機能

## 概要

本ドキュメントは、GhosttyのOpenTypeフォント機能設定の設計について記述する。フォントのリガチャ、カーニング、字形バリアントなどのOpenType機能を設定・制御する機能である。

### 本機能の処理概要

**業務上の目的・背景**：
OpenTypeフォントは多数の機能（Features）を持ち、リガチャ（liga）、カーニング（kern）、字形バリアント（cv01-cv99）などを提供する。本機能は、HarfBuzzのフォント機能文字列構文と互換性のある形式で、これらの機能を有効化・無効化・パラメータ設定できるようにする。

**機能の利用シーン**：
- プログラミング用リガチャの有効化（Fira Code等）
- リガチャの無効化（合字が不要な場合）
- 特定の字形バリアントの選択
- カーニングの調整

**主要な処理内容**：
1. フォント機能文字列のパース
2. 4バイトタグと値のペアへの変換
3. FeatureListへの追加
4. HarfBuzzシェイパーへの適用
5. デフォルト機能（liga）の管理

**関連システム・外部連携**：
- HarfBuzz（テキストシェイピングエンジン）
- 設定システム（font-feature設定）

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインターミナルウィンドウ | 主画面 | フォント機能適用後のテキスト表示 |

## 機能種別

フォント処理 / OpenType機能管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| str | []const u8 | Yes | フォント機能設定文字列 | HarfBuzz互換構文 |

### 入力データソース

- 設定ファイル（font-feature設定）

### 構文例

```
kern                 # 機能を有効化
+kern                # 機能を明示的に有効化
-kern                # 機能を無効化
kern on              # "on"キーワードで有効化
kern off             # "off"キーワードで無効化
"kern" = 1           # 引用符付きタグ、数値指定
aalt=2               # 数値パラメータ指定
kern, liga, -calt    # カンマ区切りで複数指定
```

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| tag | [4]u8 | OpenType機能タグ（4バイト） |
| value | u32 | 機能の値（0=無効、1=有効、その他=パラメータ） |

### 出力先

HarfBuzzシェイパー

## 処理フロー

### 処理シーケンス

```
1. 文字列パース開始
   └─ Feature.fromReader()で1機能ずつパース
2. 状態機械による解析
   └─ start → tag → space → int/bool → done
3. タグ抽出
   └─ 4バイトのタグを抽出
4. 値決定
   └─ +/-プレフィックス、数値、on/offキーワードから決定
5. Feature構造体生成
   └─ tag + value のペアを生成
6. FeatureListへの追加
   └─ 複数の機能をリストとして管理
```

### フローチャート

```mermaid
flowchart TD
    A[文字列入力] --> B{先頭文字}
    B -->|+| C[value = 1]
    B -->|'−'| D[value = 0]
    B -->|引用符| E[タグ開始]
    B -->|文字| F[タグ抽出]
    C --> F
    D --> F
    E --> F
    F --> G{4バイト?}
    G -->|No| H[エラー]
    G -->|Yes| I{値指定}
    I -->|なし| J[value = 1]
    I -->|数値| K[value = 数値]
    I -->|on/off| L[value = 1/0]
    J --> M[Feature生成]
    K --> M
    L --> M
    M --> N{カンマ?}
    N -->|Yes| A
    N -->|No| O[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | デフォルトliga | ligaは常にデフォルトで有効 | 初期状態 |
| BR-02 | タグ長 | タグは必ず4バイト | 常時 |
| BR-03 | 値範囲 | 値は0以上のu32 | 常時 |
| BR-04 | エラー許容 | 無効な構文はスキップして継続 | パース時 |

### 計算ロジック

- ブール値: value 0 = 無効、value 1 = 有効
- cv01-cv99: 字形バリアント番号を value で指定
- aalt: 代替字形番号を value で指定

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| null | パースエラー | タグが4バイト未満 | スキップして次の機能を処理 |
| null | パースエラー | 無効な構文 | スキップして次の機能を処理 |
| null | パースエラー | 値のオーバーフロー | スキップして次の機能を処理 |

### リトライ仕様

リトライなし。エラー時は該当機能をスキップ。

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

該当なし

## パフォーマンス要件

- パースはフォントロード時のみ実行
- 状態機械によるO(n)パース
- メモリ効率的なArrayListUnmanaged使用

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

特になし

## 備考

- HarfBuzzのhb-commonドキュメント参照
- Nerd Fontsとの組み合わせで効果的

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | feature.zig | `src/font/shaper/feature.zig` | Feature構造体（16-18行目） |
| 1-2 | feature.zig | `src/font/shaper/feature.zig` | FeatureList構造体（224-284行目） |
| 1-3 | feature.zig | `src/font/shaper/feature.zig` | default_features定義（288-290行目） |

**読解のコツ**: Feature構造体はtag（4バイト配列）とvalue（u32）の単純な構造。FeatureListはArrayListUnmanagedで複数のFeatureを管理する。

#### Step 2: パーサー実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | feature.zig | `src/font/shaper/feature.zig` | fromString関数（20-24行目） |
| 2-2 | feature.zig | `src/font/shaper/feature.zig` | fromReader関数（36-189行目） |
| 2-3 | feature.zig | `src/font/shaper/feature.zig` | 状態機械enum（41-56行目） |

**主要処理フロー**:
1. **41-56行目**: 状態機械の状態定義（start, tag, space, int, bool, err, done）
2. **73-98行目**: 開始状態での+/-プレフィックスと引用符処理
3. **100-113行目**: タグの4バイト抽出
4. **115-143行目**: 空白スキップと値の開始検出
5. **145-179行目**: 数値またはon/offキーワードのパース

#### Step 3: リスト管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | feature.zig | `src/font/shaper/feature.zig` | FeatureList.fromString（233-237行目） |
| 3-2 | feature.zig | `src/font/shaper/feature.zig` | appendFromString（241-257行目） |

**主要処理フロー**:
- **246-256行目**: カンマ区切りでループしながらFeatureをパース
- **250-251行目**: 成功したFeatureをリストに追加
- **252-255行目**: 失敗時はログ出力してスキップ

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

```
設定ロード
    │
    └─ font-feature設定の読み込み
           │
           └─ FeatureList.fromString(str)
                  │
                  └─ appendFromString(str)
                         │
                         └─ [ループ]
                                │
                                └─ Feature.fromReader(reader)
                                       │
                                       ├─ [状態: start]
                                       │      └─ +/-/引用符/文字の処理
                                       │
                                       ├─ [状態: tag]
                                       │      └─ 4バイトタグ抽出
                                       │
                                       ├─ [状態: space]
                                       │      └─ =, 数字, on/offの検出
                                       │
                                       ├─ [状態: int]
                                       │      └─ 数値パース
                                       │
                                       └─ [状態: bool]
                                              └─ on/offキーワード処理

HarfBuzzシェイパー
    │
    └─ 各Featureをhb_feature_tに変換
           └─ テキストシェイピング時に適用
```

### データフロー図

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

"kern, -liga"  ────▶ fromReader() ─────────▶ Feature{tag="kern", value=1}
        │                                     Feature{tag="liga", value=0}
        │
        └─▶ FeatureList.features ───▶ [Feature, Feature, ...]

default_features ─▶ HarfBuzz ────▶ シェイプ済みテキスト
        +                │
ユーザー設定 ───────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| feature.zig | `src/font/shaper/feature.zig` | ソース | フォント機能パーサーとデータ構造 |
| harfbuzz.zig | `src/font/shaper/harfbuzz.zig` | ソース | HarfBuzzシェイパー（機能適用） |
| Config.zig | `src/config/Config.zig` | ソース | font-feature設定定義 |
