Hlavní navigace

Odpověď na názor

Odpovídáte na názor k článku Písma a jejich použití: formáty písem TrueType a OpenType. Názory mohou přidávat pouze registrovaní uživatelé. Nově přidané názory se na webu objeví až po schválení redakcí.

  • 17. 9. 2024 0:13

    Lael Ophir

    Byly tu nějaké dotazy a komentáře ohledně Unicodu, takže zkusím něco málo napsat. Unicode vznikl v roce 1991 na základě spolupráce lidí z Xeroxu, Applu, Microsoftu, NeXTu, Sunu, a dalších co se přidali po cestě. Očekávalo se, že bude popisovat pouze moderní písma, a počítalo se s 16-bitovými znaky. Je to přece triviální: 65535 znaků, protože "to musí stačit každému", a prvních 256 z důvodu kompatibility kopírovalo ISO 8859-1. Trochu problém vznikl s CJK ideogramy, tj. čínskými, japonskými a korejskými znaky. Ty totiž existují v tradiční a zjednodušené formě. Pevninská čína používá zjednodušené znaky. Japonsko, Hong Kong, Taiwan, Singapur, a k tomu občasní a historičtí uživatelé Filipíny, Jižní Korea a Vietnam používají tradiční znaky, s tím že si je ale v některých případech také různě zjednodušili. Jenže mít každý znak několikrát by nešlo, nevešlo by se to. Takže pánové usoudili, že v Unicode bude každý znak jen jednou, protože mají oba stejný význam, a prezentace konkrétní formy toho znaku bude čistě věcí fontu. Zajímavé je, že na rozdíl od CJK symbolů jsou v Unicode písmena A a А, O a О a Ο apod., které sice mají stejný význam, ale jsou z latinky, azbuky, a (v druhém příkladu) řečtiny. Pravidlo o jednom znaku pro jeden význam zjevně platí pouze pro CJK symboly. Dále přidali například full-width latinku a čísla, které se používají při psaní CJK ideogramy, pokud chcete mít "západní" znaky stejně široké jako CJK ideogramy.
    Pokud jde o implementaci, tak opět platí "je to jednoduché". Windows NT používají od začátku 16-bitový wchar_t; co wchar to znak, co znak to pozice ve fontu, znak se vykreslí na obrazovce nebo tiskárně... K Unicode-enabled API mají paralelně API v 8-bitové "ANSI" kódové stránce systému, a ta se interně převádí na Unicode. Unicode verze každého API končí na W, ANSI verze na A, například CreateFileW a CreateFileA. Zní to skvěle, je to jednoduché, ale počkejte si na dějový zvrat.

    Na Unixech to bylo složitější, protože v průběhu a po Unix Wars neexistovala autorita, která by řídila vývoj API unixových systémů. Nakonec došlo k přidání velmi omezené podpory locale pro wchar, který byl obyčejně (ale zřejmě ne vždy) 32-bitový. Nikomu se ale nechtělo předělávat všechna API používající 8-bitové chary na 16- nebo 32-bitové wchary, mimo jiné protože je na to navázaná spousta datových struktur, a navíc to neměl kdo koordinovat napříč Unixy. Naštěstí kdosi přišel s myšlenkou, jak Unicode protlačit skrz API stavěné na 8-bitové chary. Pro tento účel vznikla kódování UTF-1, UTF-7 a UTF-8; to poslední jistě znáte. V principu se 16-bitové Unicode wchary přeloží na sekvenci 8-bitových charů. V případě UTF-8 to navíc má kompatibilitu s ASCII (dolních 7 bitů), a pokud je nastavený osmý bit, tak jde o součást sekvence, takže je možná resynchronizace pokud začnete číst uprostřed streamu. UTF-8 se po pár letech rozšířilo. Trochu problém nastal v tom, že se v každém API mohl míchat text v "tradičních" kódových stránkách s textem v UTF-8, podle toho jestli aplikace používala nebo nepoužívala Unicode, a to například u názvů souborů nebylo úplně ideální. Podobně když aplikace zavolala X11lib s požadavkem "vykresli tento string", tak nebylo jasné, jestli je v UTF-8 nebo v ISO 8859-x. Navíc aplikace používající Unicode většinou používaly (a používají) stringy založené na wcharu. Unixy měly prostě horší technické řešení ve srovnání se systémy založenými na wcharech, což jsou Windows NT, .NET, Java, Qt, NextStep a OS X (Cocoa API). Tedy vyjma toho, že u wcharu je problém s endianness. Když nevíte, v jakém kódování Unicode text je, tak se dá použít Byte Order Mark, který je na začátku stringu... Je velmi často nepodporovaný a způsobuje problémy, takže se moc nepoužívá (na Unixech, co vím, jen raritně). Navíc endianness znamená průšvih pro portabilitu datových struktur... To není vše, na dějový zvrat dojde záhy.

    V roce 1996 vyšel Unicode 2.0. Při jeho vývoji bylo zjevné, že je projekt úspěšný, a také že se všechny znaky do 16-bitové tabulky nevejdou. Proto vymysleli vyjma UTF-1, UTF-7 a UTF-8 také UTF-16 pro reprezentaci více než 65536 znaků. To znamená, že pak ani u systémů s 16-bitovým wcharem neplatí, že jeden wchar je jeden znak. K tomu přišly kompozitní znaky, řekněme r plus ˇ, a tabulka toho, které kombinace odpovídají předdefinovanému znaku (zde ř). K tomu Unicode (již z dřívějška) obsahuje řídící znaky, které například u arabských znaků indikují, jestli se mají spojit "na čáru", nebo jestli mají zůstat oddělené. Když se znaky spojí "na čáru", tak dostanou jinou formu, což často vyžaduje další "znaky" - glyphy - ve fontu. Je to další odklon od konceptu jeden wchar je jeden znak. A podobně jako na Unixech s UTF-8 je i na NT/.NETu/Javě/Qt/OS X možné mít text s neplatnými UTF-16 sekvencemi, které sice prolezou skrz většinou API, ale nedávají smysl. Implementace Unicode (a OpenType, který je do věci logicky zapojený) je výrazně složitější, než na začátku cesty. S víceznakovými sekvencemi, ligaturami, podporou jazyků psaných zprava doleva, hromadami modifikátorů atd. bych už řadu let rozhodně nepsal "je to jednoduché". A Microsoft minimálně pro multiplatformní vývoj her doporučuje používat "ANSI" API s 8-bitovými znaky, přepnuté do UTF-8.

    Co se stalo od doby Unicodu 2.0? Nic moc. Unicode přidal podporu dalších živých i mrtvých jazyků, včetně klínového písma a egyptských hieroglyfů. K tomu další CJK symboly, symboly měn atd. Vyjma pár odborníků to nikoho nezajímá. Výjimkou je přidávání nových emoji, kombinačních znaků pro určení barvy pokožky u emoji, kombinační znaky typu "žena plus dítě", "muž plus vozík" apod. To je v podstatě jediná věc, o které se u nových verzí Unicode mluví. Poslední verze má 154 998 znaků, a dá se čekat, že ještě pár desítek emoji bude přidáno :)

    Ještě zpátky k těm kombinačním znakům. Jak jsem psal, znak ř je možné alternativně zapsat jako r plus ˇ. Proto ISO 10646 (což není úplně totéž co Unicode) popisuje různé normalizace textu: NFD (Normalization Form Canonical Decomposition, ř se převede na r plus ˇ), NFC (Normalization Form Canonical Composition, r plus ˇ se převede na ř pokud lze), NFKD (Normalization Form Compatibility Decomposition) a NFKC (Normalization Form Compatibility Composition). Ty normalizace nejsou bijekce, tj. nutně neplatí že vstup převedený z NFC do NFD a zpátky bude shodný s původním. Compabitility (de)composition řeší věci typu převodu římského čísla xii na znaky xii, ligatura ffi se převede na znaky ffi, index ⁵ se převede na 5 atd., což je dobré například při hledání v textu; dále nebudeme řešit. Windows by default používají NFC, takže jména souborů jsou ve formě "ř", pokud to lze (a pokud někdo nedonutil Windows to udělat jinak). OS X používá NFD, takže například jména souborů jsou ve formě "r plus ˇ". Pokud je o Linux, tak nevím, ale například u Samby se řešilo, jestli "ř" a "r plus ˇ" v názvu souboru je totéž, a údajně to způsobovalo i ztrátu dat (nevím jak). Opět "je to jednoduché" neplatí, ani název souboru už není jen string charů nebo wcharů, a je třeba nad tím přemýšlet.

    Další kategorií komplikací je třeba možnost změnit směr psaní textu, což může vyústit v bezpečnostní problémy - text na pohled vypadá jinak, než co obsahuje (a v případě skriptu/kódu dělá). Ještě bych přidal již delší dobu profláknuté případy, kdy si někdo nechal vystavit certifikát například na jméno Microsoft, ale jedno z písmen "o" bylo z azbuky, což vizuálně nepoznáte. Protože nešlo o Microsoft zapsaný plně v latince, tak certifikační autorita prostě vystavila certifikát, nejspíš automaticky. Skvělý způsob jak podepsat malware platným a zdánlivě důvěryhodným certifikátem, ale dneska to už neprojde.

    Kdo to dočetl až sem, ten je extrémní geek. Komu by to nebylo zjevné: to je označení pochvalné, svým způsobem prestižní.