Sign in Join
Wiki copytemporary

Graphics - Working with TCanvas/ru: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Graphics - Working with TCanvas/ru

OldNewLine
1+## Рисование прямоугольника
2+
3+Многие элементы управления отображают свой холст как общедоступное свойство или в событии OnPaint, например, [[TForm]], [[TPanel]] и [[TPaintBox]]. Давайте используем TForm в качестве примера, чтобы продемонстрировать, как рисовать на холсте.
4+
5+Предположим, мы хотим нарисовать красный прямоугольник с синей рамкой толщиной 5 пикселей в центре формы; размер прямоугольника должен составлять половину размера формы. Для этого мы должны добавить код в событие OnPaint формы. Не рисуйте в обработчике OnClick, потому что это рисование не является постоянным и будет стираться всякий раз, когда операционная система запросит перерисовку, всегда рисуйте в событии OnPaint!
6+
7+Метод TCanvas для рисования прямоугольника вызывается именно так: `Rectangle()`. Он получает координаты краев прямоугольника либо отдельно, либо в виде записи `TRect`. Цвет заливки определяется цветом кисти Brush холста, а цвет границы задается цветом пера Pen холста:
8+
9+``` pascal
10+procedure TForm1.FormPaint(Sender: TObject);
11+var
12+ w, h: Integer; // ширина и высота прямоугольника
13+ cx, cy: Integer; // центр формы
14+ R: TRect; // запись, содержащая координаты левого, верхнего, правого и нижнего углов прямоугольника
15+begin
16+ // высчитываем центр формы
17+ cx := Width div 2;
18+ cy := Height div 2;
19+
20+ // высчитываем размеры прямоугольника
21+ w := Width div 2;
22+ h := Height div 2;
23+
24+ // высчитываем точки углов прямоугольника
25+ R.Left := cx - w div 2;
26+ R.Top := cy - h div 2;
27+ R.Right := cx + w div 2;
28+ R.Bottom := cy + h div 2;
29+
30+ // задаем цвета заливки
31+ Canvas.Brush.Color := clRed;
32+ Canvas.Brush.Style := bsSolid;
33+
34+ // задаем цвет границ
35+ Canvas.Pen.Color := clBlue;
36+ Canvas.Pen.Width := 5;
37+ Canvas.Pen.Style := psSolid;
38+
39+ // рисуем прямоугольник
40+ Canvas.Rectangle(R);
41+end;
42+```
43+
44+## Использование шрифта по-умолчанию
45+
46+Это может быть выполнено с помощью следующего простого кода:
47+
48+``` pascal
49+SelectObject(Canvas.Handle, GetStockObject(DEFAULT_GUI_FONT));
50+```
51+
52+## Рисование текста, ограниченного по ширине
53+
54+Используйте процедуру **DrawText** сначала с параметром DT_CALCRECT, а затем без него.
55+
56+``` pascal
57+// Сначала вычисляем размер текста, затем рисуем его
58+TextBox := Rect(0, currentPos.Y, Width, High(Integer));
59+DrawText(ACanvas.Handle, PChar(Text), Length(Text),
60+ TextBox, DT_WORDBREAK or DT_INTERNAL or DT_CALCRECT);
61+
62+DrawText(ACanvas.Handle, PChar(Text), Length(Text),
63+ TextBox, DT_WORDBREAK or DT_INTERNAL);
64+```
65+
66+## Рисование текста с четкими краями (без сглаживания)
67+
68+Некоторые виджеты поддерживают этот способ с помощью свойства
69+
70+``` pascal
71+Canvas.Font.Quality := fqNonAntialiased;
72+```
73+
74+Но некоторые виджеты, например из набора gtk2, не поддерживают это свойство и всегда отображают текст сглаженным. Вот простая процедура для рисования текста с четкими краями для gtk2. В ней не рассмотрены все случаи, но в ней предлагается идея:
75+
76+``` pascal
77+procedure PaintAliased(Canvas: TCanvas; x,y: integer; const TheText: string);
78+var
79+ w,h: integer;
80+ IntfImg: TLazIntfImage;
81+ Img: TBitmap;
82+ dy: Integer;
83+ dx: Integer;
84+ col: TFPColor;
85+ FontColor: TColor;
86+ c: TColor;
87+begin
88+ w:=0;
89+ h:=0;
90+ Canvas.GetTextSize(TheText,w,h);
91+ if (w<=0) or (h<=0) then exit;
92+ Img:=TBitmap.Create;
93+ IntfImg:=nil;
94+ try
95+ // рисуем текст в растре
96+ Img.Masked:=true;
97+ Img.SetSize(w,h);
98+ Img.Canvas.Brush.Style:=bsSolid;
99+ Img.Canvas.Brush.Color:=clWhite;
100+ Img.Canvas.FillRect(0,0,w,h);
101+ Img.Canvas.Font:=Canvas.Font;
102+ Img.Canvas.TextOut(0,0,TheText);
103+ // получаем картинку из памяти
104+ IntfImg:=Img.CreateIntfImage;
105+ // заменяем серые пиксели
106+ FontColor:=ColorToRGB(Canvas.Font.Color);
107+ for dy:=0 to h-1 do begin
108+ for dx:=0 to w-1 do begin
109+ col:=IntfImg.Colors[dx,dy];
110+ c:=FPColorToTColor(col);
111+ if c<>FontColor then
112+ IntfImg.Colors[dx,dy]:=colTransparent;
113+ end;
114+ end;
115+ // создаем растровую картинку
116+ Img.LoadFromIntfImage(IntfImg);
117+ // рисуем ее на холсте
118+ Canvas.Draw(x,y,Img);
119+ finally
120+ IntfImg.Free;
121+ Img.Free;
122+ end;
123+end;
124+```
125+
126+---
127+*From the Free Pascal wiki, page "Graphics - Working with TCanvas/ru", as it stood on 2020-02-16 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history