Recent

Author Topic: Question about TFONT.Handle  (Read 483 times)

jamie

  • Hero Member
  • *****
  • Posts: 6734
Question about TFONT.Handle
« on: September 21, 2024, 08:08:43 pm »
I have many LogFont records being used as list of fonts selected via the user.

I can use the "CreateFontIndirect(lf)" and use that Handle to set the Handle of TFOnt.Handle;

The question is this, who owns the handle and what happens to the Handle that is currently there being overwritten ?

The only true wisdom is knowing you know nothing

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1428
    • Lebeau Software
Re: Question about TFONT.Handle
« Reply #1 on: September 21, 2024, 09:36:28 pm »
The question is this, who owns the handle and what happens to the Handle that is currently there being overwritten ?

I can't find the source code for TFont in my download of FPC/Lazarus sources.

In Delphi, the resource management is a bit complicated, but essentially TFont maintains a cache of HFONTs that it creates internally with CreateFontIndirect(). When you assign an existing HFONT to the TFont.Handle, the LOGFONT is extracted via GetObject() and compared to the cache. If a match is found then the cached HFONT is used, otherwise a new HFONT is created and cached.  So either way, TFont uses only HFONTs that it creates for itself, and any HFONT you assign remains your responsibility.

I'm guessing FPC/Laz does something similar?
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

dsiders

  • Hero Member
  • *****
  • Posts: 1282
Re: Question about TFONT.Handle
« Reply #2 on: September 21, 2024, 09:46:04 pm »
The question is this, who owns the handle and what happens to the Handle that is currently there being overwritten ?

I can't find the source code for TFont in my download of FPC/Lazarus sources.

In Lazarus TFont is an alias to TFPCustomFont located in packages/fcl-image/src/fpcanvas.pp.

Preview the next Lazarus documentation release at: https://dsiders.gitlab.io/lazdocsnext

jamie

  • Hero Member
  • *****
  • Posts: 6734
Re: Question about TFONT.Handle
« Reply #3 on: September 21, 2024, 11:06:05 pm »
The question is this, who owns the handle and what happens to the Handle that is currently there being overwritten ?

I can't find the source code for TFont in my download of FPC/Lazarus sources.

In Delphi, the resource management is a bit complicated, but essentially TFont maintains a cache of HFONTs that it creates internally with CreateFontIndirect(). When you assign an existing HFONT to the TFont.Handle, the LOGFONT is extracted via GetObject() and compared to the cache. If a match is found then the cached HFONT is used, otherwise a new HFONT is created and cached.  So either way, TFont uses only HFONTs that it creates for itself, and any HFONT you assign remains your responsibility.

I'm guessing FPC/Laz does something similar?

Ok, Then that means I should be able to create it, assign to the FONT.Handle and then deleteobject of the recently created and TFONT should be happy with its new duplicate.
 We will need to experiment a little on this.

 The other alternative is to create a Assignment method to use a Logfont to assign a currently active FONT, I noticed there isn't any such method in the TFONT class that can assign a LogFont to it.

The only true wisdom is knowing you know nothing

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1428
    • Lebeau Software
Re: Question about TFONT.Handle
« Reply #4 on: September 21, 2024, 11:35:43 pm »
In Lazarus TFont is an alias to TFPCustomFont located in packages/fcl-image/src/fpcanvas.pp.

Thanks, but where is that alias defined?  Searching the entire source, I don't see a single mention of TFont anywhere.

Looking at TFPCustomFont, I don't see a Handle property.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

dsiders

  • Hero Member
  • *****
  • Posts: 1282
Re: Question about TFONT.Handle
« Reply #5 on: September 22, 2024, 12:17:30 am »
In Lazarus TFont is an alias to TFPCustomFont located in packages/fcl-image/src/fpcanvas.pp.

Thanks, but where is that alias defined?  Searching the entire source, I don't see a single mention of TFont anywhere.

Looking at TFPCustomFont, I don't see a Handle property.

Sorry... not an alias. It's definmed in the derived class in lcl/graphics.pp. My bad.

Code: Pascal  [Select][+][-]
  1.   TFont = class(TFPCustomFont)
  2.   private
  3.     FIsMonoSpace: boolean;
  4.     FIsMonoSpaceValid: boolean;
  5.     FOrientation: Integer;
  6.     FPitch: TFontPitch;
  7.     FQuality: TFontQuality;
  8.     FStyle: TFontStylesBase;
  9.     FCharSet: TFontCharSet;
  10.     FPixelsPerInch: Integer;
  11.     FUpdateCount: integer;
  12.     FChanged: boolean;
  13.     FFontHandleCached: boolean;
  14.     FColor: TColor;
  15.     FHeight: integer; // FHeight = -(FSize * FPixelsPerInch) div 72
  16.     FReference: TWSFontReference;
  17.     procedure FreeReference;
  18.     function GetHandle: HFONT;
  19.     function GetData: TFontData;
  20.     function GetIsMonoSpace: boolean;
  21.     function GetReference: TWSFontReference;
  22.     function IsHeightStored: boolean;
  23.     function IsNameStored: boolean;
  24.     procedure SetData(const FontData: TFontData);
  25.     procedure SetHandle(const Value: HFONT);
  26.     procedure ReferenceNeeded;
  27.     procedure SetPixelsPerInch(const APixelsPerInch: Integer);
  28.   protected
  29.     function GetCharSet: TFontCharSet;
  30.     function GetHeight: Integer;
  31.     function GetName: string;
  32.     function GetOrientation: Integer;
  33.     function GetPitch: TFontPitch;
  34.     function GetSize: Integer;
  35.     function GetStyle: TFontStyles;
  36.     procedure Changed; override;
  37.     procedure DoAllocateResources; override;
  38.     procedure DoCopyProps(From: TFPCanvasHelper); override;
  39.     procedure DoDeAllocateResources; override;
  40.     procedure SetCharSet(const AValue: TFontCharSet);
  41.     procedure SetColor(const NewColor: TColor; const NewFPColor: TFPColor); virtual;
  42.     procedure SetColor(Value: TColor);
  43.     function GetColor: TColor;
  44.     procedure SetFlags(Index: integer; AValue: boolean); override;
  45.     procedure SetFPColor(const AValue: TFPColor); override;
  46.     procedure SetHeight(Avalue: Integer);
  47.     procedure SetName(AValue: string); override;
  48.     procedure SetOrientation(AValue: Integer); override; // This was introduced in 2.5 quite late, and the Android pre-compiled compiler was before this, so I prefer to let it only for 2.6
  49.     procedure SetPitch(Value: TFontPitch);
  50.     procedure SetSize(AValue: integer); override;
  51.     procedure SetStyle(Value: TFontStyles);
  52.     procedure SetQuality(const AValue: TFontQuality);
  53.   public
  54.     constructor Create; override;
  55.     destructor Destroy; override;
  56.     procedure Assign(Source: TPersistent); override;
  57.     procedure Assign(const ALogFont: TLogFont);
  58.     procedure BeginUpdate;
  59.     procedure EndUpdate;
  60.     property FontData: TFontData read GetData write SetData;
  61.     function HandleAllocated: boolean;
  62.     property Handle: HFONT read GetHandle write SetHandle;
  63.     function IsDefault: boolean;
  64.     function IsEqual(AFont: TFont): boolean; virtual;
  65.     property IsMonoSpace: boolean read GetIsMonoSpace;
  66.     procedure SetDefault;
  67.     property PixelsPerInch: Integer read FPixelsPerInch write SetPixelsPerInch;
  68.     property Reference: TWSFontReference read GetReference;
  69.   published
  70.     property CharSet: TFontCharSet read GetCharSet write SetCharSet default DEFAULT_CHARSET;
  71.     property Color: TColor read FColor write SetColor default {$ifdef UseCLDefault}clDefault{$else}clWindowText{$endif};
  72.     property Height: Integer read GetHeight write SetHeight stored IsHeightStored;
  73.     property Name: string read GetName write SetName stored IsNameStored;
  74.     property Orientation: Integer read GetOrientation write SetOrientation default 0;
  75.     property Pitch: TFontPitch read GetPitch write SetPitch default fpDefault;
  76.     property Quality: TFontQuality read FQuality write SetQuality default fqDefault;
  77.     property Size: Integer read GetSize write SetSize stored false;
  78.     property Style: TFontStyles read GetStyle write SetStyle default [];
  79.   end;
  80.  
Preview the next Lazarus documentation release at: https://dsiders.gitlab.io/lazdocsnext

jamie

  • Hero Member
  • *****
  • Posts: 6734
Re: Question about TFONT.Handle
« Reply #6 on: September 22, 2024, 04:41:51 pm »
I looked at the source and apparently the LOGFONT's are being cached in the LCL but not the handles.

The external handle is only used as a reference to get the LOGFONT data when you set the handle but is not managed by TFONT and is not needed afterwards, because TFONT will make a copy of the LOGFONT if one does not exist in the cache.

 The coder must free the handle, because it's not required after the fact.
The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018