Slide 1

Slide 1 text

ゼロから実装する 縦書きTextViewと その周辺技術 六々@496_ / DroidKaigi 2019 Room 6 - 2019/02/08 15:40-16:30 Keynoteに続いてGoogle スライドも縦書きができなかった

Slide 2

Slide 2 text

自己紹介 ● 六々(ろくろく) ● @496_ ● 趣味でTATEditorという縦書きエディタを作ってます ○ Windows / macOS / Ubuntu版は公開中 ○ Android / iOS / UWP版は開発中

Slide 3

Slide 3 text

TATEditor ● クロスプラットフォームな縦書きエディタ ● C/C++製で2013年から公開

Slide 4

Slide 4 text

縦書きTextViewって? ● カスタムViewの話です ○ 縦書きでテキストが表示できる ○ 縦書きでテキストが編集できる ● AndroidのTextView / EditTextに相当

Slide 5

Slide 5 text

縦書きTextView ● テキストが入力できてる! ● 縦書きで表示されてる!

Slide 6

Slide 6 text

今回話す内容 ● TextViewの話 ● 文字コードという概念 ● フォントという概念 ● 縦書きテキストの作り方 ● IMEの話 ● AndroidのIMEをViewから利用する方法 ● AndroidのTextViewのその他の便利機能について

Slide 7

Slide 7 text

TextViewとは?

Slide 8

Slide 8 text

AndroidのTextView / EditText ● ViewerであるTextView ● EditorであるEditText ● 実はちょっと違う

Slide 9

Slide 9 text

TextViewとEditTextの違い ● テキストを選択する関数が生えているかどうか ● getTextでEditableが返ることが保証されているかどうか ● デフォルトのプロパティの違い ● TextViewでもテキスト編集は可能 ○ android:enabled="true" ○ android:focusableInTouchMode="true" ○ android:inputType="text" ○ android:textIsSelectable="true"

Slide 10

Slide 10 text

TextViewとは?

Slide 11

Slide 11 text

AndroidのTextViewの機能 ● テキストを表示できる ● テキストを入力できる ● テキストを選択できる

Slide 12

Slide 12 text

TextViewとは? ● どのOSでも標準のTextViewが用意されています →非常にプリミティブなView

Slide 13

Slide 13 text

TextViewとは? ● プリミティブなViewだけどちっともシンプルではない ● 色々なものが交わる魔窟 ○ 入力装置(≒人間) ○ アプリ ○ OS ○ IME

Slide 14

Slide 14 text

一方、縦書きのTextViewは ● 縦書きのTextViewが横書きのTextViewと違うところ ○ テキスト表示が縦書き(見た目だけの問題)

Slide 15

Slide 15 text

一方、縦書きのTextViewは ● 縦書きのTextViewが横書きのTextViewと違うところ ○ テキスト表示が縦書き(見た目だけの問題) ○ ほとんどのOSに標準で用意されてない

Slide 16

Slide 16 text

一方、縦書きのTextViewは ● 縦書きのTextViewが横書きのTextViewと違うところ ○ テキスト表示が縦書き(見た目だけの問題) ○ ほとんどのOSに標準で用意されてない ● 縦書きのTextViewを使いたければ作る必要がある ○ 一般的なOSなら縦書き含む独自のTextViewが作れる ○ そのためには何をすると良いのかを話します

Slide 17

Slide 17 text

タイトルの「ゼロから実装する」について ● TextViewやEditTextは使いません ○ 縦書きができないので ● drawTextなどは使いません ○ 縦書きができないので

Slide 18

Slide 18 text

タイトルの「ゼロから実装する」について ● 文字コードは作りません ○ Unicodeを使います ● フォントは作りません ○ 端末にインストールされているフォントを使います ● IMEは作りません ○ 端末にインストールされているIMEを使います ● ViewとdrawBitmapは使います

Slide 19

Slide 19 text

アウトライン ● TextViewの主な機能の縦書きでの実装可能性 1. テキストを表示する 2. テキストを編集する 3. その他の便利な機能

Slide 20

Slide 20 text

TextViewの機能その1 テキストを表示する

Slide 21

Slide 21 text

テキストを表示する ● このテキストはどうやって表示されていますか?

Slide 22

Slide 22 text

テキストを表示する ● このテキストはどうやって表示されていますか? ○ ざっくりと言うと画像が表示されています

Slide 23

Slide 23 text

テキストを表示する=画像を作る 入力 テキスト描画系 出力 テキスト 画像

Slide 24

Slide 24 text

画像、Androidなら例えばBitmap ● Bitmapを作ればディスプレイに表示できる ○ 中身はARGB_8888が推奨されている ■ 32bitで上位ビットからAlpha, Red, Green, Blue ■ 0xFFFFFFFFだと白 ○ 表示方法 ■ ViewのonDrawでcanvas.drawBitmap ■ ImageViewでも良い

Slide 25

Slide 25 text

テキスト描画系(テキスト描画エンジン) 入力 テキスト描画系 出力 テキスト 画像 この魔法の箱が 欲しい

Slide 26

Slide 26 text

テキスト描画系という魔法の箱 ● 本来ならCanvasのdrawTextがこの「魔法の箱」に相当 ● drawTextは縦書きができない ○ 魔法の箱を自作します

Slide 27

Slide 27 text

この「テキスト描画系」を分解していきます 入力 テキスト描画系 出力 テキスト 画像

Slide 28

Slide 28 text

テキストも所詮ただのバイト列 入力 テキスト描画系 出力 画像 文字コードの 知識 バイト列 (テキスト)

Slide 29

Slide 29 text

文字コード ● 機械やそれを使う人同士でのプロトコル ○ みんなでこのバイト列はこの文字に相当するものとして扱 いましょうという約束 ○ でっかい表 ● プロトコルを取り違えてしまうのがいわゆる文字化け ● 最近だとだいたいUnicode

Slide 30

Slide 30 text

テキストを表示するためにはフォントが必要 入力 テキスト描画系 出力 画像 文字コードの 知識 参照する バイト列 (テキスト) フォントファイ ル

Slide 31

Slide 31 text

フォント ● 文字コードのバイト列から人間の目と脳に優しい画像情報を 生成するための全ての情報を格納したファイル ○ どの文字がどういう形なのか ○ 文字の大きさはどれくらいなのか ● 最近だとだいたいOpenTypeフォント https://www.freetype.org/freetype2/docs/glyphs/glyphs-3.html

Slide 32

Slide 32 text

テキストを表示する 入力 テキスト描画系 出力 バイト列 画像 文字コードの 知識 参照する (テキスト) フォントファイ ル バイト列と文字コードを照ら し合わせて適切な文字の形 状をフォントから取得して画 像に出力する

Slide 33

Slide 33 text

用語 ● コードポイント ○ Unicodeに収録されている文字(意味) ● グリフ ○ OpenTypeフォントに収録されている文字(形状) U+0041 U+3042 U+5B89 A あ 安 B い 以 コードポイント グリフ

Slide 34

Slide 34 text

Unicodeについて簡単に ● バイト列を文字列として扱うための規格 ● 符号化文字集合のひとつ ○ U+0000 ~ U+10FFFFを文字に対応づけたもの ○ U+xxxxがコードポイント、U+後ろは16進数表記 ● UTF-8 / UTF-16 / UTF-32は文字符号化形式 ○ U+0000 ~ U+10FFFFの21bitの情報をどのようにバイト 列で表現するかを定めたもの

Slide 35

Slide 35 text

AndroidのStringとその周辺 ● AndroidのString (CharSequence) はchar[]で構成される ○ charは16bit整数=内部データはUTF-16 ● 表のInterfaceは下が上を継承している Interface Object(実装) 役割 CharSequence String 文字列へのアクセス Spanned SpannedString 文字列とマークアップへのアクセス Spannable SpannableString 編集可能なマークアップ Editable SpannableStringBuilder 編集可能な文字列とマークアップ

Slide 36

Slide 36 text

余談: Android StudioとString ● Android Studioを使ったAndroidアプリのデバッグ ○ ブレークポイントを置くと変数の中身を確認できる ○ CharSequenceのtoString()経由でAndroid Studioが取得 ● これを知らずにデバッグ中にブレークポイントで止めるとクラッ シュする問題で困った ○ CharSequenceのtoString()は初期前でも空文字列を返す ようにした

Slide 37

Slide 37 text

OpenTypeフォントについて簡単に ● フォントファイルの仕様のひとつ ○ グリフを最大65534個格納できる ○ 最初の1つは.notdefと定められている ■ いわゆる豆腐 ○ グリフは基本的にベクター画像として格納されている ■ Bitmapにするにはラスタライズする必要がある

Slide 38

Slide 38 text

テキストを画像にするまで 入力 出力 バイト列 画像 グリフ列 文字コードの 知識 (テキスト) コードポイント列 U+0041 U+3042 U+5B89 A あ 安 Aあ安 フォントファイ ル

Slide 39

Slide 39 text

Androidとフォント ● システムのフォントファイルのありか ○ /system/etc/fonts.xml にフォント情報がある ■ Android 5.0からはこれだけを見ればよくなった https://github.com/google/skia/blob/master/src/ports/SkFontMgr_android_parser.cpp ○ fonts.xmlにフォントファイルのパスが記されている https://android.googlesource.com/platform/frameworks/base.git/+/master/graphics/java/android/graphics/FontListParser.java ■ 普通に開いて読み込むことができる ■ FreeTypeを使うとだいたいのことができる

Slide 40

Slide 40 text

余談: 最近のAndroidとフォント ● Variable Font (OpenType 1.8で導入された新機能) ○ Android 8.0からVariable Fontをバンドル可能になった ○ 合わせてfonts.xmlの仕様も一部拡張されている ○ font-weight等が無段階になる機能

Slide 41

Slide 41 text

テキストを画像にするまで 入力 出力 バイト列 画像 グリフ列 文字コードの 知識 (テキスト) コードポイント列 U+0041 U+3042 U+5B89 A あ 安 Aあ安 フォントファイ ル 今ここ

Slide 42

Slide 42 text

UnicodeとOpenTypeをつなぐもの ● OpenTypeのcmapテーブル ○ コードポイントからグリフのIDへの変換表 ○ グリフIDの0は.notdefと呼ばれるいわゆる豆腐文字 U+0041..U+0042 U+3042..U+0043 U+5B89 1: A 2: B コードポイント フォント内のグリフ 3: あ 4: い 5: 安 0: (.notdef) U+1F389 cmap

Slide 43

Slide 43 text

テキストを画像にするまで 入力 出力 バイト列 画像 グリフ列 文字コードの 知識 (テキスト) コードポイント列 U+0041 U+3042 U+5B89 A あ 安 Aあ安 フォントファイ ル 今ここ

Slide 44

Slide 44 text

グリフのラスタライズ ● 読み込みにはFreeTypeというライブラリがよく使われる ○ PostScript (CFF) 系、TrueType系をまとめて扱える ○ コードポイントからグリフIDへの変換 ○ グリフIDを指定したラスタライズ画像の取得 ■ グリフは基本的にベクター画像

Slide 45

Slide 45 text

グリフ列を画像にするまで 出力 画像 グリフ列 A あ 安 Aあ安 ラスタライズ画像列 A, あ, 安 画像化 FreeTypeなど

Slide 46

Slide 46 text

グリフ列を画像にするまで 出力 画像 グリフ列 A あ 安 Aあ安 ラスタライズ画像列 A, あ, 安 どこに? 画像化

Slide 47

Slide 47 text

グリフをテキストエリアに配置する ● 以下を繰り返す ○ グリフを置く ○ グリフの幅だけ進む ● ただし、改行文字や折り返しで次の行にジャンプする https://www.freetype.org/freetype2/docs/glyphs/glyphs-3.html

Slide 48

Slide 48 text

改行にはUnicodeの知識が必要です ● Windowsの改行は\r\n ○ Carriage ReturnとLine Feedの間では改行されない U+000D CARRIAGE RETURN \r Mac OS 9まで U+000A LINE FEED \n Linux / macOS U+000C FORM FEED \f U+000B TABULATION \v U+2028 LINE SEPARATOR U+2029 PARAGRAPH SEPARATOR U+0085 NEW LINE

Slide 49

Slide 49 text

改行にはUnicodeの知識が必要です ● Windowsの改行は\r\n ○ Carriage ReturnとLine Feedの間では改行されない U+000D CARRIAGE RETURN \r Mac OS 9まで U+000A LINE FEED \n Linux / macOS U+000C FORM FEED \f U+000B TABULATION \v U+2028 LINE SEPARATOR U+2029 PARAGRAPH SEPARATOR U+0085 NEW LINE Carriage Return: 行頭に戻る Line Feed: 行を進める

Slide 50

Slide 50 text

グリフ列を画像にするまで 出力 画像 グリフ列 A あ 安 Aあ安 画像化 {画像, 座標}の列 A, {0, 0} あ, {100, 0} 安, {200, 0} 1. グリフを置く 2. グリフの幅だけ進む ただし改行文字で次の行にジャンプ

Slide 51

Slide 51 text

テキストを表示してみる ● 簡単のためまずは横書き

Slide 52

Slide 52 text

テキストを折り返してみる ● “textarea” という英単語が分割されてしまった……

Slide 53

Slide 53 text

折り返しにもUnicodeの知識が必要です ● UAX #14: Unicode Line Break Algorithm ○ Unicode標準の一部 ○ テキストのどこが折り返し可能かを定義している ○ 行頭/行末禁止・分割禁止 ● ICU (International Component for Unicode) ○ これのLineBreakIteratorを使うと良い ○ ICUはAndroidにも組み込まれている ○ もともとIBM主導のOSSで今はUnicodeに属してる

Slide 54

Slide 54 text

テキストの折り返しを正しく ● いい感じですね

Slide 55

Slide 55 text

テキストの折り返しを正しく ● いい感じですね ハイフネーションという折り返し方法もあ りますが、そのあたりのことは 2/8 12:50~のSeigo Nonakaさんのセッショ ン「Best practice for text on Android and its internals.」が参考になります

Slide 56

Slide 56 text

ところで縦書き要素はどこに?

Slide 57

Slide 57 text

テキストについて再考 ● データ上、テキストの進行方向はひとつ ○ 配列のindexが増える方向だけ ● 一方、画像は2次元情報 ○ テキストの進行方向は無数にある 普通は文字が左から右、行は上から下に進む

Slide 58

Slide 58 text

書字方向(文字の進む方向) ● 横書き(左から右) ● 右横書き(右から左) ○ アラビア語など ○ 昔の日本のメディア ○ トラックや屋台の右側面の文字 ● 縦書き(上から下) ○ 今回のトピック https://commons.wikimedia.org/wiki/File:RIKEN_VITAMIN.png

Slide 59

Slide 59 text

改行方向(行が進む方向) ● 書字方向とは直交する方向 ○ 横書き(上から下) ○ 右縦書き(右から左、vertical-rl) ■ 日本語 ○ 左縦書き(左から右、vertical-lr) ■ モンゴル語(モンゴル文字を使った場合) ● 今はキリル文字が一般に使われている

Slide 60

Slide 60 text

余談: その他の書字方向 ● 牛耕式(Boustrophedon) ○ 書字方向が右から左、左から右と交互に繰り返す ○ 古代ギリシャ語 ● 螺旋形 ○ ファイストス円盤(未解読文字) ○ Unicodeにも収録されている ■ U+101D0~U+101FD

Slide 61

Slide 61 text

縦書きと横書きの違い ● 縦書きも横書きも内部の文字列は同じ ○ 表示されている画像が違うだけ

Slide 62

Slide 62 text

縦書きの要件 ● 文字が水平方向ではなく、垂直方向に進む ● 行が垂直方向ではなく、水平方向に進む ● じゃあ、縦に並べてみましょう

Slide 63

Slide 63 text

縦書きのテキストを表示……?

Slide 64

Slide 64 text

縦書きのテキストを表示……?

Slide 65

Slide 65 text

縦書きの要件 ● 文字が水平方向ではなく、垂直方向に進む ● 行が垂直方向ではなく、水平方向に進む ● 上の2つの他に以下2つの要件がある ○ フォントの縦書き用のグリフを使用する ■ 「。」「、」「ょ」「㍻」「(」「)」「ー」 ○ アルファベット等の文字を90度回転させる ■ 半角だと回転する、全角だと回転しない

Slide 66

Slide 66 text

縦書きの際グリフをどう描画すべきか ● UAX #50: Unicode Vertical Text Layout ○ 4つに分類して定義されている(U/T/Ur/Tr) 分類 内容 対象コードポイント U (Upright) 正立(そのまま)で表示 漢字等 R (Rotated) 時計回りに回転して表示 Alphabet etc... Tu Uだが専用グリフが必要 、。ょ㍻ Tr Rだが専用グリフが必要 ()ー

Slide 67

Slide 67 text

横書き専用のグリフに変換する ● これはFreeTypeでは対応できないのでOpenTypeの仕様を 読んで実装すると良い ● OpenTypeのGSUB (Glyph Substitution) ○ グリフを別のグリフに置換するOpenTypeの機能 ○ 縦書きの場合は1グリフ↦1グリフ ■ vert / vrt2 / vrtrというタグのもの ■ 他の用途だとNグリフ↦Mグリフの場合もある

Slide 68

Slide 68 text

完成!? ● だいたい良さそう

Slide 69

Slide 69 text

完成!? ● だいたい良さそう 豆腐

Slide 70

Slide 70 text

グリフの形式の多様化について ● 一昔前までは白黒の世界で全てが閉じていた ● カラー絵文字の登場でここが複雑化している

Slide 71

Slide 71 text

Unicodeとカラー絵文字の話 ● UTS #51: Unicode Emoji (ごく最近version 12.0が出た) ○ 絵文字の大雑把な類型 ■ 国旗 ■ 囲み数字 ■ 結合文字 (ZWJ) ■ Presentation Selector ■ Emoji Modifier ■ Tag Sequence 2/7 15:40~のTakeichi Yukiさ んのセッション「Androidエンジ ニアが抑えておくべき Unicode Emojiの知識」が参 考になります

Slide 72

Slide 72 text

OpenTypeフォントとカラー絵文字 ● OpenTypeのカラー絵文字の仕様は大きく4種類 形式 主なプラットフォーム 中身の形式 CBDT / CBLC Android / Linux PNG画像 COLR / CPAL Windows 普通のグリフと色情報 SVG␣ / (CPAL) Adobe / Mozilla SVG画像(と色情報) sbix Apple macOS: PNG画像 iOS: emjc画像

Slide 73

Slide 73 text

余談: OpenTypeフォントとカラー絵文字 ● カラー絵文字に関する責務が散らばっているので大変 ○ Unicodeの領域 ■ 何をどう表示すべきかという仕様 ○ フォントの領域 ■ 表示することのできる文字の提供 ○ テキスト描画系の領域 ■ カラー絵文字を使うか白黒文字を使うかの判断

Slide 74

Slide 74 text

テキストの描画 ● 完成!

Slide 75

Slide 75 text

今回話していないこと ● 横書きのメトリクス・縦書きのメトリクス ● 1コードポイント=1グリフの例外 ○ IVS(異体字セレクタ) ● 日本語組版処理の要件(JLREQ) ● 日本語以外のテキストについて ○ リガチャ ○ bidi ● 等々

Slide 76

Slide 76 text

アウトライン ● TextViewの主な機能の縦書きでの実装可能性 1. テキストを表示する ← ここが終わった 2. テキストを編集する 3. その他の便利な機能 入力 テキスト描画系 出力 テキスト 画像

Slide 77

Slide 77 text

TextViewの機能その2 テキストを編集する

Slide 78

Slide 78 text

テキストを編集する ● 文字列を選択する ● 選択範囲を別の文字列で置換する

Slide 79

Slide 79 text

テキストを編集する ● 文字列を選択する ○ キーボード操作による変更 ○ マウス操作・タッチ操作による変更 ● 選択範囲を文字列で置換する ○ キーボードから受け取った文字列で置換 ○ クリップボードの文字列で置換

Slide 80

Slide 80 text

デスクトップのテキスト入力の模式図 テキストだと 嬉しいけど……

Slide 81

Slide 81 text

デスクトップのテキスト入力の模式図

Slide 82

Slide 82 text

キーボードからの入力 ● キーコードのストリームとキー配列からどうにかテキストを生 成しないといけない ○ アルファベットはいいとして日本語は……? ■ キーの数が足りない ● これを解決するためにIMEというものがあります

Slide 83

Slide 83 text

デスクトップのテキスト入力の模式図

Slide 84

Slide 84 text

スマホのテキスト入力の模式図

Slide 85

Slide 85 text

TextViewのおさらい ● TextViewがすべきこと ○ テキストの表示 ○ テキストの編集 ■ IMEからのテキスト入力を受け取る必要がある

Slide 86

Slide 86 text

TextViewとIMEの関係

Slide 87

Slide 87 text

TextViewとIMEの関係 ● IMEが必要なのはわかった ○ IMEとViewは一体どうやって情報をやり取りするの? ■ SDK? ■ 通信?

Slide 88

Slide 88 text

TextViewとIMEの関係

Slide 89

Slide 89 text

IME APIとは ● OSがTextView実装のために用意するViewとIMEのインター フェース ○ Viewは具体的な実装を知ることなくIMEを利用できる ○ IMEは専用のSDKなどを用意せずにViewにその機能を提 供できる

Slide 90

Slide 90 text

IME APIの概観 ● IME APIがViewに要求するのは ○ テキストの取得と変更 ○ 選択範囲の取得と変更 ○ View上での文字の位置情報 ○ 未確定文字列の管理(例: スクショの「変換」が未確定文字 列=挿入されていない) ○ Viewのテキスト・選択範囲・レイアウトの変更通知

Slide 91

Slide 91 text

各プラットフォームのIME API一覧 IME APIの名称 (View側) / 標準実装 縦書き対応 (縦書きである事を伝える方法) コメント Windows ITextStoreACP / MSFTEDIT_CLASS あり 難解だけど高機能 macOS NSTextInputClient / NSTextView あり attributedString() がつらい GTK+ GtkIMContext / GtkTextView あり - Gtk 3.6.18以降 (ただし対応IMEがない気がする) やけにドキュメントが少ない Android BaseInputConnection / TextView 不可能ではないはず (CursorAnchorInfoのsetMatrix) 黎明期の闇が垣間見える UWP Windows.UI.Text.Core / TextBox なし 縦書きがあれば…… iOS UITextInput / UITextView ないのと同じ UITextPositionは素晴らしい

Slide 92

Slide 92 text

文字を入力する際の人間を含めたループ ● 人間がキーボードを叩く ● IMEがキーコードを受け取る ● IMEがアプリに確定または未確定文字列を渡す ● アプリが現在のテキストをディスプレイに表示する ● IMEが必要な変換候補ウィンドウなどを表示する ● 人間がディスプレイを見る

Slide 93

Slide 93 text

AndroidでViewをTextViewのようにするには? ● 素のViewはIMEとやり取りをすることはできない ● AndroidのIME APIに適合する必要がある

Slide 94

Slide 94 text

AndroidでViewをTextViewのようにする ● カスタムViewでIMEを使うには2つのクラスが登場する ○ BaseInputConnection ■ インタフェース ■ ViewがIMEの要求を受信する(IMEから叩かれる) ○ InputMethodManager ■ サービス(システム) ■ Viewの変更をIMEに通知する(Viewから叩く)

Slide 95

Slide 95 text

InputMethodManager ● キーボードの表示状態を変えるのによく使われる ● IMEのためにViewから変更を伝える関数がある ○ updateExtractedText ←テキスト ○ updateSelection ←選択範囲 ○ updateCursorAnchorInfo ←選択位置(画面上の)

Slide 96

Slide 96 text

BaseInputConnection ● IMEのためにView側が実装するべきこと ○ 文字列の取得と編集のInterfaceを提供 ○ 選択範囲の情報の取得と変更のInterfaceを提供 ○ 未確定文字列の描画

Slide 97

Slide 97 text

未確定文字列の描画

Slide 98

Slide 98 text

未確定文字列 ● 未確定文字列とはIME上で編集中の文字列のこと ○ 確定していないテキスト ● Spannedを通して装飾情報が渡される ○ TextViewがテキストに装飾を反映する ○ 変換中であること・どこが変換対象になっているかなどを ユーザーわかるように

Slide 99

Slide 99 text

Viewでテキスト入力を受け付けるためのまとめ ● カスタムViewに以下の実装をする ○ InputMethodManagerを通しIMEにViewの状態を通知 ○ BaseInputConnectionを実装しIMEの要求に応える

Slide 100

Slide 100 text

縦書きで編集 ● 動画再掲

Slide 101

Slide 101 text

注意: BaseInputConnection ● 実際はInputConnectionというInterfaceを継承したObject ○ アプリがInputConnectionを直接継承しても良い ○ しかしBaseInputConnectionはInputMethodManagerの @hideなプロパティを読み書きしている ■ BaseInputConnectionを使った方が良い

Slide 102

Slide 102 text

アウトライン ● TextViewの主な機能の縦書きでの実装可能性 1. テキストを表示する ← ここが終わった 2. テキストを編集する ← ここが終わった 3. その他の便利な機能

Slide 103

Slide 103 text

TextViewの機能その他 その他

Slide 104

Slide 104 text

テキストを表示・編集する以外の機能 ● アンドゥ・リドゥ ● ドラッグ&ドロップ ● コンテキストメニュー ● 文字選択中のMagnifier

Slide 105

Slide 105 text

アンドゥ・リドゥ ● TextViewに標準で実装されている ○ android.R.id.undo / android.R.id.redo ■ API Level 23~ ● キーボードなどからアンドゥ・リドゥができる ○ キーイベントでアンドゥ・リドゥを実行する ○ 編集履歴は自分で作る必要がある

Slide 106

Slide 106 text

● ドラッグ&ドロップ ● TextViewに標準で実装されている ● 選択文字列の長押しで以下を呼ぶ ○ ViewのstartDrag / startDragAndDrop ■ API Level ~23 / 24~

Slide 107

Slide 107 text

コンテキストメニュー ● TextViewでテキストを選択したときの編集メニュー ● Activity.startActionModeを使うと良い ○ TextClassifierを使うと図のようなCallも出せる

Slide 108

Slide 108 text

文字選択中のMagnifier ● Magnifier ○ API Level 28~実装された ○ 横書き専用の機能 ○ 縦書きする場合は自作しましょう

Slide 109

Slide 109 text

縦書きTextView ● 動画再掲

Slide 110

Slide 110 text

スマホと縦書き ● 縦書きはソフトキーボードとの相性が非常に悪い ○ 縦書きのリフローは画面幅ではなく、表示領域の高さの変 更で起きる ○ キーボードの表示の有無で可視領域の高さが変わる ○ IMEの変換候補の有無でも高さが変わることがある ■ リフロー発生! ● キーボードの高さへの追従とリフローの指針はきちんと考える 必要がある

Slide 111

Slide 111 text

まとめ ● テキストを表示 ○ Unicodeのコードポイント ○ OpenTypeのグリフ ○ 改行と折り返し ● テキストの編集 ○ BaseInputConnectionの継承 ○ InputMethodManagerの呼び出し