Vlastním fonty pomohou vaši aplikaci odlišit od konkurence a hodí se i pro vektorové zobrazení ikon. Podívejme se, jak fonty používat v UWP, Androidu, iOS, a WebAssembly s Uno Platform!
Stažení (nebo vytvoření) fontu
Na internetu lze najít mnoho dobrých zdrojů fontů zdarma, například:
-
Vždy se ujistěte, že licence fontu, který chcete použít umožňuje jeho zahrnutí do balíčku s aplikací. Můžeme také vytvořit vlastní font, což se hodí zejména v případě icon fontů – můžeme si vybrate vlastní sadu vektorových ikon, vygenerovat z nich font a ten využívat pro ikonografii v rámci aplikace. Niels Laute napsal skvělý článek o vytváření vlastních icon fontů pro aplikace, velmi jej doporučuji! Pro účely tohoto článku jsem si vybral font Sniglet, který je ke stažení na Google Fonts:
Formáty fontu
Budeme potřebovat dva formáty – TrueType .ttf
pro UWP, Android a iOS, a Web Open Font Format (.woff
) nebo jeho novější verzi (.woff2
) pro WebAssembly (WASM). Všechny aktuální verze oblíbených prohlížečů, které podporují WASM, podporují také .woff2
. Pokud font, který jsme vybrali nezahrnuje verzi .woff
, můžeme použít jeden z mnoha on-line převaděčů, které zkonvertují .ttf
na .woff
nebo .woff2
– kupříkladu zde, zde nebo zde. Před konverzí se opět ujistěte, že EULA fontu umožňuje konverzi provádět. Pokud ne, zkuste kontaktovat autora a o verzi .woff
jej požádat.
Uno Platform projekt
Vytvoříme si nový projekt pomocí Visual Studio šablony Cross-Platform App (Uno Platform). Pro detaily a postup instalace Uno Platform se podívejte do na oficiální dokumantaci.
Pozor, aby fonty fungovaly správně i ve WebAssembly, musíte aktualizovat Uno NuGet balíčky na verzi 2.1.0-dev.693 nebo novější – tyto verze obsahují nutný bugfix pro podporu fontů na WASM. Otevřeme soubor MainPage.xaml ve sdíleném projektu Shared. Výchozí šablona již obsahuje TextBlock
"Hello, World!", tak jej jen upravíme, aby používal font, který za moment přidáme:
Přidání fontu do platformních projektů
Ačkoliv bychom mohli jednoduše přidat kopii našeho fontu do každého z projektů, je to poměrně nepraktické – skončili bychom se třemi nezávislými kopiemi stejného souboru .ttf
, a při jeho aktualizacích bychom museli ručně nahrazovat každou z nich – a to je otrava. Lepším řešením je přidat soubor do oddělené složky v řešení a pak se na něj pouze odkazovat relativní cestou. Přidáme složku fonts do hlavní složky našeho Uno Platform řešení a zkopírujeme tam náš .ttf
:
Tento jediný soubor bude sloužit pro UWP, Android a iOS. WASM bude fungovat trochu jinak, jak uvidíme později.
Přidání fontu do UWP
Do UWP projektu přidáme složku Assets a do ní složku Fonts. Na tu pak klikneme pravým tlačítkem myši a vybereme a menu Add > Existing Item... nebo stiskneme klávesovou zkratku Shift + Alt + A.
Najdeme složku fonts v hlavní složce našeho řešení a označíme soubor .ttf
, ale namísto jeho přidání klikneme na malou šipku napravo od tlačítka Add a v menu vybereme Add As Link.
Font by se měl objevit v Solution Exploreru s ikonou malé modré šipky v pravém dolním rohu, což signifikuje, že je soubor přidán jako odkaz. To můžeme potvrdit i otevřením projektového souboru .csproj
v textovém editoru:
Nyní už můžeme spustit naši aplikaci s aplikovaným fontem:
Přidání fontu do Androidu
Postup pro Android je úplně jako u UWP. V Android projektu by již měla být složka Assets/Fonts, do které přidáme .ttf
jako odkaz. Po přidání souboru ještě ověříme v Properties že je jeho Build Action správně nastavena na AndroidAsset:
Spusťme aplikaci a můžeme se pokochat naším novým fontem!
Přidání fontu na iOS
Opět začneme stejně jako v případě UWP přidáním fontu odkazem. Tentokrát jej ale přidáme do složky Resources/Fonts:
A ujistíme se že Build Action je nastavena na BundleResource:
iOS ale vyžaduje ještě jeden krok – přidání fontu do všemocného souboru Info.plist
. Klikneme na Info.plist
pravým tlačítkem myši a vybereme View code... nebo jednoduše stiskeme klávesu F7. Sescrollujeme dolů k sekci UIAppFonts a pridáme do <array>
náš nový font:
Tím bychom měli být hotovi a můžeme naši aplikaci na spustit na iOS, tentorkát třeba se světlým motivem :-) .
Přidání fontu do WebAssembly
Poslední dílek skládačky dá o něco více práce. Abychom zjistili proč, uděláme si malou exkurzi do toho, jak jsou WASM fonty implementovány v Uno Platform. WASM fonty se obvykle deklarují v CSS pomocí pravidla @font-face asynchronně – když prohlížeč narazí na pravidlo font face, začne font stahovat a aplikuje jej až po dokončení stahování. To znamená, že stránka se na pomalejších připojeních nejdříve načte s výchozím fontem. V Uno Platform to je ještě problematičtější, protože fonty potřebuje pro správný výpočet velikostí XAML elementů při layoutu. Takže, když není font k dispozici, výpočty jsou nutně nesprávné a výsledný layout nevypadá jak bylo zamýšleno. Tento problém je trackován v této GitHub issue a dokonce zmiňuje možný workaround. My použijeme jiný workaround, kterým je zahrnutí fontu přímo do CSS souboru pomocí data URI. To sice zvětší velikost CSS souboru a je náročnější na údržbu, ale zajistí to, že je soubor stažen synchronně spolu se styly. Data URI v CSS používá Base64 encoding - pro reprezentaci obsahu souboru (v tomto případě .woff
fontu) jako URI. Abychom encodovanou verzi fontu získali, můžeme použít jeden z nástrojů pro převod fontů, nebo kterýkoliv nástroj pro encoding do Base64. Jednoduché hledání "file to Base64" vrátí stovky výsledků, na příklad tento. Nakonec – konverzi můžeme udělat i sami z pohodlí PowerShellu::
Zkopírujeme encodovaný font do schránky a vrátíme se do Visual Studia. Ve WASM projektu najdeme složku WasmCSS, kde je soubor Fonts.css. Přidáme do něj náš nový font:
Namísto tří teček (...) v snippetu vložíme Base64 font ze schránky. Pro vlastnost font-family
používáme stejné jméno, které používáme v XAMLu – konkrétně část z znakem křížku (#) – zde Sniglet. A to je vše! Náš font nyní funguje na všech platformách!
Zdrojový kód
Ukázkový zdrojový kód k tomuto článku je dostupný na mém GitHubu.
Shrnutí
Jak jsme viděli, použití vlastních fontů v cross-platform Uno aplikacích je opravdu snadné. Skutečná krása tohoto řešení je, že máme opravdu jeden, univerzální XAML, který funguje stejně nezávisle na platformě.