Difference between revisions of "Graphics - Working with TCanvas/ru"

From Lazarus wiki
Jump to navigationJump to search
(Created page with "<noinclude>{{Graphics - Working with TCanvas}}</noinclude> == Использование шрифта по-молчанию == Это может быть выполнено...")
 
m (Fixed syntax highlighting)
 
(3 intermediate revisions by one other user not shown)
Line 1: Line 1:
 
<noinclude>{{Graphics - Working with TCanvas}}</noinclude>
 
<noinclude>{{Graphics - Working with TCanvas}}</noinclude>
 +
__TOC__
 +
== Рисование прямоугольника ==
 +
Многие элементы управления отображают свой холст как общедоступное свойство или в событии OnPaint, например, [[TForm]], [[TPanel]] и [[TPaintBox]]. Давайте используем TForm в качестве примера, чтобы продемонстрировать, как рисовать на холсте.
  
== Использование шрифта по-молчанию ==
+
Предположим, мы хотим нарисовать красный прямоугольник с синей рамкой толщиной 5 пикселей в центре формы; размер прямоугольника должен составлять половину размера формы. Для этого мы должны добавить код в событие OnPaint формы. Не рисуйте в обработчике OnClick, потому что это рисование не является постоянным и будет стираться всякий раз, когда операционная система запросит перерисовку, всегда рисуйте в событии OnPaint!
 +
 
 +
Метод TCanvas для рисования прямоугольника вызывается именно так: <tt>Rectangle()</tt>. Он получает координаты краев прямоугольника либо отдельно, либо в виде записи <tt>TRect</tt>. Цвет заливки определяется цветом кисти Brush холста, а цвет границы задается цветом пера Pen холста:
 +
<syntaxhighlight lang=pascal>procedure TForm1.FormPaint(Sender: TObject);
 +
var
 +
  w, h: Integer;    // ширина и высота прямоугольника
 +
  cx, cy: Integer;  // центр формы
 +
  R: TRect;        // запись, содержащая координаты левого, верхнего, правого и нижнего углов прямоугольника
 +
begin
 +
  // высчитываем центр формы
 +
  cx := Width div 2;
 +
  cy := Height div 2;
 +
 
 +
  // высчитываем размеры прямоугольника
 +
  w := Width div 2;
 +
  h := Height div 2;
 +
 
 +
  // высчитываем точки углов прямоугольника
 +
  R.Left := cx - w div 2;
 +
  R.Top := cy - h div 2;
 +
  R.Right := cx + w div 2;
 +
  R.Bottom := cy + h div 2;
 +
 
 +
  // задаем цвета заливки
 +
  Canvas.Brush.Color := clRed;
 +
  Canvas.Brush.Style := bsSolid;
 +
 
 +
  // задаем цвет границ
 +
  Canvas.Pen.Color := clBlue;
 +
  Canvas.Pen.Width := 5;
 +
  Canvas.Pen.Style := psSolid;
 +
 
 +
  // рисуем прямоугольник
 +
  Canvas.Rectangle(R);
 +
end;
 +
</syntaxhighlight>
 +
 
 +
== Использование шрифта по-умолчанию ==
 
Это может быть выполнено с помощью следующего простого кода:
 
Это может быть выполнено с помощью следующего простого кода:
<syntaxhighlight>SelectObject(Canvas.Handle, GetStockObject(DEFAULT_GUI_FONT));</syntaxhighlight>
+
<syntaxhighlight lang=pascal>SelectObject(Canvas.Handle, GetStockObject(DEFAULT_GUI_FONT));</syntaxhighlight>
  
 
== Рисование текста, ограниченного по ширине ==
 
== Рисование текста, ограниченного по ширине ==
Line 9: Line 49:
 
Используйте процедуру '''DrawText''' сначала с параметром DT_CALCRECT, а затем без него.
 
Используйте процедуру '''DrawText''' сначала с параметром DT_CALCRECT, а затем без него.
  
<syntaxhighlight>// Сначала вычисляем размер текста, затем рисуем его
+
<syntaxhighlight lang=pascal>// Сначала вычисляем размер текста, затем рисуем его
 
TextBox := Rect(0, currentPos.Y, Width, High(Integer));
 
TextBox := Rect(0, currentPos.Y, Width, High(Integer));
 
DrawText(ACanvas.Handle, PChar(Text), Length(Text),
 
DrawText(ACanvas.Handle, PChar(Text), Length(Text),
Line 21: Line 61:
 
Некоторые виджеты поддерживают этот способ с помощью свойства
 
Некоторые виджеты поддерживают этот способ с помощью свойства
  
<syntaxhighlight>Canvas.Font.Quality := fqNonAntialiased;</syntaxhighlight>
+
<syntaxhighlight lang=pascal>Canvas.Font.Quality := fqNonAntialiased;</syntaxhighlight>
  
 
Но некоторые виджеты, например из набора gtk2, не поддерживают это свойство и всегда отображают текст сглаженным. Вот простая процедура для рисования текста с четкими краями для gtk2. В ней не рассмотрены все случаи, но в ней предлагается идея:
 
Но некоторые виджеты, например из набора gtk2, не поддерживают это свойство и всегда отображают текст сглаженным. Вот простая процедура для рисования текста с четкими краями для gtk2. В ней не рассмотрены все случаи, но в ней предлагается идея:
  
<syntaxhighlight>procedure PaintAliased(Canvas: TCanvas; x,y: integer; const TheText: string);
+
<syntaxhighlight lang=pascal>procedure PaintAliased(Canvas: TCanvas; x,y: integer; const TheText: string);
 
var
 
var
 
   w,h: integer;
 
   w,h: integer;
Line 43: Line 83:
 
   IntfImg:=nil;
 
   IntfImg:=nil;
 
   try
 
   try
     // paint text to a bitmap
+
     // рисуем текст в растре
 
     Img.Masked:=true;
 
     Img.Masked:=true;
 
     Img.SetSize(w,h);
 
     Img.SetSize(w,h);
Line 51: Line 91:
 
     Img.Canvas.Font:=Canvas.Font;
 
     Img.Canvas.Font:=Canvas.Font;
 
     Img.Canvas.TextOut(0,0,TheText);
 
     Img.Canvas.TextOut(0,0,TheText);
     // get memory image
+
     // получаем картинку из памяти
 
     IntfImg:=Img.CreateIntfImage;
 
     IntfImg:=Img.CreateIntfImage;
     // replace gray pixels
+
     // заменяем серые пиксели
 
     FontColor:=ColorToRGB(Canvas.Font.Color);
 
     FontColor:=ColorToRGB(Canvas.Font.Color);
 
     for dy:=0 to h-1 do begin
 
     for dy:=0 to h-1 do begin
Line 63: Line 103:
 
       end;
 
       end;
 
     end;
 
     end;
     // create bitmap
+
     // создаем растровую картинку
 
     Img.LoadFromIntfImage(IntfImg);
 
     Img.LoadFromIntfImage(IntfImg);
     // paint
+
     // рисуем ее на холсте
 
     Canvas.Draw(x,y,Img);
 
     Canvas.Draw(x,y,Img);
 
   finally
 
   finally

Latest revision as of 13:12, 16 February 2020

English (en) français (fr) italiano (it) русский (ru)

Рисование прямоугольника

Многие элементы управления отображают свой холст как общедоступное свойство или в событии OnPaint, например, TForm, TPanel и TPaintBox. Давайте используем TForm в качестве примера, чтобы продемонстрировать, как рисовать на холсте.

Предположим, мы хотим нарисовать красный прямоугольник с синей рамкой толщиной 5 пикселей в центре формы; размер прямоугольника должен составлять половину размера формы. Для этого мы должны добавить код в событие OnPaint формы. Не рисуйте в обработчике OnClick, потому что это рисование не является постоянным и будет стираться всякий раз, когда операционная система запросит перерисовку, всегда рисуйте в событии OnPaint!

Метод TCanvas для рисования прямоугольника вызывается именно так: Rectangle(). Он получает координаты краев прямоугольника либо отдельно, либо в виде записи TRect. Цвет заливки определяется цветом кисти Brush холста, а цвет границы задается цветом пера Pen холста:

procedure TForm1.FormPaint(Sender: TObject);
var
  w, h: Integer;    // ширина и высота прямоугольника
  cx, cy: Integer;  // центр формы
  R: TRect;         // запись, содержащая координаты левого, верхнего, правого и нижнего углов прямоугольника
begin
  // высчитываем центр формы
  cx := Width div 2;
  cy := Height div 2;

  // высчитываем размеры прямоугольника
  w := Width div 2;
  h := Height div 2;

  // высчитываем точки углов прямоугольника
  R.Left := cx - w div 2;
  R.Top := cy - h div 2;
  R.Right := cx + w div 2;
  R.Bottom := cy + h div 2;

  // задаем цвета заливки
  Canvas.Brush.Color := clRed;
  Canvas.Brush.Style := bsSolid;

  // задаем цвет границ
  Canvas.Pen.Color := clBlue;
  Canvas.Pen.Width := 5;
  Canvas.Pen.Style := psSolid;

  // рисуем прямоугольник
  Canvas.Rectangle(R);
end;

Использование шрифта по-умолчанию

Это может быть выполнено с помощью следующего простого кода:

SelectObject(Canvas.Handle, GetStockObject(DEFAULT_GUI_FONT));

Рисование текста, ограниченного по ширине

Используйте процедуру DrawText сначала с параметром DT_CALCRECT, а затем без него.

// Сначала вычисляем размер текста, затем рисуем его
TextBox := Rect(0, currentPos.Y, Width, High(Integer));
DrawText(ACanvas.Handle, PChar(Text), Length(Text),
  TextBox, DT_WORDBREAK or DT_INTERNAL or DT_CALCRECT);

DrawText(ACanvas.Handle, PChar(Text), Length(Text),
  TextBox, DT_WORDBREAK or DT_INTERNAL);

Рисование текста с четкими краями (без сглаживания)

Некоторые виджеты поддерживают этот способ с помощью свойства

Canvas.Font.Quality := fqNonAntialiased;

Но некоторые виджеты, например из набора gtk2, не поддерживают это свойство и всегда отображают текст сглаженным. Вот простая процедура для рисования текста с четкими краями для gtk2. В ней не рассмотрены все случаи, но в ней предлагается идея:

procedure PaintAliased(Canvas: TCanvas; x,y: integer; const TheText: string);
var
  w,h: integer;
  IntfImg: TLazIntfImage;
  Img: TBitmap;
  dy: Integer;
  dx: Integer;
  col: TFPColor;
  FontColor: TColor;
  c: TColor;
begin
  w:=0;
  h:=0;
  Canvas.GetTextSize(TheText,w,h);
  if (w<=0) or (h<=0) then exit;
  Img:=TBitmap.Create;
  IntfImg:=nil;
  try
    // рисуем текст в растре
    Img.Masked:=true;
    Img.SetSize(w,h);
    Img.Canvas.Brush.Style:=bsSolid;
    Img.Canvas.Brush.Color:=clWhite;
    Img.Canvas.FillRect(0,0,w,h);
    Img.Canvas.Font:=Canvas.Font;
    Img.Canvas.TextOut(0,0,TheText);
    // получаем картинку из памяти
    IntfImg:=Img.CreateIntfImage;
    // заменяем серые пиксели
    FontColor:=ColorToRGB(Canvas.Font.Color);
    for dy:=0 to h-1 do begin
      for dx:=0 to w-1 do begin
        col:=IntfImg.Colors[dx,dy];
        c:=FPColorToTColor(col);
        if c<>FontColor then
          IntfImg.Colors[dx,dy]:=colTransparent;
      end;
    end;
    // создаем растровую картинку
    Img.LoadFromIntfImage(IntfImg);
    // рисуем ее на холсте
    Canvas.Draw(x,y,Img);
  finally
    IntfImg.Free;
    Img.Free;
  end;
end;