Using Canvas.MoveTo()
and Canvas.LineTo()
like you are doing will work just fine. You just need to constrain the drawing of the line inside of the ellipse so anything you draw outside of the ellipse won't be seen.
You can apply an elliptical clipping region to the Canvas
before drawing the line, using the Win32 API CreateEllipticRgn()
and SelectClipRgn()
functions, eg:
// draw the actual ellipse first...
Bmp.Canvas.Ellipse(0, 0, Bmp.Width, Bmp.Height);
// then create a region to match the ellipse...
Rgn := CreateEllipticRgn(0, 0, Bmp.Width, Bmp.Height);
try
SelectClipRgn(Bmp.Canvas.Handle, Rgn);
try
// then draw the line inside the region...
Bmp.Canvas.MoveTo(0, 0);
Bmp.Canvas.LineTo(Bmp.Width, Bmp.Height);
finally
SelectClipRgn(Bmp.Canvas.Handle, 0);
end;
finally
DeleteObject(Rgn);
end;
Alternatively, you can apply an elliptical clipping path instead, using the Win32 API BeginPath()
, EndPath()
, and SelectClipPath()
functions, eg:
// draw the actual ellipse first...
Bmp.Canvas.Ellipse(0, 0, Bmp.Width, Bmp.Height);
// then create a path to match the ellipse...
BeginPath(Bmp.Canvas.Handle);
try
Bmp.Canvas.Ellipse(0, 0, Bmp.Width, Bmp.Height);
finally
EndPath(Bmp.Canvas.Handle);
end;
SelectClipPath(Bmp.Canvas.Handle, RGN_COPY);
// then draw the line inside the path...
Bmp.Canvas.MoveTo(0, 0);
Bmp.Canvas.LineTo(Bmp.Width, Bmp.Height);
See Clipping Overview on MSDN for more details.
For example:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls;
type
TForm1 = class(TForm)
Image1: TImage;
Image2: TImage;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
Bmp: TBitmap;
Rgn: HRGN;
begin
Bmp := TBitmap.Create;
try
Bmp.SetSize(Image1.Width, Image1.Height);
Bmp.Canvas.Brush.Color := clWhite;
Bmp.Canvas.FillRect(Rect(0, 0, Bmp.Width, Bmp.Height));
Bmp.Canvas.Pen.Color := clRed;
Bmp.Canvas.Pen.Width := 5;
// draw the actual ellipse first...
Bmp.Canvas.Ellipse(0, 0, Bmp.Width, Bmp.Height);
// then create a region to match the ellipse...
Rgn := CreateEllipticRgn(0, 0, Bmp.Width, Bmp.Height);
try
SelectClipRgn(Bmp.Canvas.Handle, Rgn);
try
// then draw the line inside the region...
Bmp.Canvas.MoveTo(0, 0);
Bmp.Canvas.LineTo(Bmp.Width, Bmp.Height);
finally
SelectClipRgn(Bmp.Canvas.Handle, 0);
end;
finally
DeleteObject(Rgn);
end;
Image1.Picture.Assign(Bmp);
finally
Bmp.Free;
end;
Bmp := TBitmap.Create;
try
Bmp.SetSize(Image2.Width, Image2.Height);
Bmp.Canvas.Brush.Color := clWhite;
Bmp.Canvas.FillRect(Rect(0, 0, Bmp.Width, Bmp.Height));
Bmp.Canvas.Pen.Color := clRed;
Bmp.Canvas.Pen.Width := 5;
// draw the actual ellipse first...
Bmp.Canvas.Ellipse(0, 0, Bmp.Width, Bmp.Height);
// then create a path to match the ellipse...
BeginPath(Bmp.Canvas.Handle);
try
Bmp.Canvas.Ellipse(0, 0, Bmp.Width, Bmp.Height);
finally
EndPath(Bmp.Canvas.Handle);
end;
SelectClipPath(Bmp.Canvas.Handle, RGN_COPY);
// then draw the line inside the path...
Bmp.Canvas.MoveTo(0, 0);
Bmp.Canvas.LineTo(Bmp.Width, Bmp.Height);
Image2.Picture.Assign(Bmp);
finally
Bmp.Free;
end;
end;
end.
