ChangeBlog  •  Archiwum  •  Kategorie  •  Artykuły  •  Galeria  •  Czytelnicy  •  Rupieciarnia
RSS wpisów  |  RSS komentarzy
Fontologia

W przeciętnym systemie linuksowym można wyróżnić kilka podsystemów zajmujących się obsługą fontów. Każdy z nich ma swoje specyficzne cechy i wymagania - świadome rozróżnianie między nimi znacznie ułatwia egzystencję użytkownika. Podobnie jest z samymi fontami - istnieje ich kilka odmian, ale czasem widzę, że nawet tutaj początkujący linuksowcy nie mają pewności "co jest czym". Stąd ten artykuł.

Bitmapa i wektor:

Zacznę od podstaw - od fontów. Zwykle mówi się o dwóch rodzajach - fontach bitmapowych i fontach skalowalnych (wektorowych). Obydwa są wspierane pod Linuksem, w różnych odmianach.

W foncie wektorowym każda litera opisana jest za pomocą wektorowych konstrukcji - prostych, łuków, krzywych itp. Taki font nie posiada sam z siebie "rozmiaru", on tylko zawiera opisy kształtu bez skali. Wiadomo np., że litera "I" ma być siedem razy wyższa niż szeroka, ale brakuje ciągle podstawowego punktu odniesienia - skali. Ta jest ustalana dopiero w momencie użycia fontu, wtedy można podstawiając tę brakującą zmienną do wektorowego opisu ustalić ostateczny kształt znaku. Brzmi skomplikowanie i faktycznie takie też jest. Jeszcze nie tak dawno temu (na początku ery PC) użycie fontów skalowalnych było limitowane przez moc maszyn - po prostu te parę megaherzów i odrobinka ramu często nie wystarczały do wydajnej pracy z takimi fontami, maszyny nie były w stanie renderować ich w czasie rzeczywistym. Fonty wektorowe są jednak ważnym osiągnięciem - tekst używający takich fontów daje się płynnie skalować bez utraty jakości, ponieważ jego kształt nie jest opisywany za pomocą siatki pikseli lecz geometrycznych abstrakcji.

Fonty bitmapowe obierają inny kierunek - to po prostu obrazy literek narysowane na siatce pikseli. Aplikacje używające tych fontów zwykle po prostu przenoszą je na ekran, znowu piksel po pikselu. Ma to jedno znaczące ograniczenie - font bitmapowy ma określony, stały dla siebie rozmiar - litery mają taką wielkość, w jakiej zostały narysowane przez autora fontu. Skalowanie jest możliwe, ale efekty są zawsze nieciekawe - następuje drastyczny spadek jakości, podobnie jak przy powiększaniu obrazka w gimpie - znany wszystkim efekt "pikselozy". Bitmapy nie obciążają jednak maszyny w takim stopniu jak fonty wektorowe, więc były faworyzowane dopóki komputery domowe nie stały się odpowiednio silne. I nawet obecnie są w użyciu, bo zachowały pewną zaletę - dobrze wyglądają w niewielkich rozmiarach. Fonty bitmapowe są rysowane odręcznie i autorzy mogą z dokładnością do 1 piksela określić ich wygląd po przeniesieniu na pikselową siatkę monitora. Fonty wektorowe wyglądają z kolei raczej jak skomplikowany plan inżynieryjny, w niedużych rozmiarach część detali jest gubiona, bo malutka skala i rozdzielczość monitora nie pozwala im rozwinąć skrzydeł. Jest to w pewnym stopniu naprawiane przez nowoczesne rozwiązania w fontach skalowalnych, zwłaszcza fontach TrueType, ale przeciętny font bitmapowy będzie w swoim naturalnym rozmiarze zwykle wyglądał lepiej od fontu wektorowego.

Kernel: konsola VGA:

Podstawowym środowiskiem jest wirtualna konsola VGA, razem ze swoimi licznymi wirtualnymi terminalami. Tutaj cechy fontu są regulowane przez hardware, przez układ VGA. Standardowo tryb tekstowy pracuje w rozdzielczości znakowej 80x25, używając fontu o wielkości 8x16 pikseli. Rozdzielczość ekranu można oczywiście zmienić (używając np. SVGATextMode), podobnie można zmienić wielkość używanego fontu. Choć to drugie spotyka się rzadko - trudno o porządny font dla konsoli VGA który by był zaprojektowany w rozdzielczości innej od 8x16. Zwłaszcza gdy potrzebne są polskie znaczki.

Podstawowy zestaw narzędzi zawiera pakiet "kbd", znajdują się tam narzędzia do manipulowania mapą klawiatury (to nas tu nie interesuje specjalnie), ale też zbiór fontów w różnych kodowaniach i wielkościach oraz programik który ładuje font do pamięci karty VGA. Przy standardowej instalacji fonty powinny znaleźć się w /usr/share/kbd/consolefonts/, a program do ich ładowania to setfont. Posługiwanie się nim jest proste, więc nie ma o czym mówić - po załadowaniu fontu staje się on od razu fontem ekranowym.

Same fonty są bitmapowe (co nie jest dziwne, skalowanie nie wchodzi w rachubę bo karta VGA wymusza tutaj stały rozmiar), o stałej szerokości znaków (fachowa francuszczyzna określa to mianem "fixed-width" lub "non-proportional"). Standardowym formatem tych fontów jest PSF, jest to w zasadzie strumień binarny opisujący każdy ze znaków (czyli surowa bitmapa o 1-bitowej głębi), tyle że poprzedzony nagłówkiem który podaje wielkość pojedynczego znaku itp.

XFree86 Core Fonts:

Drugim, o wiele bardziej złożonym pod tym względem środowiskiem jest XFree86. Istnieją tu dwie metody udostępniania fontów: pierwsza (starsza) to tzw. serwer fontów - aplikacja, która nasłuchuje na jakimś porcie w sieci zleceń XSerwera, po otrzymaniu zlecenia wysyła dane fontu. Dzięki temu jeden serwer fontów może obsługiwać całą sieć złożoną z wielu XSerwerów. Dodatkowo taki serwer fontów był kiedyś jedynym sposobem pozwalającym użyć fontów TrueType (no, był też drugi sposób - konwersja TrueType do Type1). Drugi sposób to wykorzystanie wbudowanych funkcji XSerwera, który od jakiegoś już czasu może samodzielnie "serwować" sobie fonty. I właśnie taki przypadek omówię - zresztą, te informacje są w miarę uniwersalne tak czy siak.

Można użyć różnych fontów. Z bitmapowych najpopularniejsze są fonty PCF (Portable Compiled Format) oraz BDF (Bitmap Distribution Format). Wśród skalowalnych najczęściej spotyka się fonty Type1 oraz TrueType. Obsługiwane są też inne, ale ze względu na ich sporadyczne występowanie nie ma co sobie nimi głowy zawracać, poza tym nie ma żadnych większych różnic w ich konfigurowaniu czy używaniu...

Najpierw należy przygotować katalog z fontami. Taki katalog jest zamkniętą jednostką przechowującą jakąś liczbę fontów - tych jednostek można mieć wiele, co pozwala utrzymać porządek w dużych kolekcjach fontów (dzieląc fonty na tematyczne katalogi). W katalogu takim znajdują się pliki fontów oraz pliki specjalne. Te "pliki specjalne" to fonts.dir, fonts.alias, fonts.scale oraz encodings.dir.

fonts.dir jest najważniejszy i nieodzowny. Jest to plik indeksujący wszystkie fonty w katalogu. Podaje on liczbę fontów oraz wiąże ich opisy XLFD z fizycznymi plikami zawierającymi fonty. Może przykład:

7
lubB08.pcf.gz -biznet-fotinosbright-demibold-r-normal--11-80-100-100-p-66-iso8859-2
lubB18.pcf.gz -biznet-fotinosbright-demibold-r-normal--25-180-100-100-p-149-iso8859-2
lubB19.pcf.gz -biznet-fotinosbright-demibold-r-normal--26-190-100-100-p-155-iso8859-2
lubB12.pcf.gz -biznet-fotinosbright-demibold-r-normal--17-120-100-100-p-101-iso8859-2
lubB24.pcf.gz -biznet-fotinosbright-demibold-r-normal--34-240-100-100-p-202-iso8859-2
lubB10.pcf.gz -biznet-fotinosbright-demibold-r-normal--14-100-100-100-p-84-iso8859-2
lubB14.pcf.gz -biznet-fotinosbright-demibold-r-normal--20-140-100-100-p-118-iso8859-2

Pierwszy wiersz to liczba wszystkich wpisów w fonts.dir. Po nim następuje lista łącząca pliki fontów bitmapowych (lewa strona, pliki PCF skompresowane za pomocą gnuzip - serwer potrafi je sobie rozkompresować w razie potrzeby) z ich opisami XLFD (prawa strona, te długie konstrukcje z wieloma myślnikami). Opisem poszczególnych pól XLFD zajmę się za chwilę. A, jeśli zachodzi potrzeba użycia spacji gdzieś w XLFD (odradzam!) należy cały XLFD ująć w cudzysłów.

Plik fonts.dir można automatycznie wygenerować poleceniem mkfontdir, skanuje ono pliki fontów i na ich podstawie generuje odpowiednie linie XLFD

Drugi plik, fonts.alias to plik aliasów (no tak, można było odgadnąć). Ten plik ma prostą składnię:

-b&h-lucida-bold-r-normal--11-80-75-75-p-66-koi8-r -fiz-shine-bold-r-normal--11-80-75-75-p-66-koi8-r
-b&h-lucida-bold-r-normal--14-100-75-75-p-84-koi8-r -fiz-shine-bold-r-normal--14-100-75-75-p-84-koi8-r
-b&h-lucida-bold-r-normal--17-120-75-75-p-101-koi8-r -fiz-shine-bold-r-normal--17-120-75-75-p-101-koi8-r
-b&h-lucida-bold-r-normal--20-140-75-75-p-118-koi8-r -fiz-shine-bold-r-normal--20-140-75-75-p-118-koi8-r
-b&h-lucida-bold-r-normal--25-180-75-75-p-149-koi8-r -fiz-shine-bold-r-normal--25-180-75-75-p-149-koi8-r
-b&h-lucida-bold-r-normal--26-190-75-75-p-155-koi8-r -fiz-shine-bold-r-normal--26-190-75-75-p-155-koi8-r
-b&h-lucida-bold-r-normal--34-240-75-75-p-202-koi8-r -fiz-shine-bold-r-normal--34-240-75-75-p-202-koi8-r

Nie ma już podanej liczby wpisów, a każda linijka składa się z pary

nowy_XLFD oryginalny_XLFD

gdzie "nowy_XLFD" to alias który ma zostać stworzony, a "oryginalny_XLFD" to jakiś już istniejący XLFD. Tworzy po prostu nową nazwę dzięki której można się odwołać do jakiegoś fontu. Co interesujące, aliasować można fonty zdefiniowane w innym katalogu niż ten z którego pochodzi konkretny fonts.alias. Można zdefiniować katalog fontów który nie dodaje żadnego fizycznego fontu, a jedynie ustawia kilkadziesiąt aliasów. Dla wygody można w tym pliku (ale tylko w tym!) umieszczać komentarze - każda linia rozpoczynająca się wykrzyknikiem to komentarz. Dodatkowo istnieje jeszcze pewna specjalna konstrukcja... umieszczając w pliku fonts.alias ten wiersz

FILE_NAMES_ALIASES

uzyskuje się przydatny czasem efekt - zostaną utworzone aliasy na każdy font z tego katalogu i aliasy te będą identyczne z nazwami plików fontów. Krótko mówiąc: do każdego fontu będzie się można odwołać podając nazwę jego pliku (pozbawioną wszelkich rozszerzeń). FILE_NAMES_ALIASES zadziała tylko dla fontów bitmapowych - skalowalnym trzeba dodatkowo by podać rozmiar (bo domyślnie żadnego nie mają), a alias w postaci pojedynczego słowa (nazwy pliku) nie pozwala już na to.

Trzeci z plików to fonts.scale. Jest on trzymany przy życiu przez zaszłość historyczną, bez zagłębiania się w szczegóły można powiedzieć, że to taki fonts.dir dla fontów skalowalnych. Składnię ma identyczną ze składnią fonts.dir. Co ciekawe, przy udostępnianiu fontów skalowalnych ich wpisy powinny znaleźć się również w pliku fonts.dir, więc fonts.scale jest nieco... dziwne, w dzisiejszych X-ach przynajmniej. W sumie chodziło o to, że najpierw była dana obsługa fontów bitmapowych. Nawet obecnie polecenie mkfontdir nie umie wygenerować wpisów dla fontów skalowalnych, po prostu nie jest w stanie wypruć z nich potrzebnych informacji (pierwsze odmiany fontów skalowalnych często tych informacji po prostu nie zawierały). Te dane administrator musiał samodzielnie poskładać do kupy. Aby jakoś ułatwić sprawę utarło się, że deskrypcje fontów skalowalnych admin umieszcza (ręcznie) w pliku fonts.scale, a mkfontdir skanuje tylko fonty bitmapowe, umieszcza ich opisy w fonts.dir, po czym dokleja do fonts.dir zawartość pliku fonts.scale - który opisuje pozostałe fonty, skalowalne. Plik fonts.scale miał gwarantować, że opisy fontów skalowalnych nie zostaną przypadkiem usunięte - były cenne, bo nie można ich było generować automatycznie.

Taki stan nie trwał długo, pojawiały się nowe typy fontów i narzędzia do ich indeksowania. Swego czasu znany był program ttmkfdir służący do indeksowania plików TrueType, a w nowych dystrybucjach XFree86 standardowo załączone jest jeszcze lepsze polecenie mkfontscale które potrafi poprawnie zindeksować np. fonty Type1 i TrueType. "Zaszłości historyczne" już jednak powstały i nie są usuwane, zwłaszcza że niektóre aplikacje zaczęły na nich polegać. Z tego też powodu mkfontscale nie dodaje fontów wektorowych do fonts.dir, ale do fonts.scale. Dopiero po jego wywołaniu można użyć mkfontdir który stworzy poprawny fonts.dir.

Ostatni plik, encodings.dir, definiuje listę opisów kodowań dla fontów skalowalnych (tylko skalowalnych, bo tylko one zawierają symboliczne nazwy dla każdego ze znaków). Fonty skalowalne których używa się w normalnej pracy mogą być stworzone w różnych kodowaniach - iso8859-1, iso8859-2, utf-8, windows-cp1250 itp. Potrzebna jest jakaś metoda na pogodzenie tego ze sobą, dlatego mechanizmy obsługujące fonty Speedo, Type1 oraz TrueType potrafią "przekodować" font (bez zmieniania fizycznie jego pliku). Po prostu w XLFD podaje się takie kodowanie, jakie chce się mieć udostępnione.
Font pierwotnie może mieć inne kodowanie, ale XFree86 zadba o odpowiednie przekształcenie. To oczywiście nie znaczy, że font iso8859-1 po konwersji do iso8859-2 nagle "dostanie" polskich literek :) Po prostu można użyć np. fontu unikodowego jako iso8859-2, z fontu w windowsowym standardzie "cp" można zrobić poprawne iso8859, a z iso8859-2 stworzyć font unikodowy (w którym oczywiście będzie brakowało mnóstwa znaków, ale te polskie będą na odpowiednich pozycjach).

XFree86 posiada w tym celu wbudowaną bogatą bazę kodowań, od iso8859-1 do iso8859-10, iso8859-15, unikod (iso10646-1), microsoft-symbol, apple-roman, odmiany koi8 i parę innych. Pokrywa to całkowicie potrzeby Polaka, ale na tym nie koniec - dostępne są też inne kodowania, włączane systemem "pluginów". Właśnie za pomocą pliku encodings.dir.

Plik encodings.dir wskazuje na listę plików opisujących zewnętrzne kodowania. Pewien zbiór takich kodowań jest rozprowadzany z XFree86, zawiera on głównie kodowania wymyślone przez Microsoft. Jeśli jakieś kodowanie nie jest znane X-om, to warstwa konwertująca kodowania spróbuje w pliku encodings.dir znaleźć namiary na plik opisujący to "nieznane" dotychczas kodowanie. Ten mechanizm pozwala na łatwe dodawanie obsługi kolejnych kodowań. Sam plik encodings.dir jest tworzony automatycznie przez mkfontdir, gdy przy jego wywołaniu za pomocą opcji -e wskaże się katalog zawierający opisy kodowań. Zwykle nie będzie to potrzebne, bo te najpopularniejsze kodowania są wbudowane. A, plik encodings.dir ma składnię identyczną z fonts.dir - ale to nieważne, bo zwykle nie ma potrzeby jego ręcznego edytowania.

To by zamykało opis budowy katalogu fontów. Teraz trzeba go udostępnić - trzeba tylko dopisać co trzeba do sekcji "Files" w XF86Config:

Section "Files"
RgbPath "/usr/X11R6/lib/X11/rgb"
FontPath "/usr/share/fonts/ISO8859-2/WinFonts/"
FontPath "/usr/share/fonts/ISO8859-2/misc"
FontPath "/usr/share/fonts/FantasyTTF/"
EndSection

Chodzi o te linijki FontPath. Po prostu umieszcza się listę katalogów - przy czym ich kolejność jest ważna, ale o tym później.

X11 XLFD:

Teraz nadszedł czas na XLFD, czyli "X Logical Font Description". Jest to usystematyzowany sposób w jaki X-y odwołują się do fontów. Najłatwiej jest zaprzyjaźnić się z XLFD używając programu xfontsel. Po jego uruchomieniu można zdefiniować sobie jakiś XLFD określając jego poszczególne pola i od razu obejrzeć jaki font jest przez X-y zwracany dla tego konkretnego XLFD. XLFD ma następującą strukturę (że użyję skróconego zapisu z xfontsel):

-fndr-fmly-wght-slant-sWidth-adstyl-pxlsz-ptSz-resx-resy-spc-avgWdth-rgstry-encdng

XLFD rozpoczyna się znakiem minusa, składa się z 14 pól rozdzielanych kolejnymi myślnikami. Każde z pól odpowiada za jakąś cechę fontu.

fndr
to nazwa "odlewni" (foundry) w której powstał font, czyli ogólniej - jej producenta.
fmly
to rodzina fontu. Obiegowo mówi się na to "nazwa fontu".
wght
to "waga" fontu, określa jego "pogrubienie".
slant
steruje pochyleniem fontu. Można tu włączyć kursywę itp.
sWidth
wpływa na względną szerokość fontu. Np. fonty które są"ściśnięte" będą zwykle opisane jako "condensed", fonty bardzo "szerokie" z kolei jako "expanded".
adstyl
jest bardzo rzadko używany, może opisywać dodatkowe cechy fontu, zwykle związane z zawartym w foncie zestawem znaku. Zwykle nie zwraca się na niego uwagi.
pxlsz
To ważne dla użytkownika pole - podaje się w nim wielkość fontu w pikselach.
ptSz
To równie ważne pole - też podaje się w nim rozmiar, ale wyrażony w punktach (różnicę między pikselem a punktem wyjaśnię za chwilę ;)
resx-resy
pola te określają poziomą i pionową rozdzielczość fontu (wyrażoną w DPI). Wiąże się to z pojęciem punktu i piksela i dotyczy tylko fontów bitmapowych.
spc
określa typ fontu w zakresie jego "proporcjonalności" - fonty proporcjonalne mają litery różnej szerokości, np. "i" jest dużo węższe od "w". Fonty nieproporcjonalne mają wszystkie litery stałej szerokości, np. w terminalach używa się tylko takich fontów. Wartość "c" lub "m" oznacza fonty nieproporcjonalne (inne popularne określenie to "monospaced" lub "fixed-width"), "p" to fonty proporcjonalne.
avgWdth
określa "średnią szerokość"... ale jest to pole sporadycznie używane, zwykle do znalezienia fontu używa się tylko jego nazwy i rozmiaru.
rgstry-encdng
opisują kodowanie, np. "iso8859-1".

Mechanizm XLFD polega na tym, że nie każde pole będzie zawsze określone. Część może pozostać niezdefiniowana (będzie posiadać wartość "*"). Aplikacja podaje serwerowi wzorzec fontu ze zdefiniowaną częścią pól, a serwer zaczyna przykładać ten wzorzec do listy dostępnych fontów, sprawdzając każdy po kolei. Zwracany jest pierwszy znaleziony. Poziom "precyzji" zależy już od aplikacji. Może ona zapytać po prostu o font "arial", ale może też zapytać o "arial, prosty, normalna grubość, kodowanie iso8859-2". Albo "font o rozmiarze 14 pikseli". Robi się to pozostawiając niektóre pola niezdefiniowane ("*"), albo nawet skracając cały XLFD. Przykłady:

-monotype-arial-medium-r-*--12-*-*-*-p-*-iso8859-2
-*-arial-*
*-iso8859-2
*-14-*

Jak długo możliwe jest jakieś dopasowanie wzorca, tak długo wszystko jest OK. Tutaj okazuje się, dlaczego kolejność wpisów katalogów w XF86Config jest ważna: po prostu przy dopasowywaniu wzorców lista fontów jest przeszukiwana zgodnie z kolejnością ich definicji, pierwszy podany katalog będzie też pierwszym przeszukiwanym. Jeśli aplikacja prosi o font '*-arial-*' a my mamy dwa takie fonty, jeden iso8859-2 a drugi iso8859-1, to w zależności od tego który font został zdefiniowany pierwszy - ten zostanie dopasowany. Jest to podobne do zmiennej $PATH - katalog który został wymieniony wcześniej będzie miał tym samym pierwszeństwo.

xfontsel jest przydatnym narzędziem, bo pozwala "na żywo" oglądać, jak definiowanie poszczególnych pól ogranicza wybór fontów. Ułatwia też przegląd dostępnych fontów, bo uruchamiając np.

xfontsel -pattern '*-iso8859-2'

można sobie ograniczyć listę fontów do tych z pliterkami, a przy poszukiwaniu polskiego fontu dla xtermów przydatne będzie ograniczenie dodatkowo do fontów fixed-width:

xfontsel -pattern '*-c-*-iso8859-2'
xfontsel -pattern '*-m-*-iso8859-2'

tak że polecam to narzędzie - wygląd ma niepozorny, ale możliwości duże. Uruchamiając je z opcją "-scaled" włącza się tryb skalowania fontów (domyślnie xfontsel raczej unika skalowania)

Interesujące są domyślne XLFD dla fontów skalowalnych - one przecież nie mają domyślnych rozmiarów... I faktycznie, w plikach fonts.dir będą definiowane z wszystkimi rozmiarami ustawionymi na "0". W przypadku fontów skalowalnych gdy aplikacja podaje rozmiar w żądanym XLFD to serwer nie próbuje dopasować rozmiaru, lecz generuje font o tym rozmiarze. Żądanie udostępnienia konkretnego rozmiaru powoduje jego "wyliczenie". W przypadku fontów bitmapowych też może do tego dojść - gdy np. serwer dostał prośbę o font "fixed" w rozmiarze 24 pikseli, ale największy dostępny ma pikseli 17... wtedy dojdzie do skalowania, serwer spróbuje interpolować żądany rozmiar jako wzorców używając tych dostępnych. Co zwykle jest koszmarne. Dlatego XFree86 oferuje możliwość zablokowania skalowania fontów bitmapowych. W razie nieodnalezienia żądanego rozmiaru fontu aplikacja zostanie powiadomiona o niedostępności fontu. Skalowanie blokuje się pojedynczo dla każdego katalogu z fontami, zmieniając nieco wpisy w XF86Config. Pamiętasz ten przykładowy wycinek? Zmieniłem go tak, by fonty z jednego katalogu nie miały prawa do skalowania:

Section "Files"
RgbPath "/usr/X11R6/lib/X11/rgb"
FontPath "/usr/share/fonts/ISO8859-2/WinFonts/"
FontPath "/usr/share/fonts/ISO8859-2/misc:unscaled"
FontPath "/usr/share/fonts/FantasyTTF/"
EndSection

Sztuczka polega na dopisaniu ":unscaled" do nazwy katalogu. Oczywiście nie ma to najmniejszego znaczenia w przypadku fontów skalowalnych, bo te z definicji są dostępne w dowolnej wielkości

Listę wszystkich dostępnych w środowisku fontów można również pobrać poleceniem xlsfonts, fonty skalowalne będą oczywiście wymienione w jednym rozmiarze (0), fonty bitmapowe za to będą wymieniowe w swoich konkretnych, ręcznie rysowanych rozmiarach. Na końcu listy zauważysz fonty o nazwach złożonych z pojedynczego słowa, jak np. "fixed" czy "linux8x16". Nie, to nie jest żaden błąd - te nazwy to w większości aliasy na jakieś konkretne XLFD - aliasy, które mają w udostępnić "uchwyty" do niektórych XLFD wybranych spośród całej masy dostępnych. Np. jeśli używam kilku różnych *termów, a w każdym z nich identycznego fontu, to mogę stworzyć na ten font alias "termfont" a w konfiguracjach aplikacji odwoływać się do tego aliasu. Gdy zechcę zmienić font na jakiś ładniejszy/większy, to wystarczy że zmienię definicję aliasu - konfiguracja każdego z *termów ulegnie automatycznie zmianie.

Kolejna rzecz warta uwagi: polecenie xset. Pozwala ono zmieniać wiele opcji działającego aktualnie XSerwera, w tym także te dotyczące fontów. Lista katalogów jest zapisana w XF86Config, ale za pomocą xset można, na czas trwania sesji X-ów, zmieniać ją. Usuwać katalogi, dodawać nowe, aktualizować je. To naprawdę bardzo wygodne narzędzie. Załóżmy, że pobrałem z sieci kilka fontów TrueType. Teraz chcę je sobie "na szybko" przetestować. Zakładam więc katalog ~/tmpfonts i umieszczam w nim te pliki *.ttf. Potem wchodzę do ~/tmpfonts i uruchamiam mkfontscale i mkfontdir. Mam gotowy katalog z fontami i wygenerowanym automatycznie plikiem fonts.dir. Teraz tylko muszę powiedzieć X-om, żeby dodały zawartość katalogu do swoich zasobów:

xset fp+ $PWD
xset fp rehash

Pierwsze polecenie dokleja do spisu katalogów z fontami także aktualny katalog ($PWD) - należy podawać katalogi w notacji absolutnej, a mi się zwykle nie chce, więc najprościej jest wejść do takiego katalogu i użyć $PWD. Ale doklejenie katalogu do spisu fontów to tylko połowa sukcesu, bo XFree86, ze "względów wydajnościowych", buforuje sobie te dane tuż po starcie serwera. Jeśli dokonam jakiejś zmiany (zmienię któryś fonts.dir, dodam nowy katalog, usunę stary) to muszę kazać X-om na nowo zestawić listę fontów. I to właśnie robi to drugie polecenie. Nie chcę opisywać wszystkich możliwości niesionych przez xset, dość powiedzieć że to narzędzie znacznie ułatwia życie - warto się z nim zaprzyjaźnić. A używanie Zsh bardzo ułatwia pracowanie z nim (inteligentne dopełnianie!)

A, jeszcze coś - jeśli wykonanie pierwszego polecenia, dodającego katalog do spisu, wywoła jakiś błąd to najpewniej winny jest fonts.dir. Po prostu X-y dokonują bardzo prostego sprawdzenia składni i po wykryciu odchyłów powiadamiają o tym. Ale to nie powinno się zdarzać przy fonts.dir generowanym automatycznie.

Ale wróćmy do tematu - te moje fonty ściągnięte z sieci. Po tych operacjach powinienem już móc uruchomić xfontsel i znaleźć tam nowe wpisy. Jeśli tak, to mogę ~/tmpfonts przesunąć w jakieś bardziej "globalne" miejsce i dodać jego wpis na stałe do XFree86, a wtedy będę miał te fonty dostępne przy każdym uruchomieniu XFree86. Proste, prawda? Założyć katalog dla fontów, wrzucić je tam, uruchomić w katalogu mkfontscale i mkfontdir, dodać wpis katalogu do XF86Config, zrestartować XSerwer (lub użyć xset).

DPI:

A teraz powrócę do obiecanego wyjaśnienia różnicy pomiędzy rozmiarem w pikselach a rozmiarem w punktach. Wiąże się z tym również pojęcie DPI. Jak wiadomo, karty graficzne pracują w określonych trybach, np. 1024x768. Mądrość ludowa zwie to "rozdzielczością". Rozdzielczość wyrażana w ten sposób nic jednak nie mówi o faktycznych, fizycznych wymiarach - np. mówiąc o "1024x768" nie wiadomo ile centymetrów długości będzie miała linia o długości 100 pikseli. Po prostu nie wiadomo, jakie wymiary ma pojedynczy piksel, jak gęsto piksele są upakowane. Obraz komputerowy staje się "nieprzenośny", bo w zależności od monitora będzie inaczej przeskalowany. I tutaj do gry wchodzi drugi sposób określania rozdzielczości - właśnie DPI. DPI określa "gęstość" upakowania pikseli (lub ogólniej - punktów) jakiegoś medium. Samo słowo DPI rozwija się w "Dots Per Inch". Wspomagając się DPI można "zmaterializować" abstrakcyjny tryb karty graficznej w fizyczne, możliwe do zmierzenia linijką wielkości. W zależności od wielkości monitora i wybranego trybu graficznego zmieniają się wartości DPI. Jak obliczyć DPI? Wystarczy wziąć fizyczne wymiary ekranu (obszaru, na którym jest wyświetlany obraz, bez marginesów), przekształcić je ew. na cale, a następnie podzielić liczbę pikseli w poziomie/pionie przez wymierzone długości w calach. Otrzyma się wtedy DPI monitora. Okazuje się szybko, że monitory komputerowe mają koszmarnie niskie DPI - pałętające się zwykle pomiędzy 80-110dpi. Wystarczy szybko porównać to z drukarkami - w dzisiejszych czasach normą są drukarki oferujące 600, 1200, a nawet więcej dpi (choć akurat te skrajnie wysokie wartości to akurat blef, fatamorgana, złudzenie optyczne uzyskiwane poprzez retusz obrazu, a nie podniesienie dokładności wydruku)
Ale do rzeczy - monitor ma określone DPI. Bardzo fajnie, tylko co z tego? Ano, pozwala to na pewną przenośność obrazu (w tym i tekstu) między urządzeniami. Jest to szczególnie ważne w DTP, gdzie kartka papieru przedstawiona na monitorze powinna mieć identyczne wymiary i proporcje co kartka po wydrukowaniu. Używa się tego też w fontach. Zamiast określać wielkość i proporcje tekstu za pomocą pikseli które mają wszędzie różne wymiary i proporcje używa się jednolitej, "ufizycznionej" miary - punktu. Punkt (point) to miara drukarska o ściśle określonych wymiarach - 1/72 cala. I teraz cała układanka zaczyna się układać - określając wielkość fontu w punktach określa się jego wielkość niezależnie od wielkości kineskopu czy trybu pracy karty graficznej, jest to jak "daj mi tu font o wysokości 12mm". A jest to możliwe dzięki wyliczeniu DPI konkretnego urządzenia - znając aktualne DPI wiadomo, ile pikseli jest upakowanych w jednym calu. Wiedząc ile pikseli jest w calu można wyliczyć przelicznik pomiędzy pikselami a punktami. Font o wielkości określonej w punktach będzie na kineskopie zajmował zawsze tyle samo przestrzeni, obojętnie czy w rozdzielczości 1024x768, czy w 640x480. Nie będzie też zależny od wielkości ekranu. Zakładając, że XSerwer będzie zawsze wiedział jakie jest aktualne DPI monitora - tylko wtedy punkt na ekranie i na kartce papieru zachowa wymiary 1/72 cala.

To by wyjaśniało różnicę pomiędzy pikselem a punktem. Wyjaśniłem też od razu owo tajemnicze "dpi". Bo do dpi chcę jeszcze raz wrócić: standardowo z X-ami rozpowszechniane są dwa katalogi fontów bitmapowych o nazwach "100dpi" oraz "75dpi". Teraz już powinno być jasne, że to generalnie te same zestawy fontów, tylko zawierające mapowania skalujące przeznaczone odpowiednio dla ekranów o dpi zbliżonym do 75 lub 100.

Ale skoro już tu jestem, to pozostanę jeszcze przez chwilkę: DPI w XFree86. Jak odczytać aktualne wartości DPI? Można albo zajrzeć do logów XFree86 w /var/log/, albo użyć polecenia xdpyinfo które, pośród wielu informacji o ekranach, będzie też zawierało stosowną informację o "resolution" ekranu.
To by było o odczytywaniu DPI, ale jak ono jest ustalane? Cóż, standardową wartością X-ów jest 75dpi, ale jeśli dysponujemy względnie współczesnym monitorem/kartą graficzną, to poprzez kanał komunikacyjny DDC nasz XSerwer może zapytać monitor o jego fizyczne wymiary (pod Windows DDC określa się zbiorczym mianem "plug'n'play"). Monitor ma w elektronice zakodowane wymiary swojego obszaru widzialnego w milimetrach i przesyła te dane XSerwerowi. XSerwer wie z kolei w jakim trybie graficznym pracuje, więc łącząc te dane może automatycznie wyliczyć aktualne DPI monitora (cały czas akcentuję tutaj DPI słowem "aktualne", bo wystarczy zmienić tryb pracy karty graficznej i DPI automatycznie się zmieni). DPI można też ustalić na sztywno, używając opcji -dpi XSerwera, np.

start -- -dpi 100

wymusi odgórnie "okrągłe" DPI 100x100. A jeśli monitor nie wspiera DDC, to można wymierzyć samodzielnie wielkość obszaru widzialnego na kineskopie i podać ją w XF86Config, w sekcji "Monitor" dyrektywą DisplaySize:

DisplaySize x y

gdzie za x i y trzeba podstawić szerokość i wysokość obszaru widzialnego, w milimetrach (uff, odpada męczące przeliczanie na cale). Z tego co mi donoszą różni ludzie, to niektóre monitory kłamią przy podawaniu wielkości swojego obszaru widzialnego, więc czasem warto podać ręcznie własne, prawidłowe wymiary nawet gdy monitor obsługuje DDC.

XFree86 Xft:

We współczesnych X-ach raźno sobie poczyna mechanizm Xft. Xft to nowa warstwa która renderuje fonty wygładzając je przy okazji. Używa przy tym (jeśli to możliwe) rozszerzenia XRender, co znaczy że wiele przekształceń jest robionych "sprzętowo" przez elektronikę karty graficznej. Obecnie mamy już drugą generację Xft (zwaną też Xft2), Xft1 wypada z obiegu. Wszędzie gdzie będę mówił o Xft mam na myśli właśnie Xft2 - skoro właśnie ta wersja jest aktualnie rozpowszechniana z XFree86, więc można ją uznać za domyślną. I tak zresztą jest.

Xft jest interesującym uaktualnieniem X-ów. Po pierwsze, dodaje wydajny mechanizm antyaliasingu dla fontów (antyaliasing polega na wyrównywaniu krawędzi obrazu, zwłaszcza w kontrastowych obszarach - przez dodanie pikseli o kolorach przejściowych - w rezultacie obraz wygląda "gładziej", choć łatwo o przesadę i rozmycie). Po drugie, ma niezależne źródło fontów - nie korzysta z fontów udostępnianych bezpośrednio przez XSerwer, ale samodzielnie się do nich dobiera. Po trzecie, odchodzi od schematu XLFD przy opisywaniu fontów. Całkiem dużo różnic, prawda? Ponieważ Xft jest obecnie całkiem mocno wspierany (to właśnie dzięki niemu toolkity gtk+ oraz Qt, a więc i środowiska Gnome/KDE, mogą oferować antyaliasowane fonty) warto jest mu się przyjrzeć. Najprościej będzie przyjrzeć się dokładnie różnicom w stosunku do "core X fonts".

Xft dodaje antyaliasing. Tutaj nie będę się wypowiadał, są jego gorący zwolennicy jak i przeciwnicy. Antyaliasing jest opcją w Xft. Opcją domyślnie załączoną, ale mimo wszystko można z niego zrezygnować. Oprócz tego Xft dodał wsparcie dla "sub-pixel rendering" - w skrócie polega to na tym, że można określić kolejność plamek RGB w pikselach naszego monitora, a może to być użyte właśnie do sterowania ich natężeniem i uzyskanie lepszego wygładzania bazującego na ścieraniu się składowych RGB przy krawędziach pikseli. Przydatne zwłaszcza na ekranach LCD, które mają plamki składowych ułożone inaczej niż monitory CRT.

Xft uniezależnia się od tradycyjnego źródła fontów i kładzie akcent na fonty skalowalne, a nie bitmapy. To pozwala na znaczne uproszczenie całego procesu obsługi, z punktu widzenia użytkownika przynajmniej. Po pierwsze, "katalogi fontów" to w ujęciu Xft tylko katalogi z plikami fontów. Pliki fonts.dir itp. nie są tu potrzebne. Po drugie, Xft co jakiś czas (co ileś-tam sekund) sprawdza katalogi które ma "we władaniu" wyszukując zmian - dodania fontów, usunięcia itp. To przekłada się na wygodę użytkownika - wystarczy wrzucić kolejny font do katalogu a po chwili będzie on dostępny w systemie. Po trzecie jest z góry zaprojektowany do konfigurowania przez użytkownika. Istnieje globalny plik konfiguracyjny Xft, ale każdy użytkownik może mieć w swoim katalogu domowym swoją własną konfigurację, włączającą np. jego prywatny zbiór fontów i zmieniającą ustawienia antyaliasingu.

Xft odszedł też od opisów XLFD wprowadzając własną, bardziej elastyczną strukturę która jest bardziej elastyczna w wyszukiwaniu fontów. W zasadzie to cały mechanizm wyszukiwania i dopasowywania fontów został zepchnięty na zewnętrzne biblioteki - na fontconfig. To fontconfig zajmuje się zarządzaniem plikami z fontami, Xft je tylko renderuje.

A jakie są różnice w administracji? Hmm. Główny plik konfiguracyjny to /etc/fonts/fonts.conf. Technicznie rzecz biorąc jest to plik XML, prosty w edycji. Wystarczy po prostu w okolicach już indeksowanych tam katalogów z fontami dopisać te nasze i po sprawie. Dopisywać warto tylko fonty skalowalne, bitmapowe i tak będą ignorowane. Katalogi które tam załączamy mogą być jak najbardziej współdzielone z tymi "głównymi" XFree86 (te same, co w XF86Config). Xft nie potrzebuje już plików fonts.dir itp., ale nie będą mu one też przeszkadzać, więc mogą sobie leżeć. Standardowo Xft próbuje też używać fontów z katalogu ~/.fonts oraz odczytywać plik konfiguracyjny ~/.fonts.conf (plik ten ma identyczną budowę, co "główny" /etc/fonts/fonts.conf). Z punktu widzenia użytkownika można wziąć garść różnych fontów i wrzucić je do ~/.fonts. I koniec, nic więcej robić nie trzeba. Potem użytkownik może tam dorzucać kolejne fonty lub usuwać stare, jego sprawa - Xft sobie z tym poradzi.

fontconfig wprowadza dwa przydatne polecenia. Jedno to fc-list, które pokaże listę dostępnych poprzez Xft fontów (podobne do xlsfonts, prawda?), a drugie to fc-cache, który skanuje katalogi z fontami i tworzy tam pliki cache, które potem drastycznie przyspieszają odczytywanie informacji o fontach.

Mimo iż samo dodanie fontów do Xft jest bardzo proste nie znaczy to, że jest to mechanizm prymitywny, o nie. Lektura "man 5 fonts-conf" pokazuje, jakie możliwości tkwią w plikach konfiguracyjnych. Nie jest to lekka lektura i najlepiej czytać to równolegle z domyślnymi plikami konfiguracyjnymi. Na szczęście mało kto będzie musiał zmieniać te konfigi na tak zaawansowanym poziomie. Większość użytkowników zadowoli się włączeniem swoich zbiorów fontów TrueType i Type 1, po czym po prostu zacznie tego używać.

Aplikacje:

I na zakończenie może ogólne informacje o poszczególnych programach:

OpenOffice.org
Chcę zaznaczyć, że nie jest konieczne dodawanie fontów poprzez program spadmin. W środowisku XFree86-4.x, po dodaniu zestawu fontów do fontów podstawowych jak i do mechanizmu Xft cały pakiet OpenOffice.org zawsze mi te fonty "widział" bez potrzeby "instalowania" ich prywatnie w katalogach OpenOffice.org. Oczywiście ktoś może chcieć udostępnić część fontów wyłącznie w pakiecie OpenOffice.org, ale myślę że większości użytkowników zależy na czymś odwrotnym - mają zestaw fontów "ogólnoiksowych" i chcą, by OpenOffice je też zobaczył.
gtk+-1.x
Nie jest dostępne wygładzanie fontów. Po prostu gtk+-1.x nie korzysta z tego. Nie korzysta z Xft. Istnieje co prawda specjalna modyfikacja biblioteki gdk, gdk-xft, można albo kompilować z nią aplikacje albo używać jako biblioteki typu "preloaded" - niestety efekty są brzydkie, wydajność koszmarnie niska, a na domiar złego nie ma obsługi iso8859-2. Więc odpada.
gtk+-2.x
Biblioteka wspiera standardowo antyaliasing używając Xft. Wygładzaniem można sterować za pomocą zmiennej środowiskowej $GDK_USE_XFT. Przypisując jej wartość "1" wymusza się włączenie antyaliasingu, przypisując "0" wymusza się jego wyłączenie. Czyli można tym sterować osobno dla każdej aplikacji, choć zwykle chodzi raczej o ogólnosystemowe ustawienie. Więc wyeksportowanie tej zmiennej w swoim ~/.Xclients lub globalnie w /etc/X11/xinit/xinitrc powinno być wyjściem.
Qt
Praktycznie dopiero wersja 3.x wspiera sensownie antyaliasing, ale wersja 2.x już wymarła, więc wszystko jest chyba OK. Antyaliasing można włączać/wyłączać za pomocą zmiennej środowiskowej, podobnie jak w przypadku gtk+-2.x, ale nie pamiętam już nazwy zmiennej (i nie używam Qt), poza tym zdaje się że owa opcja może być i tak przeforsowana przez aplikację, więc nie ma takiego znaczenia jak w gtk+.
Opera
Używa Qt, więc oferuje bardzo przyjemny antyaliasing. Obsługa fontów jest wykonywana przez funkcje Qt, które z kolei korzysta z Xft2/Xft1 (w zależności które znajdzie w systemie), więc chcąc udostępnić fonty w Operze należy je udostępnić poprzez Xft.
Firefox, Thunderbird i ogólnie całe Mozilla Suite/Gecko
Obecnie używa Xft2 (tylko Xft2, wsparcie dla Xft1 nigdy nie było w pełni zrobione). Alternatywnie możliwe jest używanie bezpośrednio libfreetype, rozwiązanie to polegało na dokonywaniu charakterystycznych zmian w pliku unix.js Mozilli. I odradzam, gdyż ten antyaliasing jest powolny i strasznie "gruby" (przetłuszczone fonty). Zalecaną metodą jest antyaliasing przez Xft2. Udostępnianie fontów sprowadza się więc do włączenia ich poprzez Xft.
Emulatory terminali
Emulatory skojarzone na stałe ze środowiskami KDE/Gnome korzystają z ich możliwości, czyli standardowo z gtk+-2.x oraz Qt-3.x, a więc używają Xft i oferują antyaliasing. Pozostałe *termy (rxvt, aterm itp.) będą pozbawione wygładzania a fonty będą pobierać w "klasyczny" sposób (X Core Fonts). Pewnym wyjątkiem jest xterm, który można skompilować z obsługą Xft - daje to oczywiście antyaliasing, ale wtedy raczej trzeba przestawić się na pracę w unikodzie, choć nie jest to już konieczne. Antyaliasing w emulatorach terminali może być jednak wątpliwym "ulepszeniem" - jeśli terminal używa małych fontów, to zapewne będą one lepiej (wyraźniej) wyglądać bez wygładzania.
Gimp
Wersje 1.x używają gtk1, a więc X Core Fonts. Wersje 2.x używają gtk2, czyli Xft.
Pozostałe aplikacje i pomniejsze toolkity
Cała ta reszta raczej korzysta z X Core Fonts.