I want to draw a dotted grid on a TPaintbox canvas in a Firemonkey project, the outcome should be exactly like this:
To start with I thought I would draw the vertical dotted lines and then the horizontal dotted lines, so with that in mind I attempted to draw a single line first in attempt to get the appearance just right, this is what I tried:
Canvas.Stroke.Color := TAlphaColorRec.Black;
Canvas.Stroke.Dash := TStrokeDash.Dot;
Canvas.Stroke.Kind := TBrushKind.Solid;
Canvas.Stroke.Thickness := 1;
Canvas.DrawLine(PointF(0, 0), PointF(0, 150), 1);
The result is not what I had hoped, in fact the TLine
shape can do a dotted line how I want it to:
But I need to do this drawing myself on the canvas and not use additional controls. For the record TLine
simply needs the Stroke.Dash property changing to Dot.
So, using the canvas in a Firemonkey project how may I draw a dotted line the same as TLine
does so that I can draw a grid like the first sample image?
Without going into the 'why it works' you can achieve 1 pixel dotted line (like in TLine
) by adding (or subtracting) half the line width to the coordinates. I got the idea when tracing through what TLine
does; during rendering it uses
InflateRect(Result, -(FStroke.Thickness / 2), -(FStroke.Thickness / 2));
Applying the 0.5 modification to the line coordinates, gives the same result.
procedure TForm24.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
var
a: integer;
begin
Canvas.BeginScene;
try
Canvas.Stroke.Dash := TStrokeDash.Dot;
for a := 0 to 10 do
Canvas.DrawLine(PointF(a * 20 + 0.5, 0.5), PointF(a * 20 + 0.5, 200.5), 1);
for a := 0 to 10 do
Canvas.DrawLine(PointF(0.5, a * 20 + 0.5), PointF(200.5, a * 20 + 0.5), 1);
Canvas.DrawLine(PointF(0.5, 0.5), PointF(200.5, 200.5), 1);
Canvas.DrawEllipse(RectF(5.0, 5.0, 195.5, 195.5), 1);
finally
Canvas.EndScene;
end;
end;
produces this result:
Magnifier view is 500%
Edit 2018.02.23:
An alternative way, worth to test, is to change the forms Quality
property to HighPerformance