The first two parameters of the Canvas.TextOut method denote the x and y coordinates of the point where the top/left corner of the text given as third argument is printed. So, when you want to reserve a top margin do not begin drawing at y = 0 but at the value corresponding to the top margin. But note: the pixels on the printer are much denser than on the screen (usually). The printer has properties XDPI and YDPI (dpi = dots per inch) which you can use to convert a given distance to pixels. The following function converts millimeters to pixel count:
function mmToPx(mm: Double; PPI: Integer): Integer;
var
inches: Double;
begin
inches := mm/25.4;
Result := round(inches * PPI);
end;
Basically you can use the PageSetupDialog's MarginLeft/Top/Right/Bottom values here which are displayed as millimeters on my system; looking at it with the debugger, however, I saw that the actually returned values are millimeters multiplied by 100. And there is a property Units (pmDefault, pmMillimeters, pmInches) which suggests that there may be more complicated cases in general - I did not investigate this.
Find in the attachment a small project which prints a memo and uses the PageSetupDialog's margins. It is a bit special (and thus more complicated) because it automatically tries to wordwrap the lines of the memo, certainly not perfect in all cases, but good enough for the demo's dummy text.