To nie jest twierdzenie, a realny problem, zauważony w Delphi7 - pisałem swój label i taki problem napotkałem przy testach różnych fontów; Pisałem o tym od pierwszego posta w tym wątku: http://4programmers.net/Forum/Off-Topic/Oceny_i_recenzje/239916-tfuriouslabel_-_etykieta_formatowana_znacznikami_html:
Wady:
(...)
- występuje problem z niektórymi fontami i rysowaniem podkreślonych linków o takich fontach - z tego co wybadałem nie jest to problem kodu komponentu, a metody
TCanvas.TextHeight
, która czasem źle oblicza wysokość pogrubionego lub podkreślonego tekstu), co negatywnie wpływa na rysowanie słów; W nowszych środowiskach niż Delphi7 być może zostało to poprawione;
Złe mierzenie wysokości tekstu objawiało się tym, że słowa o pogrubionym stylu były rysowane piksel/dwa piksele niżej, niż tekst ze stylem standardowym; W niektórych fontach (głównie Ubuntu
) był problem z mierzeniem szerokości słów o stylu pogrubionym lub pochylonym; Objawiało się to tym, że dwa słowa - ze stylem standardowym i drugie z pogrubionym - rysowane były ze zbyt małą przerwą, a nawet bez odstępu; Taki defekt zauważyłem wilokrotnie podczas dziesiątek testów i nie znalazłem winy w moim kodzie; Dlatego też napisałem o tym w dedykowanym komponentowi wątku;
Sprawdzałem dokładnie i wielokrotnie poprawność działania tokenizera, wrzucając dane ze wszystkich tokenów do pliku tekstowego; Jeżeli pogrubione słowo było źle malowane na kanwie, patrzyłem do pliku z logami i faktycznie token posiadał złą wartość szerokości słowa (ze złą wysokością było tak samo); A szerokość słowa zawsze była obliczana po ustawieniu stylu i metodą TCanvas.TextWidth
; Dlatego też tokenizer działał poprawnie, mechanizm rysujący słowa także, więc jedynym winnym były metody TCanvas.TextHeigh
i TCanvas.TextWidth
, które de facto korzystają z API Windowsa; Pod Lazarusem tego problemu nie było, a przynajmniej w testach się nie ujawnił;
Z resztą funkcja DrawText
z modułu Windows
także jest wadliwa; Przeprowadziłem testy na mierzeniu obszaru za pomocą flagi DT_CALCRECT
i obszar wyliczany był źle; Dla samej literki A
szerokość była dobra, ale z góry i z dołu były niepotrzebne odstępy, więc obszar był źle wyznaczany; Następnie sprawdziłem z sekwencją Aj
, aby także sprawić na innych literach; Tu znowu był problem, po pusta przestrzeń była u góry, a dół literki j
był ucięty;
Tak więc kodu nie ujawnię, bo kod labelka nie jest otwarty; Sam sprawdź to zobaczysz (a może i nie); Z resztą metoda TCanvas.TextHeight
chyba żadnego fonta nie zmierzy według faktycznych rozmiarów liter i dobrze, bo nie do tego ma służyć; Znaki są różne, mają różną szerokość, różną wysokość i różny offset od góry, a pomimo tego wysokość wszystkich znaków określa jako taką samą - Canvas.TextHeight(',') = Canvas.TextHeight('|')
;
PS: W wątku dotyczącym mojego labelka jest program testowy - spróbuj wywalić parser i zaobserwować ten defekt.