Recent

Author Topic: [SOLVED] Changing Font.Name raises exception.  (Read 3524 times)

JCobb

  • New Member
  • *
  • Posts: 15
[SOLVED] Changing Font.Name raises exception.
« on: April 08, 2018, 10:36:33 am »
When I try to change Canvas.Font.Name before sending text to it I get:
Project proj_rawdisplay raised exception class 'External: SIGSEGV'...

Actually I get this error whenever I change the Name of any font.  All the examples I've looked at online use the Font.Name property for changing the font.  Is there some reason this wouldn't work?

The code is pretty long but here's the test code I've been using to work the problem:
Code: Pascal  [Select][+][-]
  1. function THexDisplay.DetectMonospace(fontStr: string) : boolean;
  2. var
  3.   w1,w2  : integer;
  4.   HFont  : TFont;
  5.  
  6. begin
  7.     HFont.Create;
  8.     with HRawDisplay do
  9.      with Rimg do
  10.       begin
  11.          HFont.Assign(Canvas.Font);
  12.          HFont.Name:='Monospace';
  13.          Canvas.Font.Assign(HFont);
  14.              w1 := Canvas.TextWidth('M');
  15.              w2 := Canvas.TextWidth('i');
  16.              DetectMonoSpace := (w1 = w2);
  17.           end;
  18.  
  19. end;

I've tried with and without HFont.Create.  I've tried using Assign or just HFont := Canvas.Font, etc.

HRawDisplay is a TGraphicControl class in another unit.  I've tried creating a local bitmap for this unit but it fails just as well.

Essentially what I'm trying to do is make certain that a Monospace font is selected for the control just in case the default font is NOT monospace.  Using "IsMonospace" doesn't return useful results so I'm checking TextWidth which seems to work fine... At least until I try to change the Font.Name.

In this case "Monospace" is a font that's available on my Linux system but it's not available on my Windows system.  So I want to find the next best usable monospace font and use that instead.

Thanks in advance,
Jeff

« Last Edit: April 08, 2018, 11:51:06 pm by JCobb »

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Changing Font.Name raises exception.
« Reply #1 on: April 08, 2018, 10:50:55 am »
I hope so otherwise it would be scary.
In short hfont is an empty variable, what ever value it has, is invalid. you need to initialize it. Depending on your needs you can do
Code: Pascal  [Select][+][-]
  1. function THexDisplay.DetectMonospace(fontStr: string) : boolean;
  2. var
  3.   w1,w2  : integer;
  4.   HFont  : TFont;
  5. begin
  6.   HFont := Canvas.Font;
  7.   .
  8.   .
  9.   .
  10. end;
  11.  
this will create an reference to the canvas' own font variable, any change to the HFont is made to the canvas.font directly.
if you want to create a copy of the canvas.font then you do something along the lines of.
Code: Pascal  [Select][+][-]
  1. function THexDisplay.DetectMonospace(fontStr: string) : boolean;
  2. var
  3.   w1,w2  : integer;
  4.   HFont  : TFont;
  5.  
  6. begin
  7.   HFont := TFont.create;
  8.   try
  9.   HFont.Assign(Canvas.Font);
  10.   .
  11.   .
  12.   .
  13.   finally
  14.     HFont.Free;
  15.   end;
  16. end;
  17.  
This creates a copy of what property values the canvas.font has. Any change to hfont is local only.
Now when you assign hfont to canvas.font the property setter is smart enough to call the assign method eg
Code: Pascal  [Select][+][-]
  1.   canvas.Font := HFont;
  2.  
is the same as
Code: Pascal  [Select][+][-]
  1.   canvas.Font.Assign(HFont)
  2.  
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Cyrax

  • Hero Member
  • *****
  • Posts: 836
Re: Changing Font.Name raises exception.
« Reply #2 on: April 08, 2018, 10:51:31 am »
You are creating instance of TFont class in wrong way.

Change
Code: Pascal  [Select][+][-]
  1.  HFont.Create;
to
Code: Pascal  [Select][+][-]
  1.  HFont := TFont.Create;

Then there should be no exceptions anymore.

jamie

  • Hero Member
  • *****
  • Posts: 6130
Re: Changing Font.Name raises exception.
« Reply #3 on: April 08, 2018, 04:05:35 pm »
My docs tells me that TFont.Pitch := fpFixed will force the font handler system to locate a font with a fixed
pitch..

 At less this works in Windows, not sure if that is also supported in other widgets?

 In the case of windows, it would most likely use "Courier".
The only true wisdom is knowing you know nothing

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: Changing Font.Name raises exception.
« Reply #4 on: April 08, 2018, 04:16:23 pm »
My docs tells me that TFont.Pitch := fpFixed will force the font handler system to locate a font with a fixed
pitch..

 At less this works in Windows, not sure if that is also supported in other widgets?

 In the case of windows, it would most likely use "Courier".
How did you test this? If I add a TLabel to a form, set its Font.Pitch to fpFixed and run, nothing changes regarding the label's font. And this is the experience that I've always been having.

dsiders

  • Hero Member
  • *****
  • Posts: 1080
Re: Changing Font.Name raises exception.
« Reply #5 on: April 08, 2018, 05:59:14 pm »

My docs tells me that TFont.Pitch := fpFixed will force the font handler system to locate a font with a fixed
pitch..

 At less this works in Windows, not sure if that is also supported in other widgets?

 In the case of windows, it would most likely use "Courier".

How did you test this? If I add a TLabel to a form, set its Font.Pitch to fpFixed and run, nothing changes regarding the label's font. And this is the experience that I've always been having.

What I see on On Windows 8.1:

It has no effect if a value has been assigned to TFont.Name (even the value Default). When TFont.Name is blank, changing TFont.Pitch selects the default monospace font.
« Last Edit: April 08, 2018, 06:00:48 pm by dsiders »
Preview Lazarus 3.99 documentation at: https://dsiders.gitlab.io/lazdocsnext

jamie

  • Hero Member
  • *****
  • Posts: 6130
Re: Changing Font.Name raises exception.
« Reply #6 on: April 08, 2018, 07:09:29 pm »
Yes, that is how I did the test, I just used a local TFont to test with..

I didn't know the NAME had to be cleared, in my case it was already cleared so I guess it work :)

P.S.
  I tested this on my old W2k PC, now on my Win10 and it did it with old D3...

« Last Edit: April 08, 2018, 07:11:50 pm by jamie »
The only true wisdom is knowing you know nothing

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: Changing Font.Name raises exception.
« Reply #7 on: April 08, 2018, 10:57:18 pm »
IIRC you can use EnumFontFamiliesEX to retreive mono-space fonts.
I did once, but cannot find that code anymore (catastophic harddisk failure).
Note: this was on Windows, not sure *nix worked as well.

Bart

JCobb

  • New Member
  • *
  • Posts: 15
Re: Changing Font.Name raises exception.
« Reply #8 on: April 08, 2018, 11:50:38 pm »
Turns out Assign versus := and knowing which did what was giving me one problem.

Another stems from a resized dynamic array not being large enough.  But instead of getting this notice I was getting an exception.  :(

Everything works now.

Thanks for the help!
Jeff
« Last Edit: April 08, 2018, 11:52:11 pm by JCobb »

 

TinyPortal © 2005-2018