Własne czcionki w trybach graficznych





      W Lekcji 11 swojego podręcznika grafiki Bob Seguin opisuje, jak stworzyć własnš czcionkę w trybie graficznym (lub zaimportować jš z Windows) przy pomocy map bitowych, a potem zastosować w programie używajšc poleceń BLOAD, GET i PUT. Jest to technika uniwersalna, ale doœć skomplikowana. Na pewno jest niezastšpiona przy czcionkach ozdobnych i o dużych rozmiarach, np.

Czcionka Berliner 48 Pt

(http://www.newfonts.net/index.php?pa=show_font&id=32).

Znalazłem jednak na sposób - moim zdaniem - prostszy, przydatny wtedy gdy linie tworzšce litery majš gruboœć tylko jednego piksela, jak w czcionce Boba GOTHIC przeznaczonej dla SCREEN 13 (gdzie DOS-owskie napisy sš o wiele za duże) lub Microsoft Sans Serif 8 używanej w menu Windows. Do rysowania takich napisów wykorzystałem polecenie DRAW.

Kliknij aby powiększyć

Bob wraz z programem QBASICS.BAS dostarcza pliki czcionek, które opracował, do swobodnego wykorzystania w programach freeware. Obejmujš one jednak tylko alfabet łaciński - zakres ASCII od 32 do 126, nie ma tam naszych polskich "ogonków", które wszystkie znajdujš się w rozszerzonym zestawie ASCII, powyżej 127. Mój zestaw sięga aż do ASCII 228 (ń), pomijajšc znaki nieużywane, których (puste) miejsca w tablicy można jeszcze wykorzystać na własne symbole.

Najłatwiejszy do odwzorowania przy pomocy DRAW jest

w którym litery sš w większoœci tworzone z linii prostych. Jak widać powyżej, daje się uzyskać także cieniowanie, podobnie jak w czcionce uzyskanej z bitmapy.

      W programie, który ma wykorzystywać czcionkę rysowanš przez DRAW, deklarujemy tablicę tekstowš o indeksach od 32 do kodu najdalszego znaku z rozszerzonego zestawu ASCII, w tym przypadku ń = 228. Tablicę tš wypełniamy następnie łańcuchami komend dla DRAW, rysujšcymi kolejne litery. Łańcuchy te można załadować z zewnętrznego pliku (jak u Boba) albo umieœcić w samym programie w liniach DATA.

Tekst do wypisania przypisujemy zmiennej łańcuchowej, która potem jest analizowana znak po znaku. Na podstawie odczytanych kodów ASCII kolejnych liter tekstu pobierane sš z tablicy łańcuchy rysujace litery i łšczone w jeden długi łańcuch dla pojedynczego polecenia DRAW, które narysuje od razu cały wiersz tekstu. Jeżeli wykonujemy więcej niż jeden napis, to kod analizujšcy i drukujšcy tekst umieszczamy w podprogramie lub procedurze SUB.


'Tablica dla łańcuchów rysujšcych znaki o kodach 32 - 228
DIM Chars$(32 TO 228)

' Jeżeli łańcuchy dla czcionki znajdujš się
' w zewnętrznym pliku, to:
'Otwarcie pliku zawierajšcego zapisane kody i łańcuchy
' OPEN "gothic.txt" FOR INPUT AS #1

'Pętla wypełniajšca tablicę Chars$()
' DO
'  INPUT #1, indeks, a$, lancuch$
'  Chars$(indeks) = lancuch$
' LOOP UNTIL EOF(1)
'CLOSE

'Jeżeli (jak tutaj) dane umieszczone sš w liniach DATA, to:

'Pętla wypełniajšca tablicę Chars$()
 RESTORE Gothic                   'wskazanie DATA dla czcionki
                                  ' (gdy mamy ich kilka, np.
                                  ' GOTHIC i MS Sans Serif)
 DO
  READ indeks, a$, lancuch$
  IF indeks = -1 THEN EXIT DO     'wyjdŸ z pętli, gdy nie ma
                                  ' więcej DATA
  Chars$(indeks) = lancuch$       'zapisz łańcuch odpowiednio
                                  ' do tablicy
 LOOP

'(Gdy mamy wiecej czcionek i używamy ich na zmianę, to tš pętlę
'też umieœcimy w podprogramie/procedurze.)

SCREEN 13

'Przykładowy tekst do wydrukowania:
Zrodlo$ = "Ten napis został wykonany poleceniami DRAW..."

DRAW "c7"        ' kolor pisma 7 - jasnoszary 
DRAW "bm23,20"   ' poczštek pisma x=23; linia bazowa pisma y=20 
GOSUB Drukuj

END

' --------------------- podprogram rysujšcy napis ----------- 

Drukuj:
 prt$ = ""          ' usunięcie łańcuchów poprzedniego napisu
'Pętla przypisujšca kolejnym znakom Zrodlo$ łańcuchy rysujšce 
 FOR i = 1 TO LEN(Zrodlo$)
  indeks = ASC(MID$(Zrodlo$, i))
  prt$ = prt$ + Chars$(indeks)
 NEXT i
 DRAW prt$          ' rysuje napis 
RETURN

Gothic: 
' ---- dane (kody i łańcuchy) dla czcionki GOTHIC -----

' ASCII, znak, łańcuch dla DRAW 

DATA 32, spacja, br3
DATA 33, !, brrbu2u4ld2bd4br2
DATA 34, cudzysłów, brbu5ubr2dbd5br
DATA 35, #, ber4bu2l4ed4br2u4d4br2
DATA 36, $, berduru2l2u2rudrbd5br
DATA 37, %, bre3ue2g2u2lgdrfdr2dglubr3bd

 .  .  .  .  .  .  .
DATA 126, ~, brbu6r2bd6br
DATA 134, ć, br3udl2u4rudrdbd3br

 .  .  .  .  .  .  .
DATA 228, ń, bru4rudrd4br
DATA -1, -1, -1

MSSansSerif8: 
' -- dane (kody i łańcuchy) dla czcionki MS Sans Serif 8 --
 .  .  .  .  .  .  .

Zwróćmy uwagę na następujšce rzeczy:

1. Blok DATA kończy się zawsze liniš DATA -1, -1, -1 - sygnalizuje ona koniec danych. Sygnałem jest tylko pierwsze -1, pozostałe sš tu dlatego że jedno READ wczytuje trzy dane na raz: liczbę i dwa łańcuchy.

2. Danych w linii mogłoby być tylko dwie, a nie trzy, bowiem druga - znak lub jego opis - jest tylko po to, aby program był czytelny dla człowieka: gdyby trzeba było jakšœ literę zmodyfikować, to łatwo jš znaleŸć. READ wczytuje drugš danš do zmiennej a$ i zmienna ta do niczego więcej nie służy. Można jš spokojnie pominšć, ale wtedy trzeba też usunšć drugš danš z wszystkich linii DATA. Chyba najlepiej robić to po nadaniu programowi ostatecznej formy.

3. Powyżej 126 pierwsze dane w DATA - kody ASCII znaków - nie sš już kolejnymi liczbami; umieszczamy dane tylko dla tych znaków, które będziemy wykorzystywać, tu - polskie "ogonki". W tablicy Chars$ komórki odpowiadajšce pominiętym znakom pozostanš po prostu puste.

4. Czcionki graficzne sš proporcjonalne, w GOTHIC np. majš szerokoœć od 1 do 5 pikseli; jeœli użyć jš jako drobnš czcionkę dla SCREEN 12, to w wierszu zmieœci się znacznie wiecej niż 80 znaków.
Tymczasem zmienna Zrodlo$ przechowujšca tekst do wydrukowania ma - znowu dla czytelnoœci - nazwę dosyć długš, która w przypadku łšczenia łańcuchów:

Zrodlo$ = Zrodlo$ + "reszta łańcucha do wypisania"
podczas pisania zajmuje znaczšcš częœć widocznego ekranu. Przy pisaniu programu warto jš więc nazwać jednym znakiem, np. z$.

5. Jeżeli w jednym programie używamy kilku różnych czcionek, to nie zawsze musimy przechowywać w DATA wszystkie znaki. Np. piszemy czcionkš MS Sans Serif, ale w którymœ miejscu trzeba opisać wykres cyframi z małej czcionki Garamond. Wystarczy wtedy, gdy w DATA pod etykietš Garamond: znajdš się tylko cyfry czyli kody od 48 do 57 i wiersz kończšcy z -1, -1, -1. Wskazanie podprogramowi wypełniajšcemu tablicę tego adresu (RESTORE Garamond) spowoduje nadpisanie komórek 48 do 57 danymi dla Garamond. Za to aby przywrócić cyfry MS Sans Serif, najwygodniej będzie nadpisać całš tablicę (RESTORE MSSansSerif8).

      Przy wypisywaniu tekstu pewne komendy DRAW używa się tylko raz, a inne - kiedy tekst zajmuje więcej niż jeden wiersz, powtarzajš się wielokrotnie.
  Jeżeli kolor napisu ma być inny niż ostatnio używany, definiujemy go przez "Cn", np. DRAW "c7" - jasnoszary, liczba to numer koloru, litera duża czy mała - jak zwykle w DRAW, nie robi różnicy.
  Jeżeli wykorzystujemy skalowanie (zob. niżej), dochodzi jeszcze komenda skali "Sn", np. DRAW "s8" - dwukrotnie większe. Obydwie komendy można połšczyć w jednym poleceniu: DRAW "c7s8".
     Następne czynnoœci będš się już powtarzać cyklicznie:
Przypisujemy tekst wydruku do zmiennej Zrodlo$.
Ustalamy miejsce poczštku napisu, np. DRAW "bm23,20"
. B (od Blind - œlepy) powoduje wykonanie następujšcej po nim czynnoœci bez rysowania. M (od Move - przesuń) przesuwa kursor graficzny w położenie x/y okreœlone bezpoœrednio po nim, tu: x=23, y=20. Całoœć - przesuwa kursor bez rysowania w to położenie i odpowiada tekstowemu poleceniu LOCATE x,y.
  GOSUB Drukuj - wywołujemy podprogram, który rysuje napis. I teraz znowu:
  Zrodlo$ = "kolejny wiersz napisu"
  DRAW "bm23,40"
(wiersz o 20 pikseli niżej)
  GOSUB Drukuj

Podprogram Drukuj najpierw usuwa poprzedni łańcuch ze zmiennej prt$:
  prt$= ""
Następnie w pętli FOR i = 1 TO LEN(Zrodlo$) odczytuje kod ASCII każdej kolejnej litery ze Zrodlo$, a zawartoœć komórki tablicy Chars$ o indeksie takim samym jak ten kod - czyli łańcuch rysujšcy taki znak - "dokleja" do prt$: prt$ = prt$ + Chars$(indeks), tworzšc w ten sposób parametry polecenia rysujšcego od razu cały wiersz:
  DRAW prt$

      Jeżeli pokusimy się o wydrukowanie w ten sposób dłuższego tekstu, trzeba pamiętać że DRAW, tak jak i inne polecenia rysujšce, za nic sobie ma krawędzie ekranu i tekst-rysunek, który się na nim nie zmieœci, zostanie zwyczajnie obcięty bez zgłaszania żadnego błędu. Trzeba więc co kawałek sprawdzać rezultaty i odpowiednio korygować zawartoœć zmiennej Zrodlo$.

      Cieniowanie, jak w napisie uzyskuje się przez dwukrotne wyrysowanie tego samego napisu odmiennymi kolorami i z przesunięciem. Najpierw rysujemy napis, który będzie cieniem - i ten zostaje zwykle przesunięty o 1 lub więcej pikseli w prawo i w dół, a następnie - właœciwy napis. To drugie rysowanie nie potrzebuje już analizowania zmiennej Zrodlo$; w prt$ znajduje się wszystko, co trzeba. Wystarczy więc w głównym programie powtórzyć DRAW prt$ zamiast GOSUB Drukuj:

DRAW "bm24,21c4"   'położenie i kolor razem 
Zrodlo$ = "GOTHIC Boba"
GOSUB Drukuj
DRAW "bm23,20c12"
DRAW prt$
lub nawet DRAW "bm23,20c12" + prt$





Eksperymenty z tymi czcionkami widać na ekranach powyżej. Czcionki rysowane można mieszać z wydrukiem uzyskanym ze zwykłego PRINT, ale wtedy PRINT trzeba wykonać jako pierwsze. PRINT w trybach 12 i 13 zawsze drukuje na tle w kolorze 0 - także spację, taki napis potrafi więc przykryć sobš rysunek. ("Spacja" w DRAW to po prostu "br3" albo "br8" czyli przesunięcie kursora w prawo bez rysowania - więc niczego nie przykrywa.)

Można wykorzystać mechanizm skalowania DRAW - komendę Sn, gdzie n = 8, 12, 16..., co odpowiada 2x, 3x, 4x... ale skalowanie to jest odmienne niż w czcionkach True Type, mianowicie zwiększana jest tylko długoœć rysowanych linii, a nie ich gruboœć. Przykład tego widać powyżej. Dodatkowo zastosowanie skal poœrednich np. DRAW "s5" powoduje napis "falujacy"; nie wiem, dlaczego tak się dzieje.

Program PRINTS.BAS zawiera w liniach DATA dane dla czcionki GOTHIC dedykowanej trybowi SCREEN 13 oraz Microsoft Sans Serif 8 dla SCREEN 12. Można je wykorzystać do utworzenia zewnętrznego pliku czcionek - do użytku z wieloma programami, albo też jako szablon do stworzenia własnej lub skopiowania innej gotowej czcionki.

Aby utworzyć zewnętrzny plik danych dla czcionki z istniejacych w programie linii DATA, posłużymy się malutkim programem, który umieœcimy na samym poczštku kopii PRINTS.BAS:

OPEN "nazwa.txt" FOR OUTPUT AS #1
RESTORE Gothic         'odpowiednia etykieta 
DO
 READ a, a$, b$
 IF a = -1 THEN CLOSE : EXIT DO
 WRITE #1, a, a$, b$
LOOP
END

Programik ten przenosi dane z DATA do pliku tekstowego. Rozszerzenie .txt jest tylko dla ułatwienia podglšdania pliku spod Windows, może go nie być wcale lub np. .fnt. Otrzymany plik będzie pod Windows wyglšdał tak:

32,"spacja","br3"
33,"!","brrbu2u4ld2bd4br2"
34,"cudzysˆ˘w","brbu5ubr2dbd5br"
35,"#","ber4bu2l4ed4br2u4d4br2"
 . . . . .
Cudzysłowy wokół łańcuchów nie sš konieczne dla poprawnego odczytu pliku przez INPUT, ale tak pisze do pliku polecenie WRITE. Zapisanie tego samego przez PRINT #1 byłoby nieco bardziej skomplikowane, chyba że przystaniemy na postać
32
spacja
br3
33
!
brrbu2u4ld2bd4br2
34
 . . . . .
i trzy polecenia PRINT #1 zamiast jednego WRITE:
PRINT #1, a
PRINT #1, a$
PRINT #1, b$
Zarówno przy WRITE jak przy PRINT można pominšć zapisywanie a$ (informacji dla człowieka), wtedy plik będzie mniejszy, trzeba tylko pamiętać, że póŸniej programy odczytujšce ten plik też muszš mieć o tš jednš zmiennš mniej.

Możesz zechcieć zmodyfikować nieco GOTHIC Boba np. poszerzajšc lub zaokršglajšc trochę niektóre litery: zamiast albo opracować własnš jego odmianę... Możesz też potrzebować kursywy albo czcionki pogrubionej Sans Serif. W obu przypadkach potrzebne będš nowe dane dla czcionek.

Wykorzystanie DATA jako Ÿródła dla szablonu do opracowania innych czcionek oszczedzi trochę mozolnej pisaniny. Kodujšc czcionkę GOTHIC, pisałem wszystko ręcznie, ale do nastepnych czcionek wykorzystam możliwoœci QBasica.

Potrzebny będzie wzorzec czcionki oraz możliwoœć sprawdzania na bieżšco poprawnoœci jej odwzorowania przez komendy DRAW. Sporzšdzimy więc szablon, który to ułatwi. Po zakończeniu kodowania przekształcimy go w zewnętrzny plik danych albo w linie DATA gotowe do wstawienia do programu.

Posłużymy się znowu mini-programem wstawianym na samym poczštku kopii programu zawierajšcego DATA:

OPEN "szablon.bas" FOR OUTPUT AS #1

PRINT #1, "SCREEN 13"
PRINT #1, "DRAW "; CHR$(34); "bm20,20"; CHR$(34)
PRINT #1,

RESTORE Gothic
DO
 READ a, a$, b$
  IF a = -1 THEN EXIT DO
 PRINT #1, a
 PRINT #1, "'"; a$
 PRINT #1, "DRAW "; CHR$(34); CHR$(34)
LOOP
END

      Program ten tworzy plik SZABLON.BAS. Pierwszy PRINT wpisuje tryb ekranu - 13, ale może też być 1 lub 7 - chodzi o to, aby pracować w rozdzielczoœci 320 x 200, gdzie piksel jest duży i wyraŸny - łatwiej wtedy porównywać uzyskany wynik z powiekszonym wzorem czcionki. Następny PRINT wstawia polecenie DRAW "bm20,20", przesuwajšce kursor graficzny na pozycję x=20, y=20; jeœli nasza czcionka jest bardzo wysoka i wyjdzie poza ekran, zawsze póŸniej można zwiększyć y.
      Zauważ że z trzech danych wczytywanych z DATA sš do pliku wysyłane tylko dwie pierwsze (kod ASCII i znak lub jego opis), przy czym druga jest poprzedzona apostrofem. QBasic potraktuje kod ASCII jako (nieobowišzkowy) numer linii, a znak - jako komentarz. Trzeci PRINT posyła do pliku "puste" polecenia DRAW "", wenštrz których właœnie będziemy kodować kształty liter.

Plik SZABLON.BAS wewnštrz będzie wyglšdał tak:

SCREEN 13
DRAW "bm20,20"

 32 
'spacja
DRAW ""
 33 
'!
DRAW ""
 34 
'cudzysˆ˘w
DRAW ""
  .   .   .   .

Potrzebny będzie teraz wzorzec czcionki. Jeżeli potrzebnej czcionki nie mamy w systemie, można jej poszukać w Sieci, œcišgnšć i zainstalować. Np. pod adresem http://www.newfonts.net sš dostępne obecnie 372 czcionki. Pod adresem http://fonts.lordkyl.net jest zaœ kolekcja czcionek wzorowanych na œredniowiecznych, stšd pochodzi przykładowy Berliner.bmp. Dobrym Ÿródłem mogš być zrzuty ekranu (tak skopiowałem GOTHIC Boba). Można też próbować skanów wydawnictw drukowanych, ale tutaj spodziewam się kłopotów z ostroœciš. Niezależnie od Ÿródła rzecz sprowadza się do otrzymania pliku .BMP, który można powiększać w programie MS Paint (podobnie jak w metodzie Boba).

Jeżeli potrzebna czcionka jest w systemie, to w MS Paint rozcišgamy pole do rysowania tak, aby mogło pomieœcić wszystkie znaki i uruchamiamy jego narzędzie tekstowe:
Ikonka narzędzia tekstowego Painta
Okno narzędzia tekstowego Painta Wybieramy rodzaj i wielkoœć czcionki, po czym wypisujemy wszystkie litery i znaki w wygodnej dla nas kolejnoœci (kolejnoœć alfabetyczna pokrywa się z kolejnoœciš kodów ASCII, wyjštkiem sš znaki przestankowe, symbole i polskie "ogonki".). Zapisujemy powstały plik .BMP na dysk.

Dalsze postępowanie będzie niezależne od tego, skšd pochodzi nasz plik .BMP - czy został utworzony jak powyżej, czy też jest to zrzut ekranu lub skan.

Dostawione przed jedynkami kropki pomagajš liczyć wysokoœć znaku w pikselach
Powiekszone 2x trzy kroje oœmiopunktowych czcionek. Dostawione przed jedynkami kropki pomagajš liczyć wysokoœć znaku w pikselach.

Odwzorowywane znaki będš miały pewnš stałš wysokoœć i - jeœli jest to czcionka True Type - różne szerokoœci. Jednostkš miary dla komend rysujšcych DRAW jest piksel. Musimy naszš czcionkę pomierzyć w pikselach. Powiększamy więc widok w Paincie szeœciokrotnie, aby wygodnie operować pojedynczym pikselem. Można zastosować rozmaite linie pomocnicze, kreœlone np. żółtym czy czerwonym kolorem; ja stosuję w tym celu szachownicę z pikseli - łatwiej jest je policzyć. Wybieram do tego literę I albo H.

Kolorowe linie pomocnicze Etapy rysowania znaku $ Za zasadę odwzorowania przyjmuję, że kursor graficzny zaczyna swojš wedrówkę zawsze od tej samej linii bazowej (u podstawy pisma) od "pustego" piksela (br), obiega wszystkie linie tworzšce znak i kończy obieg znowu na linii bazowej plus jeden lub więcej "pustych" pikseli w prawo jako przerwa między znakami - zapewnia to prawidłowe łšczenie znaków w jeden wyrównany napis. W niektórych literach kursor rysuje dwukrotnie tš samš linię (np. I: "bru6d6br"), w innych przebiega odcinek bez rysowania (np. C: "bru6r2dbd4dlbr3"). Zamiast podwójnego rysowania lepiej czasem wykorzystać komendę N (Null - nic) - powoduje ona, że kursor rysuje i wraca do punktu wyjœcia. Rysowane w ten sposób "I" to "brnu6br", łańcuch jest o jeden znak krótszy. Warto starać się, aby te łańcuchy były możliwie najkrótsze, bo oszczędnoœć w bajtach przemnożona przez długoœć napisu może być znaczna. (Niestety GOTHIC, jako moja pierwsza odwzorowywana czcionka, pewnie nie wszędzie ma łańcuchy najkrótsze z możliwych - może jš ulepszysz?) ;)


Posługiwanie się komendami polecenia DRAW bardzo dobrze opisał Bob Seguin w Lekcji 4. Tu przypomnę jedynie, że symbole głównych kierunków pochodzš od słów angielskich:


U - Up - do góry
D - Down - w dół
L - Left - w lewo
R - Right - w prawo

zaœ kierunki ukoœne to kolejno E, F, G, H zaczynajšc od prawego górnego rogu w kierunku ruchu wskazówek zegara. Razem tworzy to coœ w rodzaju róży wiatrów, którš opanuje się już po zakodowaniu kilku - kilkunastu znaków. Kiedy wraz ze znużeniem wkrada się niepewnoœć (tych znaków jest przecież ponad 100), warto rzucić okiem na narożniki klawiatury numerycznej, pamietajšc, że kierunek E to klawisz 9 (3-F, 1-G, 7-H):

H  U  E

L     R

G  D  F

Liczba po literze komendy okreœla, o ile pikseli przesunie się kursor; brak liczby to domyœlne 1. A więc r3 to 3 piksele w prawo - równoważne zapisowi rrr.

Podłużna kropka i pogrubiony wykrzyknik Uwaga: Przy pomocy DRAW nie da się narysować samotnej kropki, a tylko co najmniej dwupikselowy odcinek! Takie odcinki rysuje pojedyncza komenda. Dlatego zarówno w GOTHIC jak i w MS Sans Serif wykrzyknik został pogrubiony, aby harmonizował z takš podłużnš "kropkš".

Powiększony rysunek czcionki w Paint'cie służy nam więc za wzór, z którego odczytujemy pikselowš budowę poszczególnych znaków:

Powiększone znaki Microsoft Sans Serif 8 Pt.
Powiększone znaki Microsoft Sans Serif 8 Pt.

Równoczeœnie w drugim oknie mamy otwarty QBasic z wczytanym programem SZABLON.BAS. W szablonie tym w cudzysłowach po DRAW przy odpowiednim znaku kodujemy rysunek tego znaku komendami rysujšcymi, co chwila uruchamiajšc program aby sprawdzić, czy rysuje prawidłowo.

  Kiedy nie mamy jeszcze dostatecznej wprawy, warto zaczšć od prostej litery I (br nu8 br), potem H (br u8 d3 r2 u3..) i uruchamiamy program aby sprawdzić czy poprzeczka w H nie jest za wysoko oraz czy litera nie jest za wšska, w razie potrzeby zmieniajšc liczbę po d lub r (br u8 d4 r3u4 d8 br).
  Litera J dostarczy nam pierwszego ćwiczenia z kształtem zaokršglonym i kombinacjš z poczštkowym i końcowym br: może to być brbu ale może (krócej!) iœć na ukos: be. (Jeżeli przerwa między literami ma być większa, niż 1 piksel, to już nie można tak skrócić; musi być br2 bu albo br be.) W końcu wyjdzie nam coœ jak "be u d f r e nu7 bf br" (oczywiœcie bez spacji, spacje sš dozwolone między komendami, ale bez nich łańcuch jest znacznie krótszy).
  Aby sprawdzić, czy na końcu litery sprowadziliœmy kursor graficzny do linii bazowej, warto po ostanim br czy bf dodać komendę rysujšcš w górę pionowš linię (tu, przy 9-pikselowej czcionce: u8) i uruchomić program. Jeżeli otrzymane tak "dodatkowe I" będzie za blisko, za daleko, za wysoko lub za nisko w stosunku do reszty napisu, to skorygujemy odpowiedzialne za to komendy. Gdy wszystko jest w porzšdku, usuwamy owo testujšce u8 i przystępujemy do kodowania następnego znaku.

Przy pracy w rozdzielczoœci 320 x 200 po pewnym czasie zabraknie miejsca na ekranie w linii o y=20 (kolejne znaki "wyjdš" poza ekran). Trzeba będzie wtedy w odpowiednim miejscu pliku SZABLON.BAS wstawić polecenie DRAW "bm20,40", które spowoduje umieszczenie reszty znaków w nowym wierszu (y=40; 20 pikseli niżej).

Kiedy już zakodujemy ostatni znak, trzeba przekształcić plik SZABLON.BAS albo w zewnętrzny plik danych, albo w plik z liniami DATA do wstawienia w programie, w którym będš wykorzystywane. W obydwu przypadkach trzeba usunšć wszystkie puste linie oraz poczštkowe SCREEN .. i wszystkie DRAW "bm..", aby plik zaczynał się od liczby 32. Oczywiœcie sporzšdzamy wczeœniej kopię pliku, aby w razie jakieœ pomyłki nie stracić wyniku czasochłonnej pracy.

Najprosztszy, "ręczny" sposób takiej zamiany to wykorzystanie opcji zamiany "Change..." z menu "Search" Qbasica i zamiana wszystkich DRAW na pojedyncze spacje:

Find What: DRAW
Change To: tu wstaw jednš spację
i kliknij
Change All - Zamień wszystkie.

Czasami taka zamiana wywołuje komunikat o błędzie - trzeba wtedy wyłšczyć sprawdzanie składni QBasica - odznaczyć Syntax checking w menu Options.
Na koniec plik zapisujemy (Save As...), pod nazwš zakodowanej w nim czcionki.
Otrzymany plik można już użyć jako dane dla programu, chciaż zawiera pewne elementy nadmiarowe - apostrof przed znakami i cudzysłowy wokół łańcucha rysujšcego:

32
'spacja
"br3"
33
'!
"brrbu2u4ld2bd4br2"
34
'cudzysłów
"brbu5ubr2dbd5br"
Jeżeli chcielibyœmy jednak przetworzyć ten plik na linie DATA (albo zaoszczędzić paręset bajtów), trzeba go uformować inaczej: dane dla jednego znaku - w jednej linii, oddzielone przecinkami. Tutaj znów z pomocš przyjdzie program, dla którego ten "słupkowy" plik, już pozbawiony poleceń DRAW, będzie materiałem wyjœciowym: CONVERT.BAS.

Program ten sprawdza na poczštku, czy zachowana jest kolejnoœć zapisów w pliku Ÿródłowym (pozostawione puste linie na poczštku, w œrodku czy na końcu pliku będš jš zaburzać!), po czym daje wybór wyniku: zewnętrzny plik danych z danymi ułożonymi w liniach, lub plik z liniami DATA. W przypadku wybrania DATA program sam dopisuje na końcu DATA -1,-1,-1. Te linie DATA można potem wstawić do programu, który będzie miał posługiwać się naszš nowš czcionkš.

  Kodujšc M, V lub W przekonamy się, że najdłuższe łańcuchy powstajš przy kodowaniu znaków składajšcych się z dużej liczby ukoœnych odcinków:
M = "br u8 d2 r d f d f d u e u e u e u d8 br"
V = "br bu8 d f d2 f d f d u e u e u2 e u bd8 br"
W = "br bu8 d f d2 f d f d u e u e u2 d2 f d f d u e u e u2 e u bd8 br"
  Jeszcze dłuższe jest pozawijane @:
@ = "br4 bd nr5 h l u h u3 e u r e r3 f r d f d3 l2 h u2 l2 g d f r bd2 br5"

Powiększenie kursywy Dlatego kodowanie kursywy, składajšcej się w całoœci z takich ukoœnych linii, będzie znacznie bardziej mozolne, niż czcionki normalnej. Zauważyć też trzeba, że odstęp pomiędzy znakami również jest ukoœny - znaki w pionie zachodzš na siebie. Proste I - br nu8 br - to teraz I -
  br e u e u e u e u bd8 bl3.
Na końcu, zamiast prostego przesunięcia w prawo (br), trzeba zejœc w dół bez rysowania (bd8) i cofnšć się w lewo (bl3) !

4x Czcionka Berliner 12 Pt

Pracochłonnoœć kodowania kursywy porównywalna jest z kodowaniem pisma ozdobnego. Pokazanš obok literę B z dwunastopunktowej czcionki Berliner.gif koduje następujšcy łańcuch:

brbur2e2drudnr2dr4e2nu2luh2ger2du2nr2unru2lnd2lglnd3lnd4ul2glnd2rd3gbd4br13

Bold - czcionka pogrubiona, powiększenie. Mniej pracy zapewne zajmie kodowanie czcionki pogrubionej (Bold), gdzie pogrubiane sš tylko linie pionowe. I zrealizujemy tu jako br u8 r d8 br - doszło przesunięcie w prawo u góry znaku (r) i rysowanie drugiej pionowej kreski w dół (d8). Przy innych znakach pewnie częœciej będzie wykorzystywana komenda n("rysuj i wróć").

W razie potrzeby niewykorzystane indeksy w tablicy przechowujšcej łańcuchy można użyć do zakodowania liter innych niż łacińskie lub np. symboli matematycznych: Litery greckie

Œcišgnij pakiet Prints.ZIP

W pakiecie:
Program PRINTS.BAS - demonstruje pisanie za pomocš DRAW, w DATA zawiera dane czcionek;
OVERLAY1.BAS - nakładka na PRINTS.BAS - wycišga dane czcionki z DATA do pliku tekstowego;
OVERLAY2.BAS - nakładka na PRINTS.BAS jak wyżej, ale dane w pliku umieszcza w "słupku";
OVERLAY3.BAS - nakładka do tworzenia pliku szablonu do wpisywania danych dla nowej czcionki;
CONVERT.BAS - przekształca dane nowej czcionki w plik danych albo plik z liniami DATA.



Damian Gawrych "Deger", marzec 2008
http://deger.republika.pl