Kategorie
Publicystyka

Co nowego w fontach dla programistów?

Dlaczego kroje pisma używane przez programistów mają litery stałej szerokości? To nie tylko kwestia tradycji, wywodzącej się z czasów drukarek igłowych i terminali tekstowych – lecz także wygoda i realna pomoc w czytaniu kodu źródłowego. Powody są oczywiste dla zawodowców ale i nietrudne do objaśnienia laikom. Zwłaszcza, gdy spojrzymy na kilka ilustracji.

Spoglądajmy zatem – zapraszam do lektury bogato ilustrowanego tekstu o tym, jakie udogodnienia pojawiły się w tym obszarze w kilku minionych latach!

Aby było wiadomo, o czym mowa – poniżej widzimy napis przygotowany przy użyciu kroju Calibri o proporcjonalnej szerokości liter, czyli literka „m” jest szeroka zaś literka „j” wąska. Widzimy przy okazji, że daszek literki „T” wychodzi poza swój obszar, podobnie „j”, ale o tym później.

Podczas programowania korzystamy jednak zawsze z fontów o stałej szerokości znaków, jak tutaj (krój Consolas):

Dygresja – dzięki stałej szerokości znaków możemy w trybie tekstowym wyświetlać takie tabelki:

Przy użyciu proporcjonalnego fontu to po prostu nie zadziała:

Nie chodzi jednak wyłącznie o tabelki. W przypadku języka Python bloki kodu są wyróżniane wcięciami – kod działający w pętli albo otoczony wyrażeniem warunkowym ma na początku wiersza więcej spacji, które w przypadku fontów proporcjonalnych nie stanowiłyby wystarczającego wyróżnika. Także w innych językach programowania przejrzyste formatowanie kodu wymaga fontów o stałej szerokości znaków.

Moim ulubionym krojem do pracy z terminalami znakowymi jest Fixedsys, obecny w systemach Microsoftu od wersji 1.0 (rok 1985). Cecha charakterystyczna – jest to font rastrowy, litery są zdefiniowane nie w formie kształtów opisanych krzywymi matematycznymi, lecz jako siatka pikseli o stałych rozmiarach, wyświetlana bez żadnego wygładzania skośnych linii.

Gdy powiększymy zrzut ekranu windowsowego Terminala, zauważymy wygładzaną czcionkę Cascadia Code – jednak wygładzanie jest realizowane jedynie za pomocą pikseli o uśrednionych kolorach.

To skądinąd niespójność z ogólnosystemowymi ustawieniami ClearType, które realizują wygładzanie subpikselowe – temat ten poruszałem w tekście „Jak robić lepsze zrzuty ekranu” z roku 2020, jednym z pierwszych artykułów na blogu. Windows Terminal – podobnie, jak cały pakiet Office – renderuje tekst przy użyciu DirectWrite, z pominięciem systemowego renderowania fontów ClearType widocznego np. w tytule okna programu Putty.

Dygresja od dygresji – u początków blogowania starałem się pamiętać, by robiąc screenshoty wyłączać ClearType, ale potem zacząłem korzystać z monitorów 4K i problem stał się – nomen omen – mało dostrzegalny. Tym bardziej zresztą, że ponad połowa czytelników przegląda blogaska na smartfonach, niekoniecznie badając każdy piksel każdego obrazka.

Dygresja od dygresji od dygresji – okazuje się, że artefakty wygładzania ClearType mogą być inspiracją do stworzenia… kolorowego retro-kroju Coral Pixels. Cóż, ClearType ma już 26 lat i pomału odchodzi w przeszłość, więc retro-inspiracje są w pełni uzasadnione.

O czym to ja… A tak, o fontach dla programistów.

Który krój pisma jest najlepszy do programowania?

Powyższe pytanie ma tyle samo sensu, co dociekanie, który samochód jest najlepszy do jeżdżenia po asfalcie. Mamy różne potrzeby, gusta i przyzwyczajenia – więc i preferencje dotyczące krojów pisma będą odmienne. W ostatnich latach znacząco wzrosła jednak liczba ulepszeń i opcji konfiguracyjnych, które mamy do dyspozycji. Oto te, które zwróciły moją uwagę.

Waga czcionki

Nie jesteśmy już ograniczeni do dwóch wariantów liter – zwykłych i pogrubionych. Współczesne kroje miewają kształty definiowane algorytmicznie, dzięki czemu możliwa jest płynna zmiana grubości linii. Zwyczajowo określa się ją w skali od 100 do 800. Poniżej przykład regulacji parametrów kroju Monaspace.

źródło: Monaspace

W innych przypadkach krój może być dostępny w 5-8 wariantach, tutaj JetBrains Mono

źródło: JetBrains Mono

Ligatury w kodzie źródłowym

Ligatury były dawniej zestawem kilku liter na jednej czcionce (ołowianym bloku z którego składano wiersze i szpalty). Stosowano je tam, gdzie dwa lub trzy znaki drukowane osobno wyglądały źle – np. zbitka liter „fi” wygląda lepiej, gdy pierwsza litera nachodzi na kropkę drugiej litery.

autor: Daniel Ullrich, Threedots, licencja CC BY-SA 3.0

W fontach dla programistów ligatury zyskały jednak zupełnie nową rolę – zwiększają czytelność konstrukcji składniowych spotykanych w kodzie źródłowym. Spójrzmy na przykłady:

Źródło: FiraCode

Powyżej widzimy ligatury zmieniające np. kilkuznakowe operatory równości lub nierówności w jeden zunifikowany symbol. Korzyści? Przejrzystość i czytelność. W niektórych językach do jednoczesnego porównania wartości i typu używa się trzech znaków – FiraCode zamienia je na ligaturę z trzema poziomymi liniami. Z kolei operator nierówności != może zostać zastąpiony znanym ze szkoły symbolem (przekreślony znak równości).

źródło: Cascadia Code

Niektóre zmiany bywają bardziej, inne mniej subtelne – powyżej ligatury Cascadia Code – zawsze jednak zachowują szerokość oryginalnego zestawu znaków składowych.

źródło: Monaspace

Ligatury programistyczne nie muszą być wyborem typu „wszystko albo nic” – np. różne grupy ligatur w Monaspace mogą być włączane i wyłączane niezależnie – choć takie sztuczki obsługują tylko niektóre edytory.

Dodajmy dla porządku, że nie wszystkie nachodzące na siebie znaki to ligatury. Wspomniana wcześniej literka „T” najeżdżająca nad „o” to jedynie efekt używanego w fontach proporcjonalnych płynnego definiowania odległości między znakami. Prostokąty otaczające sąsiadujące znaki mogą się zazębiać, jeśli – mocno tu upraszczamy – kreski nie nachodzą na siebie.

Wyraźne różnice wyglądu liter

Gdy próbujemy wpisać na klawiaturze hasło czytane z innego ekranu, odkrywamy, jak wiele literek jest podobnych lub bardzo podobnych:

i I l | 1 !
O 0
‘ ` ’

Podobnie jest ze znakami interpunkcyjnymi i specjalnymi – w niektórych sytuacjach zamiana w kodzie źródłowym podobnie wyglądających symboli może skutkować zupełnie innym zachowaniem programu.

Dobrze więc, gdy kształty są odróżnialne na pierwszy rzut oka, nawet mimo pewnej nachalności daszków czy innych kresek.

źródło: JetBrains Mono

W kroju FiraCode niektóre znaki odnajdziesz w kilku wariantach. Wolisz zero z kropką a nie kreską? Da się. Literka „i” ma mieć szeryfy u góry czy u dołu? A może w obu miejscach? Albo wcale? Też się da! Również kilka ligatur w FiraCode ma swoje warianty.

źródło: FiraCode

Szeroki wybór znaków specjalnych

Czasem zastosowania rzadziej spotykanych symboli mogą nas zaskoczyć – przykładem może być np. narzędzie do rysowania wykresów w terminalu przy użyciu… symboli z alfabetu Braille’a.

źródło: YouPlot
źródło: Fixedsys Excelsior

Ligatury poprawiające wygląd

Przyznam, że zachwyciłem się dwoma poniższymi modyfikacjami, które jeszcze bardziej poprawiają wygląd renderowanego tekstu. Pierwsza pochodzi z kroju Monaspace i opiera się na spostrzeżeniu, że litery nie zawsze muszą mieć przestrzeń po lewej i prawej stronie. Skoro to przez owe marginesy litera „m” jest aż tak ściśnięta, może powinniśmy zbadać kontekst jej wystąpienia? I niekiedy pozwolić jej wypełnić cały segment?

Tak właśnie działa technika zwana „texture healing” w kroju Monaspace – jeśli szerokie litery sąsiadują z takimi, które mogą zapewnić dość pustego miejsca, to litery te dostaną więcej przestrzeni do dyspozycji.

źródło: Monaspace

Modyfikacja druga: w kroju FiraCode znaki interpunkcyjne i specjalne są adjustowane w pionie w taki sposób, aby ich lokalizacja pasowała do wysokości liter po lewej i prawej stronie. Mało kto świadomie zarejestruje takie detale, niemniej warto docenić dążenie autorów do typograficznej perfekcji.

źródło: FiraCode

Jak wybrać font do programowania?

To proste – wejdź na stronę www.codingfont.com i poddaj się testowi. Zobaczysz 28 krojów o stałej szerokości znaków, ułożone w losowej kolejności, gotowe do rywalizacji w systemie pucharowym. Za każdym razem wybierasz, czy bardziej podoba ci się krój po lewej czy po prawej stronie – zwracaj uwagę na wszystkie cechy opisane w niniejszym artykule!

Po 27 pojedynkach wyłonisz zwycięzcę. Daj znać w komentarzach, który krój okazał się u ciebie tym najlepszym. U mnie prawie zawsze jest to Noto Sans Mono.

Zwracam uwagę na możliwość rezygnacji z ligatur – choć wyglądają elegancko, to wiele osób jest zirytowanych zmianami wyglądu kodu źródłowego podczas pisania.

Dygresja o Panu Tadeuszu

Skoro mówimy o fontach ekranowych, chciałbym przypomnieć moje dokonanie opisane w artykule pt. „Litwo! Ojczyzno moja! Ty jesteś jak PNG 4K UHD!”. Sprawdzałem wówczas, jak duża musi być bitmapa, aby zmieścił się na niej czytelny tekst poematu „Pan Tadeusz” Adama Mickiewicza.

Zastosowałem bitmapowy alfabet o rozmiarze 3×3 piksele.

Niby niedużo, ale po krótkim treningu da się płynnie czytać

No i wyszło, że tekst „Pana Tadeusza” zmieści się na bitmapie o rozdzielczości 3840 x 2160 pikseli, czyli popularnym 4K UHD. Gdy dziecko będzie miało przerobić tę lekturę, zamiast zasuwać do biblioteki wrzucisz na ekran domowego telewizora obrazek i z głowy:

Kliknij aby powiększyć. Jeśli chcesz zapisać sobie ten właściwy duży obrazek na swoim komputerze, kliknij prawym klawiszem tutaj i wybierz pozycję „Zapisz element docelowy jako…” lub podobną

Licencja: public domain, Creative Commons Zero (CC0 1.0)

A co, jeśli zechcielibyśmy do renderowania poematu zaprząc składowe części każdego piksela RGB? Zapraszam do lektury tekstu!

Pomysły dziwne i zwariowane

Ciekawy pomysł zrealizował autor kroju Datatype, który za pomocą ligatur pozwala konstruować wykresy słupkowe, liniowe oraz kołowe.

Dzięki temu serię danych (znormalizowaną do zakresu 0-100) można przedstawiać tak, jak na obrazku poniżej, bez użycia bitmap ani grafik SVG.

Innym pomysłem są kroje pisma tworzące kody kreskowe:

W roku 1968 opracowano krój OCR A, którego celem było minimalizowanie liczby pomyłek w maszynowym rozpoznawaniu tekstu. Wiele liter ma z tego powodu nienaturalne kształty – obejrzyjcie duże Q albo ósemkę. Z roku 1983 pochodzi niespotykany w Polsce krój E-13B używany w obrocie czekami.

Kilka specjalistycznych krojów pisma pozwala na prezentację zapisu nutowego:

Parametryzację jednego kroju doprowadzono do ekstremum w Roboto Flex, w którym dostosować do potrzeb można aż 12 cech opisujących znaki (na poniższym obrazku widać pięć: waga, szerokość, rozmiar optyczny, gradacja (?), skos).

źródło: Roboto Flex

Wyższa matematyka

Dzięki temu, że definicja fontu TrueType pozwala na przeprowadzanie podczas wyznaczania kształtu znaku(-ów) dowolnych obliczeń (jest Turing-zupełna), możliwe były dużo dziwniejsze produkcje.

Co powiecie na font, który automatycznie koduje treść w QR-kodzie?

Albo font wyświetlający w pojedynczym symbolu kalendarz?

Albo font renderujący zapis szesnastkowy kodu maszynowego Z80 w postaci asemblera z mnemonikami i trybami adresowania?

Albo font, który ma wbudowany duży model językowy i automat do inferencji tego modelu?

Albo font, który renderuje grę FPS?

Jednak moim osobistym numerem jeden jest…

Fontemon czyli Pokemony w kroju pisma

Ciężko zrozumieć Fontemona, póki się w niego nie zagra – polecam więc wypróbowanie przynajmniej wersji webowej. Każda kolejna litera wpisana z klawiatury popycha akcję do przodu poprzez przejścia między tysiącami możliwych stanów gry, z których każdy reprezentowany jest przez jeden wielki znak, komponowany z wielu części składowych. Oczywiście kasowanie liter oznacza cofnięcie ruchu i możliwość wyboru innej ścieżki gry. Programistów zainteresuje techniczny opis realizacji Fontemona.

Na zakończenie dodam tylko, że do tworzenia artykułu siadałem z myślą o tym, by opisać funkcję „texture healing” z kroju Monaspace i ewentualnie wspomnieć ligatury dla programistów. A potem – jak to w moich tekstach – doszły dygresje.

Jeśli podobał ci się ten artykuł, zapisz się na newsletter!


.

O autorze: zawodowy programista od 2003 roku, pasjonat bezpieczeństwa informatycznego. Rozwijał systemy finansowe dla NBP, tworzył i weryfikował zabezpieczenia bankowych aplikacji mobilnych, brał udział w pracach nad grą Angry Birds i wyszukiwarką internetową Microsoft Bing.

5 odpowiedzi na “Co nowego w fontach dla programistów?”

W ogóle z ligaturami jest „ciekawie”. Spora część fontów była tradycyjnie robiona pod języki cokolwiek inne niż polski. Zatem mamy w popularnych fontach ligatury typiu ffl, których w polskim praktycznie nie ma okazji użyć, ale nie mamy już np. łł, które ładnie dałoby się zligaturyzować (jest taki czasownik? :)).
Swoją drogą, jako człowiek starej daty jakoś tak jestem raczej fanem fontów odwzorowujących stare dobre rastrowe fonty z trybów tekstowych EGA, czy VGA. (Fakt, często nie mają polskich ciapków, ale w moich zastosowaniach to zazwyczaj nie przeszkadza).

Kilkanaście lat temu spotkałem font Cascadia Code i to że były z ligaturami to było coś fantastycznego co ułatwiało pracę programisty. Byłem zaskoczony że w prostych edytorach tekstowych to działa.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Wymagane pola są oznaczone *