C dla każdego (cz. 8.)
Czcionki
Tym razem omówimy podstawy posługiwania się różnymi rodzajami kroju pisma.
Czym jest wynalazek Gutenberga, tłumaczyć nie trzeba. W wypadku Amigi czcionki
należałoby podzielić
ze względu na pochodzenie, czyli pamięć stałą bądź masową. Do chwili obecnej w ROM-ie znajduje się
tylko jedna rodzina fontów, o nazwie "topaz". Pozostałe czcionki umieszcza się zazwyczaj w
katalogu "FONTS:". Podstawowoą informacją o czcionce jest jej wielkość.
Przyjęto, że podaje się wysokość w punktach oraz atrybuty, takie jak pogrubienie, pochylenie,
zwane kursywą, oraz podkreślenie.
W dawnych czasach wszystkie czcionki Amigi były zapisane w postaci plików, opisujących punkt po
punkcie daną literę. Plików było tyle, ile dostępnych rozmiarów danej czcionki. Pliki te
umieszcza się w podkatalogu o nazwie takiej, jak nazwa kroju. Oprócz tego istnieją też pliki
z rozszerzeniem "font", które zawierają pełne informacje o kroju (dostępne wielkości itp).
Tego typu czcionki nazywane są bitmapowymi, ich niewątpliwą zaletą jest to, że szybko się
je otwiera. Obecnie możliwe jest również zastosowanie czcionek wektorowych. W ich wypadku
zapisane są jedynie kontury liter, na których podstawie generuje się poszczególne wielkości.
Taka organizacja pozwala zmieniać wielkość i proporcje bez utraty jakości, jednak wymaga
czasochłonnych obliczeń (ale możliwe jest stworzenie i zapisanie czcionek bitmapowych
na podstawie wektorowych danych). System 2.0 pozwala skalować zarówno czcionki wektorowe,
jak i bitmapowe, jednak jakość tych ostatnich pozostawia nieco do życzenia.
Obsługą czcionek zajmuje się biblioteka graficzna oraz "diskfont.library", która jest
odpowiedzialna za czcionki dyskowe. Czcionki otwiera się za pomocą funkcji:
struct TextFont *OpenFont(struct TextAttr *textAttr); - z "graphics.library"
struct TextFont *OpenDiskFont(struct TextAttr *textAttr); - z "diskfont.library"
Funkcje te udostępniają nam czcionkę. Pierwsza może otworzyć jedynie czcionki znajdujące
się już w pamięci, druga natomiast doskonale radzi sobie zarówno z czcionkami
znajdującymi się na dysku, jak i w pamięci. Argumentem tych funkcji jest struktura
opisująca: "TextAttr" lub "TTextAttr" - druga pojawiła się w OS 2.04 i jest
rozszerzona o pole "tta_Tags" będące wskaźnikiem na tablicę struktur "TagItem".
struct TextAttr
{
STRPTR tta_Name;
UWORD ttaYsize;
UBYTE ttaStyle;
UBYTE ttaFlags;
struct TagItem *ttaTags;
};
Aby poinformować system, że używamy rozszerzonej struktury, należy ustawić w polu
"ttaStyle" flagę "FSF_TAGGED". Wspomniane pole zawiera również opis stylu czcionki,
którą chcemy otworzyć:
FS_NORMAL - brak udziwnień,
FSF_BOLD - pogrubienie,
FSF_ITALIC - kursywa,
FSF_UNDERLINE - podkreślenie.
Pole "tta_Name" zawiera pełną nazwę czcionki (z przyrostkiem "font"). Wysokość czcionki
jest zapisana w polu "tta_Size", w polu zaś "tta_Flags" umieszcza się następujące flagi:
FPF_ROMFONT - czcionka z ROM-U (topaz 8 lub 9).
FPF_DISKFONT - czcionka z dysku.
FPF_DESIGNED - ustawienie tej flagi powoduje, że zostaje zablokowana
możliwość generowania brakujących rozmiarów. Używa się jej. gdy nie chcemy, aby biblioteka
Disk Font "wydumała" brakujący rozmiar czcionki bitmapowej, jako że rezultaty bywają
niezbyt piękne.
Starsza wersja struktury ma cztery pierwsze pola, różnica polega również na braku
pierwszego "t" w nazwie pól.
W wypadku nowej struktury w polu "tta_Flags" umieszczamy wskaźnik na tablice "tagów",
w której można umieścić tag "TA_DeviceDPI".
Za jego pomocą zmienia się stosunek szerokości do wysokości czcionki. Dzięki zastosowaniu
"TA_DeviceDPI" można panować nad szerokością czcionek o jednakowej wysokości.
Po przydługawym omówieniu parametrów przejdźmy do rezultatów funkcji - obie zwracają
wskaźnik na strukturę "TextFont" (patrz "graphics/text.h). Pola "tf_YSize", "tf_XSize" tej
struktury zawierają wymiary czcionki, przy czym "tf_XSize" jest uśrednione w wypadku
czcionek proporcjonalnych, to znaczy takich w których litery mają różną szerokość
("W" jest szersze niż "i"). Aby odróżnić czcionki proporcjonalne od tych o stałej
szerokości (ang. fixed width), należy zbadać czy w polu "tf_Flags" otrzymanej struktury
jest ustawiena flaga "FPF_PROPORTIONAL". Kolejną przydatną informacją jest pole "tf_Baseline",
które zawiera wysokość w punktach od szczytu czcionki do linii bazowej, czyli miejsca,
poza które wystają w dół jedynie ogonki z liter takich jak: 'j', 'y', jak również
naszych narodowych "ogonkowców". Przykład w poprzednim odcinku drukował napisy na
nieco dziwnej wysokości - zarówno powyżej, jak i poniżej kursora graficznego. Na
wysokości kursora położona była właśnie linia bazowa.
Po otwarciu czcionki otrzymujemy wskaźnik na strukturę "TextFont". Aby zacząć pisać,
należy tę strukturę "podłączyć" do RastPortu za pomocą funkcji biblioteki graficznej:
void SetFont(struct RastPort *rp, struct TextFont *textFont);
Argumentami są wskaźniki na RastPort i strukturę "TextFont". Po przydzieleniu
czcionki do RastPortu możemy korzystać z niej za pomocą funkcji Text().
Uaktualniane są również pola RastPortu, opisujące czcionkę: "TxFlags",
"TxWidth", "TxHeight", "TxBaseline" oraz "AlgoStyle" (o tym wkrótce). Nie
musimy się przejmować przywracaniem poprzedniej czcionki ani wartości pól
RastPortu przed zamknięciem okna - system nie zwraca na nie najmniejszej uwagi.
A skoro jesteśmy już przy zamykaniu, to po zakończeniu współpracy z czcionką należy
poinformować o tym system za pomocą funkcji pochodzącej z biblioteki graficznej:
void CloseFont(struct TextFont *textFont);
Jedynym jej argumentem jest wskaźnik na czcionkę, czyli to, co zwróciła funkcja OpenFont() lub
OpenDiskFont().
Przepraszamy Czytelników za ciągłe opóźnienia oraz dzielenie na części w sposób często niezbyt
elegancki i niezgodny z treścią artykułów. Jest to spowodowane naszym "gadulstwem", które zmusiło
redakcję do podzielenia niektórych części. Przykro nam, że przykład zobaczycie dopiero za miesiąc,
jdenak przdstawione dziś infromacje powinny wystarczyć do pierwszych samodzielnych eksperymentów.