delphiwinapicanvastext-width

Calculating text width including space / kerning between characters using Delphi


I have troubles finding any resources that explain how to calculate the text width of a string with different kearning / space-between characters.

Textwidth can use the font size, font styles etc. but not space between characters? (Or kerning which I believe is very font specific, i.e. gives different pixel values depend on the font since characters since they can "overlap" more or less depending on the kerning/spacing value)


Solution

  • Edit: Recommended reading: Feng Yuan "Windows Graphics Programming"

    Example of TextWidth (GetTextExtentPoint32) and more complex method:

    var
      Len, w: Integer;
      s: string;
      GR: TGCPResults;
    begin
      Canvas.Font.Size := 14;
      s := 'A simple test string';
      Canvas.TextOut(0, 0, s);
      w := Canvas.TextWidth(s);
      Canvas.MoveTo(w, 0);
      Canvas.LineTo(w, 30);
    
      SetTextCharacterExtra(Canvas.Handle, 5);
      Canvas.TextOut(0, 30, s);
      w := Canvas.TextWidth(s);
      Canvas.MoveTo(w, 30);
      Canvas.LineTo(w, 60);
    
      SetTextCharacterExtra(Canvas.Handle, 0);
      Len := Length(s);
      GR.lStructSize := sizeOf(GR);
      GetMem(GR.lpOutString, (Len + 1) * sizeOf(Char));
      GR.lpOrder := Nil;
      GetMem(GR.lpDx, (Len + 1) * sizeOf(Integer));
      GetMem(GR.lpCaretPos, (Len + 1) * sizeOf(Integer));
      GR.lpClass := Nil;
      GetMem(GR.lpGlyphs, (Len + 1) * sizeOf(UINT));
      GR.nGlyphs := Len;
      GR.nMaxFit := 0;
    
      w := GetCharacterPlacement(Canvas.Handle, PwideChar(s), Len, 0, GR,
        GCP_USEKERNING) and $FFFF;
      ExtTextOut(Canvas.Handle, 0, 60, ETO_GLYPH_INDEX, nil, PChar(GR.lpGlyphs),
        GR.nGlyphs, PINteger(GR.lpDx));
      Canvas.MoveTo(w, 60);
      Canvas.LineTo(w, 90);
      // free memory for GR members