第72話の読み取り台に現れた一文字を、イトは透明なcardへ移した。
あ
cardの裏では、三つのbyteが順番を保っている。
E3 81 82
そのcardを、見学用plate printerへ差し込んだ。
preview screenが一度暗くなる。
次に現れたのは、さっきの文字ではなかった。
縺�
イトはsource edit keyへ手を伸ばした。
「壊れたなら、ここへ『あ』って打ち直せばいい」
printerの奥には、12枚のblank plateが積まれている。
resume leverを一度引けば、previewと同じ文字を12枚へ刻み、表面をsealする。
刻んだplateは元のblankへ戻せない。
それでも、次の見学班へ渡すためにはqueueを再開する必要がある。
壊れたのは、文字か、読み方か
ユイはsource edit keyへ透明coverをかけた。
打ち直すことを禁止したのではない。
まず、どこで違ったのかを残すためだ。
マコトはprinterのtraceを三段に分けた。
source bytes E3 81 82
declared encoding utf-8
active decoder shift_jis
source cardの三byteは、第72話から一つも変わっていない。
producer cardにはutf-8と書かれている。
ところがprinterは、別のdecoderを挿したまま読んでいた。
イト
文字が壊れたんじゃなくて、同じbyteを別の約束で読んだのかもしれない
ユイ
raw bytes、作った側の宣言、読む側のdecoderを分けて確認できます
マコト
previewだけ直す前に、どの段で意味が変わったかを固定しよう
Picoはsourceにもdecoderにも触れなかった。
printerの横へ、三つのrecovery cardだけを置いた。
三つの直し方
A:previewへ「あ」と打ち直す
目の前の一枚は読める。
けれど元のsource fileと、printerが次に読む12件は直らない。
B:読める文字が出るまで、三byteを書き換える
偶然読める形になるかもしれない。
しかしproducerが送ったE3 81 82を失い、別のdataを作る。
C:raw bytesを保ち、declared encodingとactive decoderを合わせる
sourceをread-onlyのまま固定する。
printerだけをutf-8へ切り替え、まず一枚をtest decode / test printする。
イトはAのtyping panelを伏せた。
Bのbyte editorも閉じた。
「C。読めないからって、先に手紙を書き換えない。読み方を確かめる」
文字、番号、byte、見た目は別の役割
一枚のcardを、四つの層へ分ける。
1. 文字
人が「あ」として区別したい、抽象的な文字がある。
丸いfontでも角ばったfontでも、同じ文字を表せる。
2. Unicode code point
Unicodeでは、この文字に U+3042 というcode pointが割り当てられている。
code pointは、文字のidentityへ結び付く番号だ。
画面に描く線そのものでも、保存済みbyteそのものでもない。
3. UTF-8 byte sequence
UTF-8は、Unicodeのcode pointを1〜4byteのsequenceとして表すencoding formだ。
このfixtureでは、U+3042をUTF-8で表した三byteが次になる。
U+3042 -> E3 81 82
第72話で守った、exact three bytesだ。
4. Font / glyph
decoderがbyte sequenceをcode pointへ戻したあと、fontが画面の形を描く。
fontを替えれば線の太さや丸みは変わる。
それだけでU+3042が別の文字へ変わるわけではない。
Unicodeはfontの名前ではない。
UTF-8も、日本語だけを表示するmodeではない。
役割を一つに混ぜると、どこを直したのか分からなくなる。
イトがdecoderだけを差し替えた
イトはsource cardへlock sealを置いた。
checksum lampはgreenのまま。
三つのbyteには触れない。
printerからshift_jis decoder cardを抜き、producer cardと同じutf-8を自分の手で差し込んだ。

test decodeを一回だけ走らせる。
raw bytes before E3 81 82
raw bytes after E3 81 82
active before shift_jis
active after utf-8
decoded code point U+3042
previewから縺�が消えた。
代わりに、あが一文字だけ現れた。
イトはまだresume leverを引かない。
一枚のtest plateを選び、自分の目でsource cardと見比べた。
code pointはU+3042。
追加byteは0。
削除byteも0。
replacement characterも0。
そこで初めて、イトはqueueを再開した。
test plates 1
queued plates 12
printed あ 12
mojibake 0
source edits 0
12枚目のsurfaceがsealされる。
Picoは、traceの三段をcyan lightで照らしただけだった。
raw sourceを守ると決め、decoder cardを選び、一件testしてからresumeしたのはイトだ。
文字化けを見たとき、最初に変えないもの
このlabの縺�は、E3 81 82をUTF-8ではないdecoderへ渡したclosed fixtureだ。
実際の文字化けには、encoding labelの取り違え、途中で変換されたdata、欠けたbyte、扱えないsequenceなど、別の原因もある。
だから「読めない文字なら、いつもUTF-8へ変えれば直る」とは限らない。
最初の一手は、変換を重ねることではない。
1. raw bytesを退避する
2. producer / fileのdeclared encodingを確認する
3. active decoderと照合する
4. copyで一件だけtestする
読める文字が偶然出たことだけを正解にしない。
元の宣言、byte sequence、期待するcode pointがつながるところまで確認する。
正しい一文字が、三つの包みを待っていた
print queueが空になると、export trayが開いた。
中には、同じあのdataを待つ三つのcontainerがある。
一つはplain text用。
一つは画像用。
一つはpage document用。
見た目は、どれも同じ白い封筒だった。
イトは一番近いcontainerへ入れようとして、手を止めた。
今回は、中のbyteを書き換えずに読み方を直した。
次は、中身を何として保存し、どのappへ渡すかを決めなければならない。
イトは三byteのlock sealを外さず、containerの口だけを見比べた。
「同じdataでも、包み方を間違えたら、開く側は困るよね」
三つのcontainerに、まだ名前は出ていない。
次回、ピコルート第74話。
File formatは、中のdataをどう読ませる?

