Wykład XVIII
Wykorzystanie narzędzi
malarskich w Object
Pascalu
Podstawy informatyki
Semestr II Transport
Wprowadzenie
O wyglądzie każdego komponentu
wizualnego decyduje jego wydzielony
prostokątny obszar zwany płótnem
(Canvas) i reprezentowany przez
właściwość Canvas typu TCanvas.
Jedną z właściwości płótna jest
właściwość Pixels reprezentująca
bitowy wzorzec poszczególnych pikseli
obrazu.
Sposób tworzenia rysunku
na płótnie
Formularz/Komp
onent
Powiększony
fragment
ekranu (każda
kratka to jeden
pixel)
(Tak
wyglądał
„prawdziwy
” kot)
heig
ht
wid
th
Narzędzia malarskie
Idea płótna komponentu stanowi niezwykle
trafną analogię, nadawanie bowiem
komponentowi wizualnego określonego
wyglądu do złudzenia przypomina malowanie
na rzeczywistym „płótnie”.
Podobnie analogicznie nazywane w środowisku
są narzędzia malarskie. Nazwy oddają
właściwy charakter i cel ich stosowania:
– Pióro (Pen)
– Pędzel (Brush)
– Czcionka (Font)
Operowanie piórem
Za pomocą piór możliwe jest
kreślenie linii w wybranym kolorze,
stylu, o żądanej grubości i sposobie
nakładania na istniejącą grafikę.
Odpowiadają za to właściwości
(kolejno): Color, Style, Width i
Mode.
Kolory
Delphi definiuje kolory standardowe np.. clRed
(czerwony) i clYellow (żółty)
Pen.Color:=clYellow;
Możliwe jest również określanie kolorów w
kategoriach systemowych np.. clActiveCaption
(kolor paska tytułu aktywnego okna) czy
clHighLightText (kolor podświetlonego tekstu)
Pen.Color:=clActiveCaption;
Można oczywiście posłużyć się numerem koloru
Pen.Color:=165768;
Styl linii
Zależy od właściwości
Style
Jedynie linie o grubości
1 piksela mogą być
liniami przerywanymi,
grubsze niezależnie od
stylu pióra są zawsze
ciągłe (Win95,98,Me).
Windows NT/2000/XP,
nie mają tego
ograniczenia
Przykład
Pen.Style:=psDot;
psSolid
psDash
psDot
psDashDo
t
psDashDo
tDot
psClear
psInsideFr
ame
Linia zamknięta w
ramce o
regularnym
kształcie
Właściwość Mode
O kolorze poszczególnych pikseli w ramach rysowanej
linii decydują trzy czynniki
– kolor pióra (Color)
– kolor istniejącego w danym miejscu piksela
– sposób nakładania kolorów (Mode)
Jeśli przez S oznaczymy kolor pióra a przez D kolor
istniejącego piksela, to poszczególne tryby można
opisać za pomocą operacji boolowskich wykonywanych
na poszczególnych bitach wartości kolorów. Możliwe
tryby przedstawia tabela (następne slajd).
Domyślnym trybem jest tryb pmCopy – oznacza to, że
kreślona linia zamazuje dotychczasową wartość
podłoża
Tryby kombinacji pióra z
kolorem tła
pmBlack
czarny
$00000
000
pmWhite
biały
$00FFFF
FF
pmNOP
bez zmiany
D
pmNOT
inwersja tła
not D
pmCopy
kolor pióra
S
pmNotCopy inwersja koloru pióra
not S
pmMargeP
enNot
suma koloru pióra i inwersji
tła
S or not
D
pmMaskPe
nNot
składowa wspólna koloru
pióra i tła
S and
not D
pmMergeN
otPen
suma inwersji koloru pióra i
tła
not S or
D
Tryby kombinacji pióra z
kolorem tła cd.
pmMaskNo
tPen
składowa wspólna inwersji
koloru pióra i tła
not S and
D
pmMerge
suma kolorów pióra i tła
S or D
pmNotMer
ge
inwersja sumy kolorów
pióra i tła
not (S or
D)
pmMask
składowa wspólna kolorów
pióra i tła
S and D
pmNotMas
k
inwersja składowej
wspólnej kolorów pióra i tła
not (S
and D)
pmXor
Różnica symetryczna
kolorów pióra i tła
S xor D
pmNotXor
Dopełnienie różnicy
symetrycznej kolorów pióra
i tła
not (S xor
D)
Dostęp do poszczególnych
pikseli płótna
Właściwość TCanvas.Pixels ma
postać dwuwymiarowej tablicy, której
elementy są typu TColors. Pozioma
wartość indeksu zmienia się w
zakresie [0..Width], pionowa
[0..Height]
Przykład
Image1.Pixels[20,50]:=clRed;
Wykorzystanie pędzli
Zadaniem pędzla jest wypełnianie
obszarów zgodnie z zadanym kolorem
(Color), stylem (Style) i wzorcem
pikselowym (Bitmap)
Właściwość Color jest wykorzystywana
identycznie jak w wypadku pióra
Canvas.Brush.Color:=clRed;
Canvas.Brush.Color:=clBtnFace;
Canvas.Brush.Color:=2312335;
Właściwość Style
Canvas.Brush.Style:=bsSolid;
Canvas.Brush.Style:=bsHorizontal;
Właściwość Bitmap
Powala posługiwać się jako wzorem pędzla dowolną
zgodną z urządzeniem bitmapą o rozmiarach 8x8 pikseli
Właściwość ta ma wyższą rangę niż właściwość Style
Przykład
procedure DrawRectangle(ACanvas:TCanvas;const
R:TRect; FillBitmap:TBitmap);
begin
ACanvas.Brush.Bitmap:=FillBitmap;
try ACanvas.Rectangle(R.Left, R.Top,
R.Right,R.Bottom);
finally ACanvas.Brush.Bitmap:=nil;
end;
end;
Wykorzystanie czcionek
Do wypisywania tekstu służy metoda
procedure TCanvas.TextOut(X, Y: Integer; const Text:
string);
Czcionka, którą wypisany zostanie tekst jest określana
przez właściwość obiektową płótna -Font określającą
m.in. jej kolor, nazwę, wysokość i styl
Właściwość Name określa nazwę czcionki
Canvas.Font.Name:=‘Times New Roman’;
Wielkość czcionki określa właściwość Size
Canvas.Font.Size:=12;
Kolor czcionki jest definiowany przez właściwość Color
Canvas.Font.Color:=clYellow;
Style czcionek
Powyższe cechy są od siebie niezależne, toteż
można je łączyć w sposób typowy dla właściwości
zbiorowych
Canvas.Font.Style:=[fsBold, fsItalic];
Wartość
Znaczenie
Przykład
fsBold
Wytłuszczenie
Delphi
fsItalic
Pochylenie
Delphi
fsUnderline
Podkreślenie
Delphi
fsStrikeOut
Przekreślenie
Delphi
Przepisywanie czcionek
pomiędzy komponentami
Umożliwia metoda Assign()
Przykład
Canvas.Font.Assign(Memo1.Font)
if FontDialog.Execute then
Memo1.Font.Assign(FontDialog.Font);
Operacje na pikselach
Dostęp do poszczególnych punktów płótna
realizowany jest za pomocą tablicowej
właściwości Pixels obiektu Canvas
Właściwość Pixels jest dwuwymiarową tablicą,
a każdy jej element zawiera wartość
oznaczającą kolor jednego punktu.
Przykład
Canvas.Pixels[10,20]:=clRed;
{255}
{Instrukcja dotyczy piksela o współrzędnych
(10,20) i ustawia jego kolor na czerwony – nr
koloru 255, clRed to stała zawierająca tę
wartość}
Kreślenie linii
Metoda MoveTo zmienia pozycję pióra na wskazaną przez
parametry
Canvas.MoveTo(0,0);
{ustawienie pióra w lewym, górnym rogu okna}
Metoda LineTo powoduje wykreślenie odcinka linii prostej
pomiędzy bieżącą pozycją pióra, a punktem wskazanym
przez parametry
Canvas.LineTo(Form.ClientWidth, Form.ClientHeight);
MoveTo(x1,y1);
LineTo(x2,y2);
(x1,y1)
(x2,y2)
Kreślenie figur
geometrycznych
TCanvas posiada szereg metod umożliwiających
kreślenie i wypełnianie różnorodnych figur
geometrycznych:
– Arc
– Chord
– Ellipse
– Pie
– Polygon
– PolyLine
– Rectangle
– RoundRect
Wszystkie figury rysowane są z użyciem własności
bieżącego pióra i pędzla
Procedura Arc
procedure Arc(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer);
przy użyciu bieżącego pióra rysuje krzywą eliptyczną
pierwsze 4 parametry procedury określają współrzędne
wierzchołków prostokąta, w który wpisana jest bazowa
elipsa
następne cztery parametry określają współrzędne
punktów, które połączone ze środkiem elipsy tworzą linie
intersekcyjne wycinające wycinek elipsy
(x1,y1)
(x2,y2)
(x4,y4)
(x3,
y3)
Przykład użycia Arc
procedure TForm1.FormPaint(Sender: TObject);
var R: TRect;
begin
R := GetClientRect;
{pobiera współrzędne prostokąta
bieżącego okna i umieszcza w zmiennej R}
Canvas.Arc(R.Left, R.Top, R.Right, R.Bottom, R.Right,
R.Top, R.Left, R.Top);
end;
Procedura Chord
procedure Chord(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer);
przy użyciu bieżącego pióra i pędzla rysuje oraz
wypełnia figurę zamkniętą przez krzywą eliptyczną i
linię łączącą punkty intersekcyjne
pierwsze 4 parametry procedury określają współrzędne
wierzchołków prostokąta, w który wpisana jest bazowa
elipsa
następne cztery parametry określają współrzędne
punktów, które połączone ze środkiem elipsy tworzą
linie intersekcyjne wycinające wycinek elipsy
(x3,y
3)
(x1,y1)
(x2,y2)
(x4,y4)
Procedura Ellipse
procedure Ellipse(X1, Y1, X2, Y2: Integer);
Powoduje narysowanie elipsy o takich długościach
osi, jakby była wpisana w prostokąt o współrzędnych
podanych przez parametry procedury
Przykład Canvas.Ellipse(X1,Y1,X2,Y2);
(x1,y1)
(x2,y2)
Procedura Pie
procedure Pie(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Longint);
przy użyciu bieżącego pióra i pędzla rysuje oraz wypełnia
figurę zamkniętą przez krzywą eliptyczną i linie łączące
punkty intersekcyjne ze środkiem elipsy bazowej (wycinek
elipsy)
pierwsze 4 parametry procedury określają współrzędne
wierzchołków prostokąta, w który wpisana jest elipsa bazowa
następne cztery parametry określają współrzędne punktów,
które połączone ze środkiem elipsy tworzą linie intersekcyjne
wycinające wycinek elipsy
(x3,y
3)
(x1,y1)
(x2,y2)
(x4,y4)
Procedura Polygon
procedure Polygon(Points: array of TPoint);
Kreśli kształt zamknięty linią łamaną łączącą punkty
z tablicy punktów podanej jako parametr procedury
i wypełnia jego wnętrze bieżącym wzorem pędzla
Przykład
Canvas.Brush.Color := clTeal;
Canvas.Polygon([Point(10,10), Point(30,10),
Point(130,30), Point(240,120)]);
Procedura PolyLine
procedure Polyline(Points: array of TPoint);
Kreśli linię łamaną łączącą punkty z tablicy punktów
podanej jako parametr procedury
Rysowana linia nie musi być linią zamkniętą
Przykład
Canvas.Pen.Color := clBlack;
Canvas.PolyLine([Point(40,10),Point(20,60),Point(
70,30), Point(10,30),Point(60,60),Point(40,10)]);
Procedura Rectangle
procedure Rectangle(X1, Y1, X2, Y2: Integer);
efektem wykonania procedury jest prostokąt
narysowany bieżącym wzorem pióra i wypełniony
aktualnym stylem pędzla
parametry procedury oznaczają współrzędne lewego
górnego i prawego dolnego rogu prostokąta
Przykład
Canvas.Rectangle(10,100,200,234);
(x1,y1)
(x2,y2)
Procedura RoundRect
procedure RoundRect(X1, Y1, X2, Y2, X3, Y3: Integer);
wykonanie procedury powoduje narysowanie na
płótnie prostokąta z zaokrąglonymi rogami
pierwsze 4 parametry oznaczają współrzędne rogów
prostokąta bazowego
ostatnie 2 parametry określają kształt (wysokość i
szerokość) elipsy użytej do zaokrąglenia rogów
x3
y3
(x1,y1)
(x2,y2)
Wypisywanie tekstu
procedure TextOut(X, Y: Integer; const Text: string);
Służy do wyprowadzania tekstu (określanego
parametrem Text) na płótnie z użyciem bieżącej
czcionki
Tekst wyprowadzony jest w miejscu określonym
przez współrzędne X i Y
Przykład
Canvas.TextOut(10, 30,’Delphi–narzędzie
profesjonalistów);
Wymiary tekstu
Do określenia wymiarów tekstu służą dwie funkcje
zwracające odpowiednio wysokość i szerokość
wyprowadzanego tekstu
function TextHeight(const Text: string): Integer;
function TextWidth(const Text: string): Integer;
Funkcji tych należy używać po określeniu właściwości
czcionki używanej do wyprowadzania tekstu i treści napisu
Przykład
var S: String; w, h: Integer;
begin
S:=’Przykładowy tekst’;
w:=Canvas.TextHeight(S); h:=Canvas.TextWidth(S);
end;
Wyprowadzanie tekstu
wewnątrz zadanego obszaru
procedure TextRect(Rect: TRect; X, Y: Integer; const Text:
string);
Służy do wyprowadzania tekstu wewnątrz
zadanego (parametr Rect) prostokątnego
obszaru
Część napisu,która nie mieści się w zadanym
prostokącie są obcinane
Parametry X i Y określają położenie napisu na
płótnie
Treść napisu definiowana jest parametrem Text;
Korzystanie z metody
TextRect
var R: TRect;
begin
R:=Rect(110,110,200,200);
Canvas.TextRect(R,130,180,'Napis wewnątrz
obszaru!');
end;
Nic nie trwa wiecznie !
W środowiskach graficznych pracuje jednocześnie
wiele aplikacji. Tak więc każde okno aplikacji może być
przysłonięte przez inne, mogą się również zmieniać
jego rozmiary. W tej sytuacji należałoby zapamiętywać
zawartość okien (niestety wymagałoby to bardzo wiele
pamięci) lub (tak dzieje się w systemie Windows)
poinformować okno, że wymaga odświeżenia.
Jeśli zatem nie wykonamy specjalnych zabiegów (nie
obsłużymy komunikatu o konieczności odświeżenia
obrazu) to narysowany na formie (lub innym
elemencie zawierającym płótno) rysunek zniknie
częściowo lub w całości gdy okno zawierające płótno
(lub jego część) zostanie przysłonięte.
Zdarzenie OnPaint
W sytuacji kiedy konieczne jest przerysowanie
okno odbiera komunikat wm_Paint. Jego
odebranie powoduje wykonanie metody OnPaint i
program sam musi zadbać o to, by doprowadzić
ekran do porządku.
Zatem uzupełniając metodę OnPaint treścią
realizującą rysunek można sprawić by był on
odtwarzany po każdorazowym odebraniu
komunikatu o konieczności odmalowania formy
(lub jej części).
W celu wymuszenia odmalowania zawartości okna
można skorzystać z metod: Invalidate, Update,
RePaint lub ReFresh;
Metoda Invalidate
procedure Invalidate; virtual;
Informuje system, że cała powierzchnia formularz
powinna być pomalowana ponownie
Odmalowanie nie następuje natychmiast lecz dopiero po
zakończeniu bieżącej wykonywanej przez system
procedury i wewnątrz systemu nie ma innych zdarzeń
oczekujących w kolejce do obsługi.
Windows opóźnia w ten sposób wykonanie operacji
malowania (jednej z najbardziej czasochłonnych spośród
realizowanych przez komputery), w wyniku czego podczas
malowania wprowadzanych jest często jednocześnie kilka
zmian w wyglądzie płótna. Unika się w ten sposób
wielokrotnego wyzwalania czasochłonnej procedury
Metoda Update
procedure Update; virtual;
Zawiera rozkaz natychmiastowego
uaktualnienia zawartości formularza
(odmalowania jego zawartości)
Operacja jest jednak podejmowana tylko
wtedy, gdy formularz zawiera obszar
unieważniony (invalidate area). Obszar taki
powstaje w wyniku wywołania metody
Invalidate lub jako efekt działania
użytkownika (przysłonięcie obszaru).
Metody Repaint i
Refresh
Metoda Repaint wzywa w odpowiedniej
kolejności metody Invalidate i Update.
Dodatkowo aktywuje zdarzenie OnPaint
Metoda Refresh jest zmodyfikowaną
wersją metody Repaint. Efekt ich
wywołania dla formularzy są identyczne.
Różnice występują przy wywołaniu dla
poszczególnych komponentów.
Obszar odświeżania
aby przyspieszyć operacje rysowania można
przerysowywać tylko fragmenty rysunku tzw.
obszar odświeżania (update region).
Jeśli unieważnimy tylko część okna to tylko ta
część zostanie przerysowana. Służą do tego
metody InvalidateRect i InvalidateRegion.
Mimo, że funkcje te znacznie skracają czas
rysowania uwalniając obraz od migotania
należy stosować je rozważnie, tak aby w
rezultacie otrzymywać poprawny obraz w
całym oknie.