Recent

Author Topic: Changing the font on a canvas  (Read 759 times)

cov

  • Full Member
  • ***
  • Posts: 244
Changing the font on a canvas
« on: June 24, 2025, 08:51:54 pm »
I'm writing a small CAD application which loads a DXF drawing file.

If the file contains text, it may simply describe the font used as Arial.

I am having a tinker with Graeme Geldenhuis' fpTTF module which claims to cache the installed fonts on the machine (I am using Mate on Manjaro).

As I understand it, I initiate the font cache:
Code: Pascal  [Select][+][-]
  1.   gTTFontCache.SearchPath.Add(ExtractFilePath(ParamStr(0)) + 'fonts/');
  2.   gTTFontCache.BuildFontCache;  

Then I use the name of the font to find it:
Code: Pascal  [Select][+][-]
  1. gTTFontCache.Find('Arial');

However, I am unsure of what happens next.

How do I assign the font to the canvas?

TIA.

wp

  • Hero Member
  • *****
  • Posts: 12927
Re: Changing the font on a canvas
« Reply #1 on: June 25, 2025, 12:06:59 pm »
Which kind of Canvas? A TCanvas as used by the LCL, or a TFPCustomCanvas descendant as used by fcl-image?

cov

  • Full Member
  • ***
  • Posts: 244
Re: Changing the font on a canvas
« Reply #2 on: June 25, 2025, 02:24:44 pm »
Thanks for the response.

Tbitmap.canvas.

Code: Pascal  [Select][+][-]
  1.       img:= TBitmap.Create;
  2.       Img.SetSize(500,500);
  3.       Img.Canvas.Brush.Style := bsSolid;
  4.       Img.Canvas.Brush.Color := clRed;
  5.       img.Canvas.TextOut(0,0,CharacterList);    

Handoko

  • Hero Member
  • *****
  • Posts: 5459
  • My goal: build my own game engine using Lazarus
Re: Changing the font on a canvas
« Reply #3 on: June 25, 2025, 04:07:41 pm »
Try this:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Graphics, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     procedure Button1Click(Sender: TObject);
  17.   end;
  18.  
  19. var
  20.   Form1: TForm1;
  21.  
  22. implementation
  23.  
  24. {$R *.lfm}
  25.  
  26. { TForm1 }
  27.  
  28. procedure TForm1.Button1Click(Sender: TObject);
  29. const
  30.   LinesPerColumn = 20;
  31. var
  32.   Names: array of string;
  33.   X, Y:  Integer;
  34.   i:     Integer;
  35.   S:     string;
  36. begin
  37.   SetLength(Names, Screen.Fonts.Count);
  38.  
  39.   // Load all font names
  40.   for i := 0 to Screen.Fonts.Count-1 do
  41.     Names[i] := Screen.Fonts[i];
  42.  
  43.   // Show it
  44.   for i := 0 to Length(Names)-1 do
  45.   begin
  46.     S := (i+1).ToString + ' ' +  Names[i];
  47.     X := (i div LinesPerColumn) * 200;
  48.     Y := (i mod LinesPerColumn) * 20;
  49.     Canvas.Brush.Color := clForm;
  50.     Canvas.Font.Name := Names[i];
  51.     Canvas.Font.Size := 12;
  52.     Canvas.TextOut(X+50, Y+50, S);
  53.   end;
  54.   Canvas.Font.Name := 'default';
  55.   Canvas.TextOut(120, 15, 'Total installed fonts = ' + Length(Names).toString);
  56.  
  57.  
  58. end;
  59.  
  60. end.

etrusco

  • New Member
  • *
  • Posts: 17
Re: Changing the font on a canvas
« Reply #4 on: June 25, 2025, 04:13:44 pm »
What are you trying to achieve? AFAICS gTTFontCache is only used by fp-pdf. Are you following Google/Gemini (mis)directions? ;)
To list the fonts installed on your system, use Screen.Fonts.
To set the Font face, set Font.Name (or assign from another Font).

wp

  • Hero Member
  • *****
  • Posts: 12927
Re: Changing the font on a canvas
« Reply #5 on: June 25, 2025, 10:09:44 pm »
To my knowledge, 'Arial' is a Windows font, and probably does not exist on your Linux system. You could use the following function FindFontOrReplacement to find the first existing font from a list provided to it:
Code: Pascal  [Select][+][-]
  1. function FindFontOrReplacement(SimilarFonts: String): String;
  2. var
  3.   fonts: TStringArray;
  4.   i: Integer;
  5. begin
  6.   fonts := SimilarFonts.Split([',', ';', #13, #10, #9]);  // Allowed separators in the font list
  7.   for i := 0 to High(fonts) do
  8.     if Screen.Fonts.IndexOf(trim(fonts[i])) > 0 then
  9.     begin
  10.       Result := fonts[i];
  11.       exit;
  12.     end;
  13.   Result := '';
  14. end;
  15.  
  16. procedure TForm1.Button1Click(Sender: TObject);
  17. const
  18.   CharacterList: String = 'abcdefghijklmnopqrstuvwxyz';
  19. var
  20.   img: TBitmap;
  21. begin
  22.   img:= TBitmap.Create;
  23.   img.SetSize(300,100);
  24.   img.Canvas.Brush.Style := bsSolid;
  25.   img.Canvas.Brush.Color := clRed;
  26.   img.Canvas.Font.Name := FindFontOrReplacement('Arial;Liberation Sans;Noto Sans');
  27.   img.Canvas.TextOut(0,0,CharacterList);
  28.   Image1.Picture.Assign(img);
  29.   Image1.Width := img.Width;
  30.   Image1.Height := img.Height;
  31.   img.Free;
  32. end;
In this example, the img.Canvas.Font is either 'Arial' or 'Liberation Sans' or 'Noto Sans' depending on which one of them is found first among the Screen.Fonts list.

cov

  • Full Member
  • ***
  • Posts: 244
Re: Changing the font on a canvas
« Reply #6 on: June 26, 2025, 11:10:09 am »
Thanks.

Yes, Arial needs to be replaced with the closest font on the user's system.

Your code looks great.

I'll give it a try.

 

TinyPortal © 2005-2018