DrawWrappedText

function DrawWrappedText(image: TImage32; const rec: TRect; const text: string; fontInfo: TFontInfo; textAlign: TTextAlign = taJustify; textVAlign: TTextVAlign = taTop; textColor: TColor32 = clBlack32; lineSpacing: double = DEFAULT; paraSpacing: double = DEFAULT): TPointD;

function DrawWrappedText_LCD(image: TImage32; const rec: TRect; const text: string; fontInfo: TFontInfo; textAlign: TTextAlign = taJustify; textVAlign: TTextVAlign = taTop; textColor: TColor32 = clBlack32; lineSpacing: double = DEFAULT; paraSpacing: double = DEFAULT): TPointD;

Line spacing is spacing between lines relative to line height. Default line spacing = line height / 3.
Paragraph spacing is spacing between paragraphs (relative to line height) that's in addition to any line spacing. Default paragraph spacing = line spacing.

uses Image32, Image32_PNG, Image32_Text;
...
const
  nonesense =
  'Lorem ipsum dolor sit amet, ' +
  'consectetur adipiscing elit, '+
  'sed do eiusmod tempor incididunt '+
  'ut labore et dolore magna aliqua.'+ #10+
  'Risus sed vulputate odio ut enim '+
  'blandit.';  
  m = 15;
var
  lf: TLogFont;
begin
  lf := DefaultLogfont;
  lf.lfFaceName := 'Segoe UI';
  lf.lfHeight := DPI(-10);

  img.SetSize(320,256, clWhite32);
  //draw a faint outline box
  DrawLine(img, Rectangle(img.Bounds), 
    1, clSilver32, esClosed);
  //draw some text 
  DrawWrappedText_LCD(img, 
    Rect(m, m, img.Width-m, img.Height-m),
    nonesense, GetFontInfo(lf), 
    taJustify, tvaMiddle);
  img.SaveToFile('text_justify.png');
      
nb: The image above will look blurry on high resolution displays. That's because the image will have been stretched* which spoils the rendered text's appearance. (*When font scaling is employed, eg when font size is > 100% in Windows Display Settings, not only will font sizes increase, but most applications (including web browsers) will stretch images by a similar amount.)