Recent

Author Topic: Change a property of Canvas.TextStyle directly  (Read 3452 times)

kinlion

  • New Member
  • *
  • Posts: 45
  • I Love Lazarus
Change a property of Canvas.TextStyle directly
« on: November 27, 2018, 12:42:33 pm »
If you want to change a property of canvas's text-style directly like this:

Code: Pascal  [Select]
  1. ACanvas.TextStyle.Alignment := taRightJustify;

FPC will tell you it's forbidden, so you have to declare a variable of type TTextStyle.

However, you can do it directly by 'with' clause:
Code: Pascal  [Select]
  1. with ACanvas.TextStyle do Alignment := taRightJustify;

Little weird :o
Lazarus 1.8.4 / FPC 3.0.4 / SVN 57972
On Win10 X64, have to compile for Win32

wp

  • Hero Member
  • *****
  • Posts: 6234
Re: Change a property of Canvas.TextStyle directly
« Reply #1 on: November 27, 2018, 01:57:34 pm »
Are you sure that you don't change another "Alignment"? "With" is dangerous!
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

Blaazen

  • Hero Member
  • *****
  • Posts: 2782
  • POKE 54296,15
    • Eye-Candy Controls
Re: Change a property of Canvas.TextStyle directly
« Reply #2 on: November 27, 2018, 02:29:33 pm »
Yes, weird. TextStyle is public property. And TTextStyle is record.
Lazarus 2.1.0 r59757M FPC 3.3.1 r40507 x86_64-linux-qt Chakra, Qt 4.8.7/5.11.2, Plasma 5.14.2
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

lucamar

  • Hero Member
  • *****
  • Posts: 2021
Re: Change a property of Canvas.TextStyle directly
« Reply #3 on: November 27, 2018, 02:49:17 pm »

And there's no Set function: setting it accesses directly a field.


Are you sure that you don't change another "Alignment"? "With" is dangerous!

I thougt the same but I did a test and the result was ... surprising. Using with allows you to do the change!

Code: Pascal  [Select]
  1.   with lbTest.Canvas.TextStyle do
  2.     Alignment := taRightJustify;
  3.   case lbTest.Canvas.TextStyle.Alignment of
  4.   taLeftJustify  : lbTest.Caption := ' Test: Left aligned';
  5.   taRightJustify : lbTest.Caption := ' Test: Right aligned';
  6.   taCenter       : lbTest.Caption := ' Test: Center aligned';
  7.   end;
  8.  
« Last Edit: November 27, 2018, 03:05:57 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

WooBean

  • Jr. Member
  • **
  • Posts: 89
Re: Change a property of Canvas.TextStyle directly
« Reply #4 on: November 27, 2018, 04:39:50 pm »
Hi,
just one more workaround (after Lucamar's sample)
 
Code: Pascal  [Select]
  1.  
  2. var temp:TTextStyle;
  3. ...
  4.   temp:=lbTest.Canvas.TextStyle;
  5.   temp.Alignment:=taCenter;
  6.   lbTest.Canvas.TextStyle:=temp;
  7.  
  8.   case lbTest.Canvas.TextStyle.Alignment of
  9.   taLeftJustify  : lbTest.Caption := ' Test: Left aligned';
  10.   taRightJustify : lbTest.Caption := ' Test: Right aligned';
  11.   taCenter       : lbTest.Caption := ' Test: Center aligned';
  12.   end;
  13. ...
  14.  
  15.  


It works. But why "with" changes visibility or access rights to records? Interesting. 
-- "with" not "width"  :)

WooBean
« Last Edit: November 27, 2018, 05:28:33 pm by WooBean »
Win7/64, Lazarus 1.8 win64-win64, FPC 3.0.4

kinlion

  • New Member
  • *
  • Posts: 45
  • I Love Lazarus
Re: Change a property of Canvas.TextStyle directly
« Reply #5 on: November 27, 2018, 05:40:32 pm »
Are you sure that you don't change another "Alignment"? "With" is dangerous!

I'm sure.

Since the 'with' simplify many code, I often use it carefully :)
Lazarus 1.8.4 / FPC 3.0.4 / SVN 57972
On Win10 X64, have to compile for Win32

kinlion

  • New Member
  • *
  • Posts: 45
  • I Love Lazarus
Re: Change a property of Canvas.TextStyle directly
« Reply #6 on: November 27, 2018, 05:50:13 pm »
It works. But why "with" changes visibility or access rights to records? Interesting. 
-- "with" not "width"  :)

WooBean

Maybe it's a bug or feature  for the compiler.
But why one can not assign value to a record field? Confused.
A post (I forget where it is) said lower verion of FPC allowed do such a thing, but not the higher version.
Lazarus 1.8.4 / FPC 3.0.4 / SVN 57972
On Win10 X64, have to compile for Win32

ASerge

  • Hero Member
  • *****
  • Posts: 1408
Re: Change a property of Canvas.TextStyle directly
« Reply #7 on: November 28, 2018, 03:20:27 am »
My opinion - it needs to be identified as a bug. By the way, the latest versions of Delphi gives an error in this case.
Example:
Code: Pascal  [Select]
  1. {$APPTYPE CONSOLE}
  2. {$MODE OBJFPC}
  3.  
  4. type
  5.   TSomeRec = record
  6.     S: string;
  7.   end;
  8.  
  9.   TSomeClass = class(TObject)
  10.   strict private
  11.     FDirectData: TSomeRec;
  12.     FHiddenData: TSomeRec;
  13.     function GetHiddenData: TSomeRec;
  14.     procedure SetHiddenData(const AValue: TSomeRec);
  15.   public
  16.     property DirectData: TSomeRec read FDirectData write FDirectData;
  17.     property HiddenData: TSomeRec read GetHiddenData write SetHiddenData;
  18.   end;
  19.  
  20. var
  21.   X: TSomeClass;
  22.   R: TSomeRec;
  23.  
  24. function TSomeClass.GetHiddenData: TSomeRec;
  25. begin
  26.   Writeln('GetHiddenData called');
  27.   Result := FHiddenData;
  28. end;
  29.  
  30. procedure TSomeClass.SetHiddenData(const AValue: TSomeRec);
  31. begin
  32.   Writeln('SetHiddenData called with ', AValue.S);
  33.   FHiddenData := AValue;
  34. end;
  35.  
  36. begin
  37.   X := TSomeClass.Create;
  38.   try
  39.     R.S := '1';
  40.     X.DirectData := R;
  41.     X.HiddenData := R;
  42.     with X.DirectData do
  43.       S := '2';
  44.     Writeln(X.DirectData.S);
  45.     with X.HiddenData do
  46.       S := '3';
  47.     Writeln(X.HiddenData.S);
  48.   finally
  49.     X.Free;
  50.   end;
  51.   Readln;
  52. end.
Code: [Select]
SetHiddenData called with 1
2
GetHiddenData called
GetHiddenData called
1

And trouble. If we change to "property HiddenData: TSomeRec read FHiddenData...", we get a different result
Code: [Select]
SetHiddenData called with 1
2
3

And in any case we will not see 'SetHiddenData called with 3'!

Zoran

  • Hero Member
  • *****
  • Posts: 1460
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: Change a property of Canvas.TextStyle directly
« Reply #8 on: November 28, 2018, 09:05:05 am »
Maybe it's a bug or feature  for the compiler.
But why one can not assign value to a record field? Confused.
A post (I forget where it is) said lower verion of FPC allowed do such a thing, but not the higher version.

It's forbidden since fpc 2.4, see here why: http://wiki.freepascal.org/User_Changes_2.4.0#Treating_direct-mapped_properties_as_regular_fields


WooBean

  • Jr. Member
  • **
  • Posts: 89
Re: Change a property of Canvas.TextStyle directly
« Reply #9 on: November 28, 2018, 10:30:45 am »

OK,

Coming back to the start of thread, TCanvas class is defined as
Code: Pascal  [Select]
  1. TCanvas = class(TFPCustomCanvas)
  2.   private
  3.     ...
  4.     FTextStyle: TTextStyle;
  5.     ...
  6.   protected
  7.     ...
  8.   public
  9.     constructor Create;
  10.     destructor Destroy; override;
  11.     ...
  12.   public
  13.     ...
  14.     property TextStyle: TTextStyle read FTextStyle write FTextStyle;  
  15.     ...
  16.   published
  17.     ...
  18. end;  
  19.  

So, we can see that  Canvas.TextStyle is a property in which someone is trying directly change a subfield "Alignment" - an operation forbidden by FPC (at least 3.0.4). 
I can understand reasons standing behind the change in FPC since   http://wiki.freepascal.org/User_Changes_2.4.0#Treating_direct-mapped_properties_as_regular_fields.

This explains why we can assign all TextStyle record to Canvas and cannot TextStyle.Alignment.

But the change was not propagated to language construction with "with" clause.
My guess is that this is FPC bug - not critical but it makes non-consistency in Pascal code parsing.

WooBean
Win7/64, Lazarus 1.8 win64-win64, FPC 3.0.4

kinlion

  • New Member
  • *
  • Posts: 45
  • I Love Lazarus
Re: Change a property of Canvas.TextStyle directly
« Reply #10 on: November 28, 2018, 02:01:50 pm »
I agree that it's a bug for FPC, and will report it.
Thanks to all, for making it clear :)
Lazarus 1.8.4 / FPC 3.0.4 / SVN 57972
On Win10 X64, have to compile for Win32

kinlion

  • New Member
  • *
  • Posts: 45
  • I Love Lazarus
Re: Change a property of Canvas.TextStyle directly
« Reply #11 on: November 29, 2018, 05:47:45 am »
Silly of me.
This problem has been reported at 2009 :o
Lazarus 1.8.4 / FPC 3.0.4 / SVN 57972
On Win10 X64, have to compile for Win32

Zoran

  • Hero Member
  • *****
  • Posts: 1460
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: Change a property of Canvas.TextStyle directly
« Reply #12 on: November 29, 2018, 07:50:37 am »
Silly of me.
This problem has been reported at 2009 :o

No, it's not silly.  One more duplicate bug report will make no harm.
You encountered a real bug and you reported it, that is the best you can do.
Yes, strangely, it was identified nine years ago, but not fixed yet.

PS. When you report a bug after discussing it in forum, when you say "I reported it", it's good to give a link here :)
Here it is: https://bugs.freepascal.org/view.php?id=34615

kinlion

  • New Member
  • *
  • Posts: 45
  • I Love Lazarus
Re: Change a property of Canvas.TextStyle directly
« Reply #13 on: November 30, 2018, 01:58:35 pm »
PS. When you report a bug after discussing it in forum, when you say "I reported it", it's good to give a link here :)
Here it is: https://bugs.freepascal.org/view.php?id=34615

Yes, a link makes more convenient  :)
Lazarus 1.8.4 / FPC 3.0.4 / SVN 57972
On Win10 X64, have to compile for Win32

kinlion

  • New Member
  • *
  • Posts: 45
  • I Love Lazarus
Re: Change a property of Canvas.TextStyle directly
« Reply #14 on: November 30, 2018, 02:21:16 pm »
Yes, strangely, it was identified nine years ago, but not fixed yet.

My understanding:
Canvas.Textstyle returns a Record, NOT a Object.
If a function's return value is a Record, FPC returns a COPY of the original one, i.e. a copy of Canvas.FTextStyle in this case, Not a reference to the Canvas.FTextStyle itself.
So if we write:
Code: Pascal  [Select]
  1. with Canvas.TextStyle do Alignment := taRightJustify;
It equals to:
Code: Pascal  [Select]
  1. tmp := Canvas.TextStyle;
  2. tmp.Alignment := taRightJustify;
That's meaningless, and apparently NOT what we want. So, it's reasonable that FPC forbids this behavior.
It can also explains someone reported that the assignment has no effect with lower version of FPC, although allowed.
Lazarus 1.8.4 / FPC 3.0.4 / SVN 57972
On Win10 X64, have to compile for Win32