TCanvas/ru

From Free Pascal wiki

English (en) русский (ru)

Класс TCanvas является базовым инструментом для рисования графики.

Для рисования линий, прямоугольников и текста используются TPen, TBrush и TFont, чтобы определить размер и цвет карандаша, стиль и цвет кисти, стиль и цвет шрифта.

текст TextOut( txt ); TextOutXY( x, y, txt )
линии Line( x1, y1, x2, y2 ); LineTo( x, y ) with MoveTo(x, y )
прямоугольник Rectangle( l, t, r, b ); Rectangle( R: TRect ); FillRect()
окружность (эллипс) Ellipse( l, t, r, b ); Ellipse( R: TRect )


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

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

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
    // paint text to a bitmap
    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);
    // get memory image
    IntfImg:=Img.CreateIntfImage;
    // replace gray pixels
    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;
    // create bitmap
    Img.LoadFromIntfImage(IntfImg);
    // paint
    Canvas.Draw(x,y,Img);
  finally
    IntfImg.Free;
    Img.Free;
  end;
end;