[20] [DFN[[RUBYB[[RUBY[結][けつ]][RUBY[合][ごう]][RUBY[文][も]][RUBY[字][じ]]]@en[combining character]]]]は、
直前の[[基底文字]]と[[合成]]されて表示されるべき[[文字]]です。

* 仕様書

[REFS[
- [142] [CITE[[[The Unicode Standard]], Version 13.0 - ch02.pdf]], [TIME[2020-03-09T17:53:32.000Z]], [TIME[2020-12-06T08:54:12.180Z]] 
<https://www.unicode.org/versions/latest/ch02.pdf#G1708>
- [209] [CITE[[[The Unicode Standard]], Version 13.0 - ch03.pdf]], [TIME[2020-03-09T17:53:34.000Z]], [TIME[2020-12-31T08:45:19.650Z]] <https://www.unicode.org/versions/latest/ch03.pdf#G50313>
- [9] [CITE[[[The Unicode Standard]], Version 12.0 - ch03.pdf]] ([TIME[2019-03-02 07:15:30 +09:00]]) <http://www.unicode.org/versions/latest/ch03.pdf#G30602>
-- [30] D53
-- [38] D54
-- [39] D55
-- [45] D56
-- [47] D56a
-- [49] D57
-- [115] [CSECTION[Application of Combining Marks]]
<https://www.unicode.org/versions/latest/ch03.pdf#G50030>
- [185] [CITE[The Unicode Standard, Version 13.0 - ch05.pdf]], [TIME[2020-03-09T17:53:36.000Z]], [TIME[2020-12-08T11:02:06.579Z]] <https://www.unicode.org/versions/latest/ch05.pdf#M9.31810.Heading.511.Strategies.for.Handling.NonSpacing.Marks>
- [164] [CITE[[[The Unicode Standard]], Version 13.0 - ch07.pdf]], [TIME[2020-03-09T17:53:38.000Z]], [TIME[2020-12-07T09:15:13.901Z]] <https://www.unicode.org/versions/latest/ch07.pdf#M9.37081.HeadingBreak.79.Combining.Marks>
- [18] [CITE@en-us[Glossary]] ([TIME[2014-12-06 10:49:08 +09:00]] 版) <https://unicode.org/glossary/#combining_mark>
-
[278] 
[CITE@en-us[UAX #15: Unicode Normalization Forms]], [TIME[2024-08-14T19:11:21.000Z]], [TIME[2025-07-02T03:56:32.187Z]] <https://unicode.org/reports/tr15/#UAX15-D3>
- [53] [CITE@en-us[UAX #44: Unicode Character Database]], [TIME[2020-03-06T22:23:11.000Z]], [TIME[2020-10-21T06:24:49.510Z]] <https://www.unicode.org/reports/tr44/#Default_Values_Table>
- [103] [CITE@en-us[[[UAX #44]]: Unicode Character Database]] ([TIME[2016-06-21 02:42:04 +09:00]]) <https://www.unicode.org/reports/tr44/#General_Category_Values>
- [54] [CITE@en-us[UAX #44: Unicode Character Database]], [TIME[2020-03-06T22:23:11.000Z]], [TIME[2020-10-21T08:24:32.981Z]] <https://www.unicode.org/reports/tr44/#Derived_Extracted>
-[55] [CITE@en-us[UAX #44: Unicode Character Database]], [TIME[2020-03-06T22:23:11.000Z]], [TIME[2020-10-21T08:37:23.285Z]] <https://www.unicode.org/reports/tr44/#Canonical_Combining_Class_Values>
- [56] [CITE@en-us[UAX #44: Unicode Character Database]], [TIME[2020-03-06T22:23:11.000Z]], [TIME[2020-10-21T08:49:23.551Z]] <https://www.unicode.org/reports/tr44/#Property_Invariants>
- [101] [CITE@en-us[[[UTS #46]]: Unicode IDNA Compatibility Processing]] ([TIME[2016-06-02 03:53:22 +09:00]]) <https://www.unicode.org/reports/tr46/#Validity_Criteria>
- [57] [CITE@en-us[UAX #44: Unicode Character Database]], [TIME[2020-03-06T22:23:11.000Z]], [TIME[2020-10-21T08:53:55.034Z]] <https://www.unicode.org/reports/tr44/#Invariants_in_Implementations>
]REFS]


[116] 
[[結合文字]]の[[適用]]については、
[CITE[The Unicode Standard]]
は[[規定]]と[DFN[[RUBYB[[[指針]]][guideline]]]]を示しています。
特に[[文字のレンダリング]]に関する指針については、
[[レンダリング]]について特に情報が与えられない場合の既定のレンダリングの挙動を示すものとされています。
個々の文字について [[typograph]] 的な慣習がある場合には、
適宜それを使って最適な[[レンダリング]]を実現することが期待されています。
[SRC[>>115]]

[141] 
[[文字]]の扱いは文化と慣習に依存した部分が大きく、
[[フォント]]や[[レンダリングシステム][文字のレンダリング]]の影響も大きいので、
厳密に[[規定]]することには困難が多いのでしょう。
それにしても曖昧な規則が多く、
こんなので[[相互運用性]]は保てるのか疑問に思ってしまいますが、
実際[[相互運用性]]はかなり低いと言わざるを得ません。
違うシステムで[[レンダリング]]が違うのは当たり前で、
同じシステムでもインストールされている[[フォント]]の違い程度の些細な要因で違って表示されることがよくあるのが現状です。


* 結合文字とその分類

[10] [DFN[[RUBYB[結合文字]@en[combining character]]]] =
[DFN[[RUBYB[結合マーク]@en[combining mark]]]]は、
[CODE[General_Category]] が
[DFN[Combining Mark]] ([DFN[[CODE[Mark]]]], [DFN[[CODE[M]]]]) の[[文字]]
([[符号位置]])
です。
[SRC[>>9, >>101, >>18]]

[12] [[私用文字]] ([CODE[[[Co]]]]) を[[結合文字]]と解釈するか否かは、
[[実装]]によります [SRC[>>9]]。
原則は[[基底文字]]扱いとされています。
[SEE[ [[基底文字]]、[[私用文字]] ]]

[143] 
[[結合文字]]は、
[[関連付けられた基底文字]]に対して相対的に決まる位置に表示される[[文字]]です
[SRC[>>142]]。

[150] 
具体的には、
[[アルファベット]]系文字などに対する[[ダイアクリティカルマーク]]、
[[アラビア文字]]の [[harakat]]、
[[デバナガリ文字]]の [[matra]]、
[[仮名]]の[[濁点]]・[[半濁点]]、
[[記号用ダイアクリティカルマーク][symbol diacritic]]、
[[囲み文字]]を作るための[[外枠文字]]などが[[結合文字]]として用意されています。

[210] 
[[異体列]]に使われる[[異体選択子]]も[[結合文字]]とされています。


[REFS[
- [23] [[結合文字]]の一覧 ([[結合文字]]と解釈する [CODE[Co]] を除く)
<https://chars.suikawiki.org/set/%24unicode%3Acombining-character>
- [31] [CODE[[[General_Category]]=[[M][Mark]]]] の一覧
<https://chars.suikawiki.org/set/%24unicode%3AMark>
]REFS]

[144] [[結合文字]]には、
[[非前進マーク]]と[[前進マーク]]があります。
[SRC[>>142]]


- [24] [DFN[[RUBYB[非前進マーク][nonspacing mark]]]]は、
[[General Category]]
が
[[Nonspacing Mark]] ([DFN[[CODE[Mn][Nonspacing Mark]]]])
か
[[Enclosing Mark]] ([DFN[[CODE[Me][Enclosing Mark]]]])
の[[結合文字]]です。
[SRC[>>30]]
--
[29] 
[DFN[[RUBYB[囲みマーク][enclosing mark]]]]は、
[[非前進マーク]]であって
[[General Category]]
が
[[Enclosing Mark]] ([DFN[[CODE[Me][Enclosing Mark]]]])
であるものです。
[[囲みマーク]]は、
[[非前進マーク]]の[[部分クラス]]であって、
[[基底文字]]の上中下に配置するのではなく、囲むものです。
[SRC[>>38]]
--
[145] 
[[非前進マーク]]は、
それ自体で表示上の位置 (spacing position)
を占有しません [SRC[>>142]]。
[[基線]]上を先へと進み (baseline advance) ません
[SRC[>>164]]。
ただし[[基底文字]]が単独の場合と、
[[基底文字]]と[[非前進マーク]]との組合せの場合とで文字幅 (advance width)
が変わってくることはあります
[SRC[>>142]]。
-
[40] 
[DFN[[RUBYB[前進マーク][spacing mark]]]]は、
[[結合文字]]であって[[非前進マーク]]ではないものです。
[SRC[>>39]]
--
[165] 
[[前進マーク]]は通常の文字のような挙動を示し [SRC[>>164]]、
それ自体の幅を占有します。
他の文字と複雑に作用することがあります [SRC[>>164]]。
-- [206] 
[CODE[General_Category]] は [DFN[[CODE[Mc]]]] です。
-- [207] 
[[異体選択子]]と併用して[[異体列]]を作ることが出来ます。

;; [166] 
[[Unicode]] 以前の[[文字コード]]で[[結合文字]]に相当するものは[[非spacing文字]]などと言っていました。
しかし [[Unicode]] の[[結合文字]]には [[spacing]] な文字も[[非spacing]]
な文字もあるのです。

[113] この分類は[[書記素クラスター]]の定義に関わってきます。



[26] 
[CODE[General_Category]] の値 
[CODE[Mark]] = [CODE[M]]
は、
[[Spacing Combining Mark]] ([CODE[[[Mc]]]]),
[[Nonspacing Mark]] ([CODE[[[Mn]]]]),
[[Enclosing Mark]] ([CODE[[[Me]]]])
のいずれかであることを表します。 
[SRC[>>9, >>103]]



[REFS[
- [44] [[nonspacing mark]] の一覧
<https://chars.suikawiki.org/set/%24unicode%3Anonspacing-mark>
- [43] [[enclosing mark]] の一覧
<https://chars.suikawiki.org/set/%24unicode%3Aenclosing-mark>
- [109] [[spacing mark]] の一覧 ([[結合文字]]と解釈する [CODE[Co]] を除く)
<https://chars.suikawiki.org/set/%24unicode%3Aspacing-mark>
- [110] [CODE[[[General_Category]]=[[Mn]]]] の一覧
<https://chars.suikawiki.org/set/%24unicode%3AMn>
- [111] [CODE[[[General_Category]]=[[Me]]]] の一覧
<https://chars.suikawiki.org/set/%24unicode%3AMe>
- [112] [CODE[[[General_Category]]=[[Mc]]]] の一覧
<https://chars.suikawiki.org/set/%24unicode%3AMc>
]REFS]

[211] 
[CODE(charname)@en[ZWJ]],
[CODE(charname)@en[ZWNJ]]
は[[結合文字列]]に含まれ得る[[文字]]で、
[[結合文字]]に近い扱いを受けていますが、
[[結合文字]]ではありません。


* 結合文字列


[13] [[結合文字]]は、通常は単独では用いません。 [SRC[>>9]]
[[基底文字]]の後に0個以上の[[結合文字]]を続ける形で使います。
[[結合文字]]は、その[[依存]]する[[基底文字]]の後に続けます
[SRC[>>115 P1, >>142, >>164]]。


;;
[151] 
この順序は、
[[Semitic scripts]]
と[[インド系文字]]の[[論理順]]と一貫したものとされます。
更に、
近代[[フォント]]技術の [[nonspacing]] 
な[[グリフ]]の取り扱いとも合致しているため処理しやすいとされます。
[SRC[>>142, >>164]]


[HISTORY[
[83] 
[[Unicode]]
の[[結合文字]]は後置です。
[[Unicode]] 以前の[[文字コード]]規格には前置式を採用したものもありましたが、
[[Unicode]]
との変換では順序を入れ替える必要があります。
[SEE[ [[非spacing文字]] ]]
]HISTORY]

-*-*-

[156] 
[[結合文字]]の数には制限がありません。
[SRC[>>142, >>115]]

[229] 
現実には、[[セキュリティー]]のため実装は現実的な個数に制限する必要があります。
[SEE[ [[プラットフォーム制限条項]] ]]
上限を超えた場合は、合成しないで表示するなど、代替手段を採ることになります。

[277] 
[DFN[Stream-Safe Text Format]]
では、 [[NFKD]] 状態で30個以下と制限されています。
この制限は、
実用よりも十分長く、実装上のバッファー長に余裕がある ([[UTF-8]] でも 
[[UTF-16]] でも [[UTF-32]] でも
128バイトを超えない)
と説明されています。
[SRC[>>278 ([DFN[UAX15-D3]])]]


-*-*-


[46] 
[DFN[[RUBYB[結合文字列][combining character sequence]]]] ([DFN[CCS]]) は、
[[基底文字]]が0個または1個の後に、
1つ[[以上]]の[[結合文字]]、
[CODE(charname)@en[ZERO WIDTH JOINER]]、
[CODE(charname)@en[ZERO WIDTH NON-JOINER]]
のいずれかが続くような列であって最長のものです。
[SRC[>>45]]



[FIG(railroad)[
= ?
== [[基底文字]]
= +
== |
=== [[結合文字]]
=== [CODE(charname)@en[ZERO WIDTH JOINER]]
=== [CODE(charname)@en[ZERO WIDTH NON-JOINER]]

]FIG]

[48] 
[DFN[[RUBYB[拡張済み結合文字列][extended combining character sequence]]]] ([DFN[ECCS]]) は、
[[拡張済み基底]]が0個または1個の後に、
1つ[[以上]]の[[結合文字]]、
[CODE(charname)@en[ZERO WIDTH JOINER]]、
[CODE(charname)@en[ZERO WIDTH NON-JOINER]]
のいずれかが続くような列であって最長のものです。
[SRC[>>47]]

[FIG(railroad)[
= ?
== [[拡張済み基底]]
= +
== |
=== [[結合文字]]
=== [CODE(charname)@en[ZERO WIDTH JOINER]]
=== [CODE(charname)@en[ZERO WIDTH NON-JOINER]]

]FIG]

;; [80] ただの[[結合文字列]]とは、
[[標準韓音節ブロック]]が含まれるかどうかが違います。
[SEE[ [[拡張済み基底]] ]] 

[82] 
「結合文字」の列というと0文字以上の[[結合文字]]の列のように聞こえますが、
実はそうではなく[[基底文字]]も (あれば) 含まれますし、
[[結合文字]]のかわりに
[CODE(charname)@en[ZWJ]] / [CODE(charname)@en[ZWNJ]]
が含まれる列のこともあります。

[114] 
[[結合文字列]]、
[[拡張済結合文字列]]は[[書記素クラスター]]と似ていますが、
違うこともあります。
[SEE[ [[書記素クラスター]] ]]



[212] 
[[結合文字]]の順序には、意味があることも、ないこともあります。
(>>186)


[HISTORY[
[146] 
[[Unicode]]
と
[[Unicode]]
以外の[[文字コード]]を混在させられるシステムもあります。
例えば
[[ISO/IEC 2022]]
は
[[ISO/IEC 10646]]
と混在させる仕組みを定義しています。
すると
[[Unicode]] ([[ISO/IEC 10646]])
とそれ以外の[[基底文字]]と[[結合文字]]の組合せも理屈の上では存在し得ます。
しかし
[[Unicode]]
はそうしたものを想定していないので何も言及していませんし、
[[ISO/IEC 2022]]
側にもそうした[[規定]]はありません。
結局そのようなシステムがどう動作するべきかは不明と言わざるを得ません。

[232] 
現実的には、
そのシステムにおいて [[Unicode文字]]と[[非Unicode文字]]に対応関係が存在するなら、
その対応関係に基づきすべて[[Unicode文字]]だった場合と同等に動作するのでしょうし、
そうでなくても[[非Unicode文字]]が[[基底文字]]であるか、
[[結合文字]]相当のものであるかに応じて動作するのでしょう。
]HISTORY]

[HISTORY[
[233] 
また[[非spacing文字]]など [[Unicode]] にない概念の文字と [[Unicode文字]]との組み合わせもありえます。

[234] 
すると[[基底文字]]、[[結合文字]]、[[非spacing文字]]のすべての組み合わせで構成される[[文字列]]の出現の可能性も一応考えておかなければなりません。

]HISTORY]


** 基底文字と結合文字の関係性


[88] 
[[結合文字]]の[DFN[[RUBYB[関連付けられた基底文字][associated base character]]]]は、
その属する[[結合文字列]]中の[[基底文字]]です。
[SRC[>>115 D61a]]

[14] [[結合文字]]の[[図形]]の位置付けは、直前の[[基底文字]]であって非[[結合文字]]で
[[zero width joiner]] でも [[zero width nonjoiner]] でもないものに依存します。
この時[[結合文字]]を[[基底文字]]に[DFN[[RUBYB[適用する]@en[apply]]]]といいます。 [SRC[>>9]]
[[結合文字]]は[[関連付けられた基底文字]]に[DFN[[RUBYB[依存する][depend]]]]といいます
([DFN[[RUBYB[依存性][dependence]]]])
[SRC[>>115 D61a]]。

[118] [[関連付けられた書記素基底]]とそれへの[[適用][関連付けられた書記素基底]]
([[図形的適用]])
と似た意味ですが、
少しずつ定義が違います。
[[依存性]]はすべての種別の[[結合文字]]に関係します。
[[図形的適用]]は可視[[グリフ]]を持つ
[[nonspacing mark]]
に関係します。



** 孤立結合文字

[15] [[結合文字]]が[[適用]]されるべき[[基底文字]]がない場合 
([[結合文字]]が[[文字列]]の先頭の場合や、
[[制御文字]]や[[書式文字]]が前にある場合) には、
[DFN[[RUBYB[[[孤立結合文字]]]@en[isolated combining character]]]]といいます。 [SRC[>>9]]


[81] 
[[結合文字列]]のうち[[基底文字]]がないものを[DFN[[RUBYB[欠陥結合文字列][defective combining character sequence]]]]といいます。
[SRC[>>49]]

[117] 
[[欠陥結合文字列]]中の[[結合文字]]には[[関連付けられた基底文字]]がありません。
どの[[基底文字]]にも[[依存する]]とはいえません。
[SRC[>>115 D61a]]


[19] 
[[完全正規化済み]]など孤立した[[結合文字]]が出現しないことを要求する[[応用]]もあります。


[89] 
意図的に使うことはあまりありませんが、
[[Unicode文字]]の一覧表などに出現することがあります。
[[結合文字]]を考慮しない[[文字列]]の分断 (一定の文字列長での分割など)
で生じることもあります。

[198] 
なお、
文頭において[[結合文字]]を含まず
[CODE(charname)@en[ZWJ]],
[CODE(charname)@en[ZWNJ]]
のみで構成される[[欠陥結合文字列]]は、
正当に利用され得るものであるはずです。
[SEE[ [[続け字]] ]]

[231] 
[[結合文字]]は[[フォント]]上で[[現在位置]]より前に表示されるなど、
単独で[[レンダリング]]するとき取り扱いに注意を要することがあります。

** 結合文字と空白の合成


[86] 
[[結合文字]]自体を単独の[[文字]]として使いたいときは、
[[基底文字]]として
[CODE(char)[U+00A0]] [CODE(charname)@en[NO-BREAK SPACE]]
を使うことが出来ます。
[SRC[>>142, >>164]]

[162] 
[[Unicode 4.1]]
までは、
[CODE(char)[U+0020]] [CODE(charname)@en[SPACE]]
を使うことが[RUBYB[[[推奨]]][recommended]]されていましたが、
推奨されなくなりました。
[[XML]]
などの 
[CODE[U+0020]]
の扱いと衝突することが理由とされています。
[SRC[>>142, >>164]]

[87] 
[[HTML]] と [[CSS]] ([CODE[white-space:normal]])
のような[[空白]]を正規化する処理が適用される環境では、
[CODE[U+0020]] を使うと思わぬ意図せぬ結果がもたらされることがあります。

[92] 
[[CSS]] の [CODE[text-emphasis]] は [CODE[Z*]] 
の文字かどうかで挙動が変わりますが、
[[間隔]]と[[結合文字]]が組み合わさったケースでは一般の文字と同じ扱いになります。

[163] 
[CITE[The Unicode Standard]]
の「推奨」
は変更されましたが、
[[互換分解]]は変更されていません (一度決めたら変更されないこととされています)。
多くの単独の[[ダイアクリティカルマーク]]は
[[NFKC]]、
[[NFKD]]
を適用すると
[CODE[U+0020]] 
が生成されてしまいます [SRC[>>164]]。
(もっとも [CODE[U+00A0]] も [[NFKC]], [[NKFD]] では [CODE[U+0020]]
になります。)


[269] 
単独の[[ダイアクリティカルマーク]]と、それを[[互換分解]]したものとで、
期待される[[レンダリング]]が異なることがあります。
[SEE[ [[発音区別符付き仮名]] ]]


[235] [[方向性]]との相互作用にも注意が必要です (>>169)。

[270] 
[[縦書き]]との関係にも注意が必要です。
例えば[CH[゛]]を[[空白]]と[[結合文字]]との組み合わせで表現したいからといって、
[CC[U+0020]] や [CC[U+00A0]] や [CC[U+2003]] と [CC[U+3039]] を組み合わせると、
[[縦書き]]したときに[[回転して寝かされて][回転 (書字方向)]]しまいます。


[271] 
[CC[U+3000]] と [CC[U+3099]] や [CC[U+309A]] を組み合わせると、
[[Windows]] の [[Firefox]] では適切に表示されますが、
[[Windows]] の [[Chrome]] ではなぜか[[フォント]]の指示に従って表示されません。
[CC[U+3099]] や [CC[U+309A]] は明らかに別の[[フォント]]で、
[[基底文字]]の隣に分かれてレンダリングされます。
すべての[[Unicode符号位置]]の[[グリフ]]を持つ[[フォント]]を指定しても、
それではない[[フォント]]の[[濁点]]が表示されてしまいます。謎です。
[CC[U+0020]] や [CC[U+00A0]] や [CC[U+2003]] [CN[EM SPACE]]
ではこのような怪現象は発生しないのですが、
[CC[U+3000]]
だけ特殊な表示処理があるのでしょうか。
他の[[結合文字]]でも発生しないようです。
[TIME[2025-01-28T13:03:00.100Z]]




** 基底文字の種類

[85] 
[[結合文字]]が[[適用]]される[[基底文字]]には制約がありません。
すべての[[結合文字]]は、すべての[[基底文字]]に対して使うことが出来ます
[SRC[>>142]]。
普通はありえない[[基底文字]]と[[結合文字]]の組合せ、
例えば[[基底文字]]を「。」 ([[句点]])、
[[結合文字]]を[[濁点]]とするような組合せは[[日本語]]としておおよそあり得ませんが、
[[Unicode]]
として禁止されていません。
(それが意味を成すか、
意図した通りにレンダリングされるかどうかは、
また別の問題です。 >>148)



-*-*-


[169] 
[CODE[U+00A0]]
を始め[[中立方向性]]の[[文字]]を[[基底文字]]とするとき、
[[bidi]]
処理によって[[基底文字]]と[[spacing結合文字]]が分離されて意図せぬ形で表示される場合があります。
[SRC[>>164]]
これを避けるには
[CODE(charname)@en[LRM]],
[CODE(charname)@en[RLM]],
[CODE(HTMLe)@en[bdi]]
の類を適宜使う必要があります。

-*-*-


[139] 
[[韓音節]]の[[書記素クラスター]]にあっては、
[[結合文字]]は最後の[[字母]]だけではなく[[音節]]全体に[[適用]]されます。
[[enclosing combining mark]]
も[[音節]]全体を囲みます。
[SRC[>>115]]

;; [225] 
[[ハングル音節]]に対しては、[[声調符号]]や[[濁点]]が付与されることがあります。


[161] 
[[基底文字]]の並びが[[合字]]として表示される場合であっても、
[[結合文字]]はそれが[[適用]]されるべき各部分の[[基底文字]]の後に置きます。
[[結合文字]]は [[ligated glyph]] の各部分に対して表示します。
[SRC[>>142, >>164]]

;; [175] ただし[[合字]]になるかどうかは
[[typographic]] 的な慣習に依存します。
[[ダイアクリティカルマーク]]が付かない時[[合字]]化されても、
[[ダイアクリティカルマーク]]が付いたことで[[合字]]化されないこともあります。
[SRC[>>164]]




* 性質

[11] [[正準結合クラス]]が 0 でない[[文字]]は、[[結合文字]]です。
しかし[[逆]]は真ではありません。[[正準結合クラス]]が 0 の[[結合文字]]もあります。 [SRC[>>9]]

;; [22] >>21 は、[[正準結合クラス]]が 0 の[[結合文字]]の一覧です。
[REFS[
- [21] [CITE@en[Character set "$unicode:Mn | $unicode:Mc | $unicode:Me - $unicode:Canonical_Combining_Class:non-0"]] ([TIME[2015-03-22 23:52:41 +09:00]] 版) <https://chars.suikawiki.org/set?expr=%24unicode%3AMn+%7C+%24unicode%3AMc+%7C+%24unicode%3AMe+-+%24unicode%3ACanonical_Combining_Class%3Anon-0>
]REFS]


[153] 
多くの[[アルゴリズム]] (すべてではありません。) は、
[[基底文字]]に[[結合文字]]が続く列を、
[[基底文字]]の[[特性][特性 (UCD)]]を持つものとして扱います。
[SRC[>>142]]
(これがうまく機能しないケースもあります (>>149)。)


* 結合文字相互の順序

[186] 
1つの[[基底文字]]に対して、
[[結合文字]]はいくつでも[[適用]]できます。
[[結合文字]]の順序には制約がありません。
順序が意味を持つケースと、
意味を持たないケースがあります。
[[正準等価]]なものは同じようにレンダリングしなければなりません
[SRC[>>185]]。

[14] 
[DFN[[RUBYB[typograph[RUBY[的][てき]][RUBY[相互作用][そうごさよう]]][typographic interaction]]]]は、
[[grapheme base]]
に対する相対的な位置が既に他の
[[nonspacing mark]]
に占有されているような
[[nonspacing mark]]
の[[図形的応用]]であって判読不能な重ね打ちや[[グリフ]]の衝突を防ぐべく何らかの[[レンダリング]]上の調整
([[default stacking]] や [[side-by-side placement]] など)
が行われなければならないものをいいます。
[SRC[>>209 D106]]



-*-*-

[119] 
[[指針]]として、
同じ[[結合クラス]]の
[[nonspacing mark]]
は、
通常、
[[適用]]する[[書記素基底]]から図形的に外側に向かって配置していきます
([DFN[inside-out application]],
[DFN[default stacking behavior]])。
[SRC[>>115 P2, >>185]]
上側に置く[[結合文字]]は垂直に上方向へ、
下側に置く[[結合文字]]は垂直に下方向へと重ねていきます。
[SRC[>>142, >>115 P2]]

[EG[
[157] 
[[タイ文字]]にあっては、
[[子音文字]]に対して
[CODE[U+0E34]] - [CODE[U+0E37]] の[[母音]]を上に置き、
更に
[CODE[U+0E48]] - [CODE[U+0E4B]] の[[声調記号]]をその上に置きますので、
この順序で[[文字]]を並べます。
[SRC[>>142]]
]EG]


[120] 
[[指針]]として、
特定の
[[nonspacing mark]]
については、
垂直に並べる [[default stacking behavior]]
ではなく、
[[書記素基底]]の上下に横並びで、
[[言語]]依存の[[正書法]]規則に従い配置します
([DFN[side-by-side application]])。
[SRC[>>115 P3]]

[121] 
[[side-by-side application]]
における[[結合文字]]の視覚的なレンダリング順序は、
当該[[用字形]]における支配的な順序に依ります。
[SRC[>>115 P3, >>142]]
[[左横書き]]では左から右に並べます。
[SRC[>>142]]
[[ギリシャ文字]]では[[書記素基底]]の上に、
1つ目の[[結合文字]]を左側、
2つ目の[[結合文字]]を右側に置きます。
[[ヘブライ文字]]では逆側に置きます。
[SRC[>>115 P3]]

- [158] 
例えば[[ギリシャ文字]]にあって、
[[breathing mark]]
の
[CODE[U+0313]] [CODE(charname)@en[COMBINING COMMA ABOVE]],
[CODE[U+0314]] [CODE(charname)@en[COMBINING REVERSED COMMA ABOBE]]
は、
[[acute accent]], [[grave accent]]
と併用する時、
[[side-by-side application]]
します。
[[基底文字]]、 
[[breathing mark]]、
[[accent mark]]
の順に並べ、
[[基底文字]]の上に左が 
[[breathing mark]]、
右が
[[accent mark]]
と表示されます。
[SRC[>>142]]
- [122] 
[CODE[U+1ABB]] [CODE(charname)@en[COMBINING PARENTHESES ABOVE]],
[CODE[U+1ABC]] [CODE(charname)@en[COMBINING DOUBLE PARENTHESES ABOVE]],
[CODE[U+1ABD]] [CODE(charname)@en[COMBINING PARENTHESES BELOW]]
は [[side-by-side application]] します。
[SRC[>>115 P3]]
これらは[[ドイツ語]]の[[方言学]]で、
[[発音]]の[[修飾子]]の効果が弱められることを表します。
これらよりも前にある[[ダイアクリティカルマーク]]を囲むように配置します。
[SRC[>>164]]
-- [181] これも [[side-by-side application]]
の一種とされますが、その定義とは少し違う別種の配置のような...


[123] 
[[指針]]として、
伝統的な
[[typographic]]
な挙動により
[[nonspacing mark]]
の既定の配置を上書きする場合があります。
[SRC[>>115 P4]]

- [168] [[基底文字]]との関係で[[結合文字]]の[[字形]]が変化するケース: >>124, >>125
- [126] 
[[アラビア文字]]の[[母音記号]]の相対配置は
[[default stacking behavior]]
だけでは説明できず、
[[アラビア文字]] [[typography]]
の伝統的規則に依存します。
[SRC[>>115 P4]]
- [160] 
[[ヘブライ文字]]、
[[キリル文字]]でも特別な扱いが必要となります。
[SRC[>>142]]
- [187] 
現代[[越南語]]では、
[[声調記号]]の
[[acute accent]] や [[grave accent]]
は、
[[circumflex accent]] 
の上ではなく横に配置されることがあります。
[SRC[>>185]]

[136] 
[[指針]]として、
[DFN[[CODE[Soft_Dotted]]]]
[[特性][特性 (UCD)]]の[[文字]]に
[DFN[nonspacing mark above]]
([CODE[ccc]] = [DFN[[N[230]]]]
の[[結合文字]])
が[[適用]]されるとき、
[[基底文字]]に元々有る[[点]]は、
表示しません。
[SRC[>>115 P9]]

[137] [CODE[i]] や [CODE[j]] の類が該当します。
この上に[[ダイアクリティカルマーク]]が来る時、
[[点]]のかわりに[[ダイアクリティカルマーク]]を書きます。
[[リトアニア語]]のように[[点]]と[[ダイアクリティカルマーク]]の両方を書く[[言語]]では、
[CODE[U+0307]] [CODE(charname)@en[COMBINING DOT ABOVE]]
を使います
[SRC[>>115 P9]]。

[REFS[
- [138] [CODE[Soft_Dotted]] な文字の一覧
<https://chars.suikawiki.org/set/%24unicode%3ASoft_Dotted>
]REFS]

-*-*-

[127] 
[N[0]] で''ない''[[結合クラス]]の 
[[non-spacing mark]]
の順序を入れ替えても、
[[結合文字列]]の視覚的表示や解釈は変化しません
([DFN[nondistict order]])。
[SRC[>>115 P5]]
そのような場合は任意の順序で書くことが出来ます [SRC[>>142]]。 
実装は内部的に任意の順序に置き換えて処理できます [SRC[>>185]]。
[[正準再順序付けアルゴリズム]]はこの性質に関する[[正規化]]の処理です。
[[NFC]]
などの[[正規化]]を適用すると、
[[結合文字]]の順序が交換されることがありますが、
それは解釈に影響が出ない場合に限られます。

[128] 
[[combining grapheme joiner]]
を使うと
[[nondistinct order]]
であっても[[正準再順序付け]]を抑制できます。
[SRC[>>115 P5]]

-*-*-

[129] 
[[指針]]として、
[[enclosing mark]]
は、
[[関連付けられた書記素基底]]やそれとの間にある
[[enclosing mark]]
を囲むものとなります。
[SRC[>>115 P6]]

[130] 
[[囲み文字]]に
[[nonspacing mark]]
を付けて更に囲むような入れ子の構造も記述できます。

-*-*-

[182] 
[CODE[U+1DC0]] [CODE(charname)@en[COMBINING DOTTED GRAVE ACCENT]],
[CODE[U+1DC1]] [CODE(charname)@en[COMBINING DOTTED ACUTE ACCENT]]
は、
[[ギリシャ文字]]で使われ、
[[dialytika varia]]
と
[[dialytika oxia]]
の組み合わせの[[異体字]]です。
[CODE[U+0308]] [CODE(charname)@en[COMBINING DIAERESIS]],
[CODE[U+0300]] [CODE(charname)@en[COMBINING GRAVE ACCENT]],
[CODE[U+0301]] [CODE(charname)@en[COMBINING ACUTE ACCENT]]
と混じると通常の stacking rule 
では[RUBYB[結果が信頼できない][cannot be reliably formed]]ために別の文字として追加されたといいます。
[SRC[>>164]]

;; [183] 理由が「表現できない」ではなく「信用できない」であるところに[[闇]]を感じます...


* 二重ダイアクリティカルマーク

[170] 
[[二重ダイアクリティカルマーク]]の[[結合文字]]は、
2つの[[基底文字]]の上や下に表示されますが、
1つ目の[[基底文字]]の後に続く[[結合文字]]として使います。

[131] 
[[指針]]として、
[[二重ダイアクリティカルマーク]]な 
[[nonspacing mark]]
は、
[[書記素基底]]に[[適用]]しますが、
次の[[書記素基底]]も包むような[[グリフ]]として[[レンダリング]]されることが意図されています。
[SRC[>>115 P7]]

- [132] [CODE[U+0360]] [CODE(charname)@en[COMBINING DOUBLE TILDE]]
が該当します。
[SRC[>>115 P7]]

[133] 
[[指針]]として、
[[二重ダイアクリティカルマーク]]な 
[[nonspacing mark]]
は、
[[書記素基底]]の上下に積んだ通常の
[[nonspacing mark]]
の最外側に「浮動」します。
[SRC[>>115 P8, >>164]]
(surrounding diacritics は除きます。 [SRC[>>164]])

[135] 
ただ
[[enclosing mark]]
と[[二重ダイアクリティカルマーク]]との図形的な相互作用は十分に定義されておらず、
多くの[[フォント]]や[[レンダリング]]処理はこれを適切に扱えないかもしれません。
従って両者を同じ[[書記素クラスター]]に含めることは[RUBYB[[[推奨]]されません][not recommended]]。
[SRC[>>115 P8]]

;;
[134] 
[[二重ダイアクリティカルマーク]]な 
[[nonspacing mark]]
の[[結合クラス]]は非常に高く設定されているので、
[[正準順序]]では[[結合文字列]]の最後の方に現れます。
[SRC[>>115 P8, >>164]]


[171] 
[CODE(charname)@en[COMBINING GRAPHEME JOINER]]
を使うと[[正準再順序付け]]が抑制されます
[SRC[>>164]]。
それ以前の[[結合文字]]とそれ以後の[[結合文字]]が区別されることになります。
これを使うと、通常なら[[二重ダイアクリティカルマーク]]より内側に表示される[[結合文字]]を、
[[二重ダイアクリティカルマーク]]より外側に表示するよう指定できます。
[SEE[ [CODE(charname)@en[COMBINING GRAPHEME JOINER]] ]]

[178] 
[[縦書き]]時の扱いは特に規定されておらず、注意が必要となります。
[SEE[ [[縦書き字形]]、[[組み合わせて使う文字]] ]]

-*-*-

[172] 
3文字以上に対する[[ダイアクリティカルマーク]]は、
[[Unicode]]
では扱えないとされています。
[[マーク付け]]によって記述するべきだとされています。
[SRC[>>164]]

[173] 
限られた状況では [[combining half mark]]
が活用できることもあるものの、
[[平文]]で満足できる[[レンダリング]]は成せないといいます。
[SRC[>>164]]

[174] 
こうしたものを用いる[[応用]]の実装のためには、
[[Unicode]]
で[[結合文字]]として記述できる[[二重ダイアクリティカルマーク]]だけでなく、
[[マーク付け言語]]により記述される三重以上の[[ダイアクリティカルマーク]]をも扱える仕組みが
(共通であれ別々であれ)
必要となってきます。

[260] 
なお、後続の[[文字]] (3文字以上の場合も含みます。) に作用する[[文字]]として、
[CODE[Prepended_Concatenation_Mark]]
たる[[文字]]があります。


* 結合文字の前後連結

[SEE[ [[上下左右線の文字]] ]]

-*-*-

[184] 
[[二重ダイアクリティカルマーク]]を分割した[[結合文字]]である
[[combining half marks]]
もあります。
これらは[[互換性文字]]で、
[[二重ダイアクリティカルマーク]]が[RUBYB[好ましい][preferred]]とされます。
[SRC[>>164]]


* レンダリング




[148] 任意の[[結合文字]]は任意の[[基底文字]]に[[適用]]できます (>>85) が、
実装はすべての組合せを等しく良く対応する必要はありません。
[SRC[>>85]]

[189] 
[[基底文字]] + [[結合文字]]の組み合わせという仕組みから、
[[文字]]の図形も合成で表示できそうな気がしますが、
現実には組み合わせごとに調整しなければ実用できる品質にはなりません。

[EG[
[243] 
例えば「A」と「a」の上部にアクセント記号を付け加えることを考えると、
汎用アクセント字形を単純に重ね合わせるだけでは美しくならないことがわかります。

]EG]

[242] 
大抵の[[フォント]]は、
一般的に用いられる組み合わせの[[グリフ]]を予め用意しています。
これが[[結合文字列]]の表示方法の1つです [SRC[>>185]]。
[[グリフ]]全体を別途用意しなくても、
[[基底文字]]のどの位置に[[結合文字]]を配置するかの情報があれば足りることもあります
[SRC[>>185]]。
こうした手法の実現には
[[フォント]]の [[ligature]] や [[kerning]] のような技術が使われることがあります 
[SRC[>>185]]。

[190] 
ですが、任意の組み合わせが許されている以上、
あらゆる組み合わせを想定した[[フォント]]を用意することは不可能です。
用意された組み合わせは[[フォント]]によっても異なります。
従って[[文字のレンダリング]]の実装は、
用意されていない組み合わせも何らかの形で扱える仕組みを持っていなければなりません
(>>244)。





-*-*-

[194] 
[[基底文字]]と[[結合文字]]の関係は、
[[書字方向]]とは関係しません。
[[結合文字]]は[[表示上][表示順]]の左側の文字に適用されるのでは''なく''、
[[論理順]]の前の文字に適用されるのです。
従って[[右横書き]]では左側の文字ではなく右側の文字に適用されることになります 
[SRC[>>185]]。

[152] 
[[インド系文字]]の[[母音記号]]の[[結合文字]]には、
[[子音文字]]や[[子音クラスター]]の左側に[[レンダリング]]されるものもあります。
[[左横書き]]で左から右に[[文字]]を並べ、
[[基底文字]]の後に[[結合文字]]を置く順序であっても、
[[基底文字]]が右、[[結合文字]]が左とそこだけ逆転します。
これは表示順ではなく発音順を取ったもので、
[[Unicode]] 以前の[[文字コード]] [[ISCII]]
の方式に倣ったものとされます。
[SRC[>>142]]

-*-*-


[202] 
[[結合文字]]が組み合わさることで、
[[結合文字列]]の幅と高さは[[基底文字]]の幅と高さから変化させることがあります。
[[文字]]や[[行]]の配置、
[[字間]]、[[行間]]の調整においては、
[[結合文字列]]の幅と高さを使って適切にレイアウトする必要が出てきます。

[203] 
通常では使わないような異常な(1つ[[以上]]の)[[結合文字]]の利用によって、
上下左右の[[文字]]その他の構造に重ねて表示させる悪戯があります。
悪戯で済めば良いですが、
[[フィッシング]]などに悪用できないとも限りません。
[SEE[ [[文字のセキュリティー]] ]]


** 非前進マーク

[32] 
[[非前進マーク]]の[RUBYB[[[表現]]][presentation]]上の位置は[[基底文字]]に依存します。
通常はそれ自体に関して [[visual baseline]] に対して間隔を消費しません。
[SRC[>>30]]

[33] 
ただし、[[非前進マーク]]の大きさによって[[基底文字]]の表示位置が影響されることはあります。
[SRC[>>30]]

[EG[
[34] 例えば [CODE[U+20DD]] [CODE(charname)@en[COMBINING ENCLOSING CIRCLE]]
を使うと (それ自体が独立して表示幅を取ることはありませんが)
その前の[[基底文字]]の周りに円を描画して、かつ前後の[[文字]]と表示が重ならないよう、
[[基底文字]]の表示位置が通常と変化することになります。
]EG]

-[167] 
[CODE[U+0301]] [CODE(charname)@en[COMBINING ACUTE ACCENT]]
のように、
[[ラテン文字]]としての[[字形]]と[[ギリシャ文字]]としての[[字形]]が異なるものもあります
[SRC[>>164]]。
つまり[[基底文字]]によって[[字形]]が変化します。
なお[[ラテン文字]]であっても[[ポーランド語]]と[[フランス語]]とでは[[字形]]
(角度) が違います
[SRC[>>164]]。
- [124] [CODE[g]] の下方と [[combining comma below]]
が衝突してしまうので、
かわりに 
[[inverted comma above]]
として伝統的に[[レンダリング]]されてきました。
[SRC[>>115 P4, >>164]]
- [125] [CODE[d]] の上方と
[[combining caron]]
が衝突してしまうので、
かわりに
[[apostrophe]] 
として伝統的に[[レンダリング]]されてきました。
[SRC[>>115 P4, >>164]]


[195] 
[[字間]]の調整は、
[[基底文字]]と[[結合文字]]の間で行うべきではありません
[SRC[>>185]]。
原則[[書記素クラスター]]の間で行うべきものでしょう
(が、[[二重ダイアクリティカルマーク]]など注意が必要なケースがあります)。

** 囲み結合マーク

[149] 
[[combining enclosing mark]]
は、
[RUBYB[[[記号]]][symbol]]を表現する[[文字]]に使うのに[RUBYB[留めるのがいいです][best to limit]]。
[SRC[>>142]]

[155] 
その理由は、
[[文字特性]]の不一致が起こることでの驚きを抑えられることとされています。
[SRC[>>142]]

[EG[
[236] 
例えば
[CODE[U+0021]] [CODE(charname)@en[EXCLAMATION MARK]]
と
[CODE[U+20E4]] [CODE(charname)@en[COMBINING ENCLOSING UPWARD POINTING TRIANGLE]]
で[[警告マーク]]を表せますが、
[CODE[!]]
が[[句読点]]であるが故に[[改行]]について通常の[[記号]]とは異なる挙動を示します。

[237] 
故に
[CODE[U+26A0]] [CODE(charname)@en[WARNING SIGN]]
は別に単独の[[記号]]として用意されており、
[[正規化]]による[[分解]]もされません。
[SRC[>>153]]

;;
[238] 
その他一般に合成済の[[囲み文字]]は[[互換分解]]はあっても[[正準分解]]はされません。
これは[[特性][文字特性]]の不一致が理由とされます
[SRC[>>164]]。
]EG]

;; [239] 
その種の特性は本来[[書記素クラスター]]に対して適切に設定されるべきだったのでしょう。
これは仕様の欠陥と言えますが、[[後方互換性]]のため今更修正するわけにもいかないのでしょう。



[154] [CODE[Vertical_Orientation]] 
は[[書記素クラスター]]に対して定義され、
[CODE[Me]]
の場合だけ[[書記素基底]]のものではなく固定値が割り当てられます。
[SEE[ [CODE[Vertical_Orientation]] ]]

;; [240] 
このような扱いなのは [CODE[Vertical_Orientation]] が比較的新しい特性であることと関係するのでしょう。


[HISTORY[
[140] 
古い実装は、
[[Indic consonant conjunct]]
や、
[[combining grapheme joiner]]
で連結された[[書記素クラスター]]群全体に対して
[[enclosing combing mark]]
で囲んでいました。
そうした手法には数々の問題があるので、
[RUBYB[推奨されません][not recommended]]。
[SRC[>>115]]

[201] 
なぜか非推奨であって禁止はされていないようです。
[[相互運用性]]は低そうです。


[200] 
非推奨とするだけで、
代替手段は用意されていないようです。
]HISTORY]

** 前進マーク

[41] 
[[前進マーク]]は一般に[[基底文字]]とそう違わない挙動を示します。
[SRC[>>39]]

[42] 
しかし [CODE[U+0BCA]] [CODE(charname)@en[TAMIL VOWEL SIGN O]]
のように、
([[囲みマーク]]でないにも関わらず)
[[基底文字]]の両側に[[レンダリング]]されるものもあります。
[SRC[>>39]]

** フォント情報に基づく結合文字列のレンダリング

[216] [CODE[GSUB]], [CODE[cmap]]

[217] [CITE@ja-jp[OpenType development (LEGACY INFORMATION) - Typography | Microsoft Docs]], [[nihar]], [TIME[2022-08-27T06:51:43.000Z]] <https://docs.microsoft.com/ja-jp/typography/develop/otdevinfo#suggested-glyphs-for-complex-scripts>

[220] 
[[OpenType]]
における[[グリフ級]] [DFN[[N[3]]]]
は、
[DFN[[RUBYB[マークグリフ][mark glyph]]]]を表します。

[221] 
[[グリフ]]における[[マークグリフ]]は[[文字]]における[[結合文字]] ([[結合マーク]])
に近い概念です。
[[マークグリフ]]は単体で使うことが想定されず、
[[基底グリフ]]または[[合字グリフ]]と組み合わせて使います。

[222] 
[[マークグリフ]]を[[基底グリフ]]や[[合字グリフ]]と組み合わせるには、
[[基底グリフ]]や[[合字グリフ]]の表す[[グリフ]]の形状や、
他の[[マークグリフ]]の形状が関係してきます。
[[フォント]]の設計者は関係[[グリフ]]の相互関係を記述しなければなりません。
[[OpenType]] [[フォント]]ではその情報を
[CODE[GPOS]] [[表][OpenType表]]に格納できます。
[SEE[ [[グリフ位置決定]] ]]

[246] 
[[マークグリフ]]であるかどうかは[[フォント]]の [CODE[GDEF]] [[表][OpenType表]]で指定でき、
[[結合文字]]の[[グリフ]]を[[マークグリフ]]でなく[[基底グリフ]]とすることも可能です。
これがどのような意味を持つのか (同じ[[フォント]]の [CODE[GPOS]] 等からの参照以外に影響があるのか)
は十分明らかではありません。

[247] 
例えば[[結合文字]]の[[グリフ]]を[[基底グリフ]]とすることで、
[[グリフ]]の表示や[[文字列の選択]]の挙動を[[基底文字]]であるかのように変更できるでしょうか。
少なくても [[Windows]] の [[Chrome]] や [[Firefox]] では、
[[文字列の選択]]の単位や ([CODE[kern]] がないときの) [[結合文字]]の[[グリフ]]の描画位置について、
[CODE[GDEF]] の指定は効果がないように見えます。
[TIME[2023-11-10T13:28:10.400Z]]

[255] 
>>247
[CODE[GDEF]] により[[マークグリフ]]として指定されると、
[[横書き]]なら横方向、
[[縦書き]]なら縦方向の[[現在位置]]の進行が0とみなされます。
後続のグリフの描画位置に影響するのはもちろん、
[[文字列の選択]]の範囲にも影響します。

[257] 
>>247 [CODE[GDEF]] で指定がないときの既定値が違うのか、
[CODE[U+3099]] だと進行しない、
[CODE[U+16FF1]] だと進行するのが何も指定しないときの挙動で、
[CODE[GDEF]] で挙動を切り替えられます。




-*-*-

[249] 
[[Windows]] の [[Chrome]] や [[Firefox]] では、
専用[[グリフ]]の有無に関わらず、[[結合列]] 
(なのか[[書記素クラスター]]なのかその他なのか、詳細は要検証)
は[[文字列の選択]]において1単位として扱われます。

[250] 
[[Windows]] の [[Chrome]] や [[Firefox]] では、
[CODE[GPOS]]
があれば、
[[結合文字]]の[[グリフ]]の配置もそれに従うようになります。
それがない場合には、
[[結合文字]]の[[グリフ]]を ([[結合文字]]の [[X軸]]の絶対値は無視して)
[[基底文字]]上の左右中央に揃えて配置します。
[TIME[2023-11-10T13:40:49.00Z]]

[251] 
[[縦書き]]のとき、 [[Windows]] の [[Chrome]] も [[Firefox]] も、
[CODE[GPOS]]
があれば[[結合文字]]を下隣に、高さ方向の[[現在位置]]を移動させずに配置します。
[CODE[GPOS]]
がなければ[[結合文字]]を右上に、高さ方向の[[現在位置]]を移動させずに配置します。


;; [253] 
なぜ右隣でも上隣でもなく右上なのか謎です。
本来ならフォントに情報がないときに最も好ましい挙動は、
[[書記素クラスター]]だけ[[縦中横]]で[[レンダリング]]することで[[横書き]]時と同じ表示にすることでしょうか。
[[濁点]]や [[U+16FF0]] が典型例でしょうが、
下に置くより右に置く方が遥かにマシな表示になるはずです。

[252] 
[[縦書き]]のときの[[文字列の選択]]の挙動は、 [[Firefox]] は[[基底文字]]部分を選択するまあ妥当な挙動ですが、
[[Windows]] はそれより大きく、しかし[[結合文字]]部分を含めているわけでもない謎の範囲を選択するように見える謎挙動です。

[256] 
[[現在位置]]を移動しないので次の[[グリフ]]に重なる、という部分は[[マークグリフ]]にしないことで回避できます
(>>255)。
[[基底グリフ]]でなくても[[マークグリフ]]でも可で、 [CODE[GDEF]]
が存在しないことでも回避可能です。



[254] 
[[グリフ]]間の位置関係は [CODE[kern]] / [CODE[vkrn]] で調整できそうなものですが、
[[Firefox]] でも [[Chrome]] でも効果があるようには見えません。

-*-*-

[261] [[Windows]] の [[Chrome]] で試してみました。 [TIME[2025-01-24T09:58:16.600Z]]

- [262] [CODE[GDEF]] がなければ、[[結合文字]]の[[グリフ]]は[F[前進幅]]に関わらず[[前進幅]]
[N[0]] とみなされます。つまり前の[[グリフ]]の続きで配置されますが、
[F[前進幅]]を加算せずに次の[[グリフ]]の処理になります。
[CODE[GPOS]] [CODE[mark]] があっても無視されます。
- [263] [CODE[GDEF]] があって無指定なら、[[結合文字]]の[[グリフ]]であっても[[基底グリフ]]とみなされるようで、
[[グリフ]]の[F[前進幅]]が無視されません。つまり前の[[グリフ]]の続きで配置され、
[F[前進幅]]を加算してから次の[[グリフ]]の処理になります。
[CODE[GPOS]] [CODE[mark]] があっても無視されます。
-- [267] 
ところが [CODE[GDEF]] に指定がないのに[[結合文字]]の[[グリフ]]に
[CODE[GPOS]] [CODE[mark]]
が指定され、
しかも[F[前進幅]]が加算されることがあります。何に依って挙動が変わっているのか不明です。
- [264] [CODE[GDEF]] で[[結合グリフ]]と指定された[[結合文字]]の[[グリフ]]は、
[F[前進幅]]に関わらず[[前進幅]] [N[0]] とみなされます。 >>262 と同じ結果になります。
[CODE[GPOS]] [CODE[mark]] の指定対象になっていると、
[[結合グリフ]]は [CODE[mark]] によって[[基底グリフ]]との位置が決定されます。
- [265] 
[CODE[mark]] に [F[[CODE[lookupType]]]] [N[4]] (MarkToBase)
を指定すれば適用されますが、
[F[[CODE[lookupType]]]] [N[2]] (pair)
を指定しても適用されません。
- [268] 
しかし
[F[[CODE[lookupType]]]] [N[8]] (chained contexts) + [F[[CODE[lookupType]]]] [N[1]] (single)
を使えば[[基底グリフ]]ごと[F[配置]]や[F[前進]]を変更できます。
[[基底グリフ]]上の位置に連動して MarkToBase の位置がずれるので、
[[結合グリフ]]も同期して移動することになります。
- [266] 
[CODE[mark]] でなく [CODE[ccmp]] で MarkToBase を指定しても同じことになります。

[272] 
[[結合グリフ]]が複数ある場合、後続のものは適用可能な [CODE[mkmk]] MarkToMark 
があればそれを使い、なければ [CODE[mark]] MarkToBase を使うようです。

[273] 
同じ[[結合グリフ]]が複数あって [CODE[mkmk]] で位置が指定されていないと、
同じ位置に同じ[[グリフ]]が描画されるため1つしかないときと同じように見えます。


[274] 
[[基底グリフ]]の[[左]]に[[レンダリング]]されるべき [CC[U+302E]] 
は何か特別な扱いになるらしく、
[CODE[mark]]
がないとき、
[[Windows]] の [[Chrome]] では、
[[基底グリフ]]、[[結合グリフ]]、点線円グリフが左から順に並べられた状態になります。
[[基底文字]]がないときは[[結合グリフ]]、点線円グリフの順に並べられた状態になります。

[275] 
[CODE[mark]] があっても何か特別な扱いはされたままらしく、
[[基底グリフ]]と[[結合グリフ]]の[[原点]]を揃えていても一般の文字だと >>274
と挙動が変わりません。
[CC[U+0020]], [CC[U+00A0]] 
は[[結合グリフ]]、空白、点線円グリフの順に並びます。
[CC[U+25CC]] は[[結合グリフ]] + 点線円グリフ、空白、点線円グリフの順に並びます 
(1つ目が [CC[U+25CC]] 用のグリフで、2つ目が勝手に補われた点線円グリフでしょうか)。
左にある特殊な[[結合文字]]故の特殊処理なのか、
それとも[[ハングル]]絡み故の特殊処理なのでしょうか。



** 合成済グリフがない場合のレンダリング

[244] 
[[基底文字]]と[[結合文字]]の組み合わせは任意のものがあり得ますから、
従って[[文字のレンダリング]]の実装は、
[[フォント]]に用意されていない組み合わせも何らかの形で扱える仕組みを持っていなければなりません。


[17] [[Unicode]] [[符号表]]の[[代表画像]]には点線の円が示されています。
[SRC[>>9, >>164]]
直前の[[基底文字]]と図形的結合して表示する場合には、[[基底文字]]を点線円部分に示すことが想定されています。 [SRC[>>9]]

[159] 
[[default stacking behavior]] 
は素朴な方法で[[基底文字]]と[[結合文字]]を重ねて表示することで
(品質はともかく)
一応実現可能です。
しかしその他の処理が必要となってくると、
表示位置や表示サイズを細かく制御する必要が生じてきます。

[188] 
未対応の組み合わせの実装戦略
[DFN[Simple Overlap]]
は、
[[基底文字]]に重なる既定の固定の位置に[[結合文字]]を描画するもので、
[[大文字]]に合わせて高い位置に置くと[[小文字]]との間に空間が生じたりします
[SRC[>>185]]。

;; [193] 
[[nonspacing mark]]
は[[零幅]]の文字で、[[現在位置]]より左側に描画する、
という考え方が採られてきました。
この戦略は[[左横書き]]の場合にはそのままでうまくいきますが、
他に[[右横書き]]や[[上縦書き]]や[[下縦書き]]の場合も想定する必要があります。




[16] [[結合文字]]が[[孤立結合文字]]である場合や、[RUBYB[図形的結合]@en[graphical combination]]を行えない場合には、
図形的結合なしに、[[基底文字]]であるかのように表示して構いません。 [SRC[>>9]]
未対応の組み合わせの実装戦略
[DFN[Show Hidden]]
は、
[[基底文字]]と[[結合文字]]をそれぞれ独立した単位として配置し、
[[結合文字]]には 
[[Unicode]] 
[[符号表]]のように点線円を表示するといったものです
[SRC[>>185]]。

;; [191] 別々に表示されるとしても単独の[[書記素クラスター]]として、
1文字表示のときと同じように[[カーソル]]移動するべきかもしれません。
[[禁則処理]]にも注意が必要となります。
また[[左横書き]]以外に[[右横書き]]や[[上縦書き]]や[[下縦書き]]の場合も想定する必要があります。


;;
[205] 
点線の円は
[CODE[U+25CC]]
[CODE(charname)@en[DOTTED CIRCLE]]
([CODE[◌]])
として用意されています。
これを[[基底文字]]とすることで、
[[符号表]]の字形を再現できます
(少なくても理屈の上では)。



[SEE[ IDS との関係は [[IDC]] ]]

[248] 
条件が複雑なので正確な挙動かどうかわかりませんが、
[[Windows]] の [[Chrome]] は[[基底文字]]と[[結合文字]]が同じ[[フォント]]内にないと次の[[フォント候補を探し][フォントの選択]]、
[[Windows]] の [[Firefox]] は[[基底文字]]と[[結合文字]]が別の[[フォント]]にあっても同じ位置に重ねるように見えます。
[TIME[2023-11-10T13:35:25.100Z]]
([CODE[GPOS]] との絡みは要検証, [[基底文字]]側フォントの [CODE[GPOS]]
の有無は影響しなそう。)

[258] 
[[Windows]] の [[Chrome]] だと[[結合文字]]に明示的に対応した[[グリフ]]がないとき ([CODE[GPOS]] がないとき??)
に[[結合文字]]の通常の配置に合わせて(?)[[基底文字]]の上方にずらして[[結合文字]]用[[グリフ]]を置くような未対応フォント向け制御も反映されているようです。


** 欠陥結合文字列のレンダリング

[192] 
[[欠陥結合文字列]]は、
[CODE[U+00A0]] [CODE(charname)@en[NO-BREAK SPACE]]
が[[基底文字]]であるかのように[[レンダリング]]する[RUBYB[べき][should]]です。
[SRC[>>185]]


[196] 
とされますが、
実際には必ずしもそう実装されてはいないようです。
[[零幅]]で、
直前の余白や他の構造に被さって表示されたりします。


[197] 
[[欠陥結合文字列]]のうち、
[CODE(charname)@en[ZWJ]],
[CODE(charname)@en[ZWNJ]]
のみから構成されるものは、
[[零幅]]で[[レンダリング]]されるべきものであるはずです。
また[[カーソル]]移動なども直後の[[基底文字]]と一体的に扱うべきかと思われます。

[245] >>16 も参照。


* 応用と結合文字

[223] 
[[Unicode文字列]]としては[[基底文字]]とその後の0個[[以上]]の[[結合文字]]は連続していなければなりません。
しかし[[応用]]によっては[[ソースコード]]上の[[文字列]]と表示される[[文字列]]とが違っていて、
[[基底文字]]と[[結合文字]]の関係性に変化が生じることがあります (例えば >>96)。
また、[[文字列]]とは別に与えられた[[フォント]]指定等で[[基底文字]]と[[結合文字]]の関係性に変化が加えられることがあります。

[218] 
[[OpenType]] 的には[[フォント]]が違うと別の[[連なり]]に属するということになっています。
[SEE[ [[連なり]] ]]
もし[[基底文字]]と[[結合文字]]で (または[[結合文字]]と別の[[結合文字]]で)
異なる[[フォント]]が指定されるとすると、
その両者は本来想定される「合成」状態で表示し得ないことになります。

[226] [[Unicode用字系特性値]]


** データ形式と結合文字

[95] 
[[テキスト]]系の[[データ形式]] ([[マーク付け言語]])
と[[結合文字]]の関係は、
[[テキストファイル]]としての表示や編集を考慮する時、
やや複雑になります。

[EG[
[96] 
例えば [[HTML]] の[[タグ]]の直後に[[結合文字]]が来ると、
[[テキストファイル]]として見た時[[タグ]]の最後の [CODE[>]] と[[結合文字]]が合成されて表示されてしまいます。
]EG]

[98] 
[[文字参照]]や[[エスケープ]]のような機能を使うと、
[[結合文字]]を直接入力しづらいときでも、
代替表現で容易に指定できます。


[97] 
[[完全正規化済]]はこうした不思議な挙動を避けることを求めたものでしたが、
普及しませんでした。

** CSS と結合文字

[94] 
[[CSS]] の[[結合文字]]の扱いは[[仕様書]]上は必ずしも明らかではありません。
例えば[[基底文字]]と[[結合文字]]が連続する別の[[要素]]に属する時でも合成されて表示されるべきかどうか、
両方の[[要素]]で[[特性]] (例えば [CODE['[[color]]']]) が違うときどう表示されるべきか、
明確ではありません。

[93] 
[CODE[::first-letter]]
は最初の[[文字]]の後に[[結合文字]]があれば、
それも含みます。
[[CSS2]]
仕様書には[[結合文字]]だけ[[子要素]]に入っている場合であっても、
そこまで含まれるという実例が示されていました。
[[CSS2]]
の改訂である
[CITE[[[Selectors 3]]]]、
その改訂である
[CITE[[[CSS Pseudo-Elements Module Level 4]]]]
ではなぜかその実例はなくなっています。
[SEE[ [[::first-letter]] ]]

[90] [CITE[html - Highlighting Combining Characters - Stack Overflow]], [TIME[2020-12-06T02:34:51.000Z]] <https://stackoverflow.com/questions/26407896/highlighting-combining-characters>

[91] [[書字方向]]は[[結合文字]]処理などを経た [[grapheme cluster]]
を対象に挙動が定義されています。
[SEE[ [[CSS Writing Modes]] ]]

* 正規化

[SEE[ [[正準等価性]] ]]

* セキュリティー

[SEE[ [[文字のセキュリティー]] ]]

* 関連

[68] 前置式の [[subtending mark]] もあります。

[199] [[IDS]] との相互作用は謎です。
[SEE[ [[IDS]] ]]

[SEE[ [[文字のようなもの]] ]]


* 特殊な利用例



[27] [CITE@ja[Xユーザーの風間さん: 「万博きた̷̡̤͕͖͓͉̯̪̅͊!̴̨̪͕̜̝̙̜̫̍̐̐͘ 今日で3581̵̡̫̞̗͖̱͍͔̿͂̎͆͐日め! 最̶̢̠͕͎̱͍͌高̷̡̢̠͚̮̳͂̓̕のお̴̨̙̲̗̗̘͐͂祭̵̡̨̪̗̦̞̟̔̓̏͂̕り̸̢̢̞͉̗͔͓̔̎͑̕だ〜! 人影はないけど、きょ̶̢͙̺̮̝̯̱̳̽̎̿̍͐̕う̵͎͓̠͚̦̼̽̅͐̔̚も̴̡̢̢͔̤̝͌̿̒͝回るぞ〜̵̨̥̝͓̙͚͍̾̋̋͆! #大̴̡̛̥阪̵̢̛̼万̴̡̛̦博̶̡̛͎2025 #大̴̡̛̥阪̵̢̛̼万̴̡̛̦博 https://t.co/SCHRR4PQWz」 / X]], [TIME[午後0:14 · 2025年10月14日][2025-10-14T03:14:37.000Z]], [TIME[2025-10-16T02:30:02.000Z]] <https://x.com/kazama_mm/status/1977936051152040176>



* 歴史

[35] 
[[Unicode]] 以前には色々な[[文字合成]]技術がありました。
[SEE[ [[文字合成]] ]]

** ISO/IEC 10646


[107] 
[[ISO/IEC 10646]] は[[文字集合]]として [[Unicode]]
と同じであるだけでなく[[結合文字]]の扱いも一致しています。
ただし
[[Unicode]]
と
[[ISO/IEC 10646]]
とでは用語法に若干の違いが見られます。


[2]
>
:結合文字 (combining character):
この規格群で規定する符号化文字集合の識別された部分集合の構成単位であって、先行する非結合文字 (以下、基底文字という。)
と組み合わせることを意図したもの、又は基底文字の後に結合文字の列が続いた形のものと組み合わせることを意図したもの (4.14 参照)。
([[JIS X 0221]]‐1:2001 4.12)

[1] 2002-11-03 (日) 15:52 ''[[名無しさん]]'': ''非''結合文字は''被''結合文字の [[typo]] じゃないかと一瞬思いますが、[[規格]]を良く読むとこれで正しいことが分かります。


[28] 

>
:合成列 (composite sequence):
[[基底文字]]とそれに続く一つ以上の[[結合文字]]からなる[[図形文字]]の列 (4.11 参照)。
> 備考 1. 合成列からなる[[図形記号]]は、通常、
その合成列を構成する各[[文字]]の図形記号の組合せからなる。
> 2. 合成列は、文字とはみなさない。したがって、
この規格群の[[レパートリ]]の構成単位ではない。
([[JIS X 0221]]‐1:2001 4.14)

[108] [[合成列]]は[[結合文字列]]と同じようなものですが、
[[基底文字]]が必須で、
[CODE[ZWJ]]
や
[CODE[ZWNJ]]
は含まれません。

-*-*-

[104] 
[[ISO/IEC 2022]]
にも合成に関する規定があります。
合成手法として、
[[重ね打ち式文字合成]]、
[[Unicode]] 式[[結合文字]]、
[CODE(charname)@en[GCC]]
が示されています。



[4]
>
'''6.3.3 図形文字の結合''' 特に指定されない限り、[[図形文字]]は、
[[結合文字]]としてはならない。すなわち、
隣接する[[図形文字]]と組み合わせようとしてはならない。
> [[図形文字集合]]によっては、複数の[[図形文字]]を一つの[[図形記号]]として[[可視化]]することによって、
追加の[[図形記号]] (例えば、[[アクセント付き文字]]) 
を[[図形表現]]することを許しているものもある。この[[規格]]では、
二つの結合方法があることを認識している。
> a) [[基底文字]]の[[図形文字]]は、[[制御文字]]の
[CODE(charname)[[[BACKSPACE]]]] ([CODE(jcharname)[[[後退]]]]) 又は
[CODE(charname)[[[CARRIAGE RETURN]]]] ([CODE(jcharname)[[[復帰]]]])
を使用して、組み合わせてよい。
> b) [[結合文字]]として[[指定]]されている[[図形文字]]は、
[[基底文字]]の[[図形文字]]と組み合わせてもよい。
> [[ISO 2375]] に従って、[[図形文字集合]]の登録を行おうとする申請者は、
[[集合]]中の[[結合文字]]を明らかにしておくことが期待される。
> 参考1. 登録では、これらの要件の詳細を求められないので、
[[文字集合]]を規定する[[規格]]は、[[結合文字]]がある場合、
それ自身で、これを指定しその用法を示しておくのがよい。
> 2. [[ISO/IEC 646]] の[[図形文字]]では、
[[アクセント付き文字]]を[[表現]]するのに、 a)
の方法が認められている。
> 3. [[JIS X 0211]] では、第3の方法として、[[文字]]自身の仕様に関係なく、
[CODE(charname)[[[GRAPHIC CHARACTER COMBINATION]]]] 
([CODE(charname)[[[GCC]]]]) の[[制御機能]]を使った[[図形文字]]の[[結合]]を規定している。
[SRC[[[JIS X 0202]]:1998]]




[8] 
>
:結合文字 (combining character):
[[符号化文字集合]]の識別された部分集合の構成単位であって、先行する非結合文字
(以下、[[基底文字]]という。)
と組み合わせることを意図したもの、又は基底文字の後に結合文字の列が続いた形のものと組み合わせることを意図したもの。
([[JIS X 0202]]:1998 4.8)


[105] 
[[ISO/IEC 2022]]
の体系で使われる
[[ISO-IR]]
に登録された[[図形文字集合]]では実はなぜかここに挙げられていない[[非spacing文字]]
(前置アクセント型) 
方式の文字合成が一番よく使われているのではないかと思われます。

[106] 
[[Unicode]]
型の[[結合文字]]を使った
[[ISO-IR]]
に登録された[[図形文字集合]]はどれだけあるのでしょうか。
[[JIS X 0213:2000]]
と
[[JIS X 0213:2004]]
が思い浮かびますが、
他にもあるのでしょうか。

-*-*-

[3] 10646 での結合文字の使い方は、 24.
に規定があります。結合文字の一覧は附属書 B
にあります。結合文字が使えるかどうかは[[実装水準]]と関係します。

- 結合文字は、[[基底文字]]の後でなければなりません。
(24.1)
- 結合文字自体を一つの[[結合列]]としたい時は、
[[間隔]]を基底文字とします。 (24.1)
-- インド系用字系の [[matra]] (母音記号)
は特殊で、周囲の複数の文字に依存するので、
間隔と結合させるのは望ましくありません。 (24.1 備考)
- 一つの基底文字に結合できる結合文字の数は 10646 
では規定しません。 (24.3)
- 結合文字同士が表示に影響する場合
(例えば [CODE(char)[[[COMBINING MACRON]]]]
と [CODE(char)[[[COMBINING DIAERESIS]]]])
は、だんだん外側に
(MACRON より DIAERESIS を上に) 配置していきます。
- 縦方向ではなく横方向に並べたり、
隣接する結合文字と合字を作る結合文字もある。
横方向に進むときは、[[書字方向]]に従う。
- 結合文字同士が影響を与えない場合
(例えば上につくものと下につくもの) は、
逆の順序の場合と同じに見えてもよい。


[147] 
当初の
[[ISO/IEC 10646]]
は、
[[実装水準]]を3つに区別していました。
その違いは主に[[結合文字]]の利用の可否でした。
[SEE[ [[ISO/IEC 10646]] ]]
現在はこの区分は廃止されました。実情にまったく即していなかったためでしょう。


** JIS X 0208 と [CODE(charname)@en[LARGE CIRCLE]]

[SEE[ [CODE(charname)@en[LARGE CIRCLE]] ]]

** JIS X 0213

[SEE[ [[JIS X 0213の結合文字]] ]]

** JIS X 4051

[SEE[ [[JIS X 0213の結合文字]] ]]

**

[5] [CITE@en[I'm not a Klingon (<span style="font-family:pIqaD,code2000"> </span>) : Most combining characters in a Unicode glyph/character/whatever]]
([TIME[2010-03-27 10:31:57 +09:00]] 版)
<http://blogs.msdn.com/shawnste/archive/2010/01/25/most-combining-characters-in-a-unicode-glyph-character-whatever.aspx>

[6] [CITE@en[Web Applications 1.0 r6611     Allow combining characters wherever, per Mark Davis.]]
( ([TIME[2011-10-02 16:17:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=6610&to=6611>

[7] [CITE@en[Bug 13502 – Text run starting with composing character should be valid]]
( ([TIME[2013-11-25 16:50:57 +09:00]] 版))
<https://www.w3.org/Bugs/Public/show_bug.cgi?id=13502>

[25] 合成用の「☆」や「★」がほしい。[[合成用丸]]があるんだしw



[50] [CITE@ja[た͜͜͏̘̣͔͙͎͎̘̜̫̗͍͚͓͜͜͏̘̣͔͙͎͎す͜͜͏̘̣͔͙͎͎ơ̟̤̖̗͖͇̍͋̀͆̓́͞͡け̜ͪ̅̍̅͂͊てとは (タスケテとは) '''['''単語記事''']''' - ニコニコ大百科]]
([TIME[2020-04-24 07:05:18 +09:00]])
<https://dic.nicovideo.jp/a/%E3%81%9F%CD%9C%CD%9C%CD%8F%CC%98%CC%A3%CD%94%CD%99%CD%8E%CD%8E%CC%98%CC%9C%CC%AB%CC%97%CD%8D%CD%9A%CD%93%CD%9C%CD%9C%CD%8F%CC%98%CC%A3%CD%94%CD%99%CD%8E%CD%8E%E3%81%99%CD%9C%CD%9C%CD%8F%CC%98%CC%A3%CD%94%CD%99%CD%8E%CD%8E%C6%A1%CC%9F%CC%A4%CC%96%CC%97%CD%96%CD%87%CC%8D%CD%8B%CC%80%CD%86%CC%93%CC%81%CD%9E%CD%A1%E3%81%91%CC%9C%CD%AA%CC%85%CC%8D%CC%85%CD%82%CD%8A%E3%81%A6>


[208] [CITE[Quivira Combining Characters - QuiviraCombining.pdf]], [TIME[2014-08-23T11:39:55.000Z]], [TIME[2020-12-29T11:06:18.497Z]] <http://www.quivira-font.com/files/QuiviraCombining.pdf>

[213] [CITE@ja[さく҉らん҉̴҉҇ぼ小҉̷҉学校҉̶҉҇҉̨҉͌3.҉̸҉̕҉̢҉̔m҉̵҉͝҉̢҉̓҉̓҉̚҉͌҉p҉҉҉͠҉͢҉͋҉͋҉̈҉4҉̷҉͝҉̨҉̏҉̀҉͔҉̜҉̙ - ニコニコ動画]]
([TIME[2021-06-12 08:59:27 +09:00]])
<https://www.nicovideo.jp/watch/sm38869649>

[219] [CITE@ja[ず҈̡̟͎̙̗̪̓̀̓̃̆͊͗̆̕んだ̴̮̣̙͇҇̃̈̔͐͢も҈̨̳̱͍̗̑̍͂̎̕̚̚̚̚ん҉マンションの日常 - ニコニコ動画]]
([TIME[2022-08-31 10:23:42 +09:00]])
<https://www.nicovideo.jp/watch/sm40995049>

[228] [CITE@ja[Unicode正規化 用語の混乱について 第4.2版 – ものかの]], [TIME[2023-05-24T01:20:54.000Z]], [TIME[2023-05-24T11:39:28.589Z]] <https://tama-san.com/unicode-normalize-confusion/>


[259] [CITE@ja[「文̥字̥打̥つ̥と̥車̥輪̥が̥つ̥く̥よ̥う̥に̥な̥っ̥た̥の̥で̥す̥が̥こ̥れ̥は̥な̥に̥な̥の̥か̥誰̥か̥ご̥存̥知̥な̥い̥で̥す̥か̥;;」謎のバグに苦しむVTuberに解決案が寄せられるもお手上げ状態 - Togetter]]
([TIME[2024-02-29T02:39:00.000Z]])
<https://togetter.com/li/2323359>