Fonty v Uno Platform

Xamarin Uno Platform WinUI XAML

4 years ago

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!

Uno Platform

Stažení (nebo vytvoření) fontu

Na internetu lze najít mnoho dobrých zdrojů fontů zdarma, například:

  • Google Fonts

  • 1001 Fonts

  • Font Squirrel

    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:

Sample of the Sniglet font on Google Fonts

"Sniglet" on 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.

Creating a new Uno App

Creating a new Uno App

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:

The font .ttf file copied in a custom folder in our solution

.ttf soubor ve složce "files"

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.

Add existing item context menu

Menu Add > Existing item...

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.

The Add as link feature

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:

Build Action of the font file should be set to AndroidAsset in properties

Build Action is set to AndroidAsset

Spusťme aplikaci a můžeme se pokochat naším novým fontem!

Custom font on Android

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:

Font added in the Resources/Fonts folder in the iOS project

Resources/Fonts folder in iOS project

A ujistíme se že Build Action je nastavena na BundleResource:

Font file has a BundleResource Build Action on iOS

Font set as 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!

Custom font in WASM

Custom font in WASM

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ě.