Recent

Author Topic: Blurry Rendering of SPKToolbar under cocoa  (Read 8877 times)

ChristianH

  • New Member
  • *
  • Posts: 32
Blurry Rendering of SPKToolbar under cocoa
« on: June 22, 2021, 09:22:33 pm »
Hi,

the font of the spktoolbar looks extremely blurry. Is there something what can be done when it comes to text rendering in third party classes? I saw that virtualtreeview has a couple of "hacks" in order to draw the output in the correct scaling.

Regards
Christian

wp

  • Hero Member
  • *****
  • Posts: 8546
Re: Blurry Rendering of SPKToolbar under cocoa
« Reply #1 on: June 23, 2021, 12:10:28 am »
What is your OS?

In Windows blurry fonts are caused by incorrect compatibility settings. Right-click on the application with the blurry text, select "Properties" > "Compatibility" > "Change High DPI settings". This opens another window where no checkbox is checked on my system. It has also a link into the Windows Settings ("Enhanced scaling settings" (my translation)) where the option "Windows can try to fix blurred presentation" is checked.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1477
  • Former Delphi 1-7, 10.2 user
Re: Blurry Rendering of SPKToolbar under cocoa
« Reply #2 on: June 23, 2021, 04:14:56 am »
What is your OS?

As he's using the Cocoa widgetset, I'd guess macOS ;-)
Lazarus 2.1 r65061 FPC 3.3.1 r49223 macOS 10.14.6 Xcode 11.3.1
Lazarus 2.1 r65182 FPC 3.3.1 r49223 macOS 11.4 aarch64 Xcode 12.4
Lazarus 2.1 r61574 FPC 3.3.1 r42318 FreeBSD 12.1 amd64 VMware VM
Lazarus 2.1 r61574 FPC 3.0.4 Ubuntu 20.04 Parallels VM
Lazarus 2.0.10 FPC 3.2.0 Win10 Parallels VM

wp

  • Hero Member
  • *****
  • Posts: 8546
Re: Blurry Rendering of SPKToolbar under cocoa
« Reply #3 on: June 23, 2021, 10:15:31 am »
As he's using the Cocoa widgetset, I'd guess macOS ;-)
And it's even in the title... Reading every word would be a benefit for me...
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

ChristianH

  • New Member
  • *
  • Posts: 32
Re: Blurry Rendering of SPKToolbar under cocoa
« Reply #4 on: June 23, 2021, 12:06:24 pm »
Big Sur on an M1. I saw that in virtualtreeeview a bunch of tweaks has been done to get it working.

ChrisR

  • Full Member
  • ***
  • Posts: 209
Re: Blurry Rendering of SPKToolbar under cocoa
« Reply #5 on: June 23, 2021, 12:54:55 pm »
All widgets will look blurry on MacOS retina displays unless the Info.plist describes the application as NSHighResolutionCapable. Lazarus will include this setting when you create a new application, but you may want to manually check your Info.plist for this key:value pair:

  <key>NSHighResolutionCapable</key>
  <true/>

ChristianH

  • New Member
  • *
  • Posts: 32
Re: Blurry Rendering of SPKToolbar under cocoa
« Reply #6 on: June 23, 2021, 02:41:58 pm »
Thanks, but this is not the case. The NSHighResolutionCapable property is in the plist.
VirtualTreeview uses CGContextScaleCTM while drawing nodes and headers. I will try to figure it out.

ChristianH

  • New Member
  • *
  • Posts: 32
Re: Blurry Rendering of SPKToolbar under cocoa
« Reply #7 on: June 23, 2021, 03:17:42 pm »
I think I fixed the issue:

procedure TSpkToolbar.ValidateMetrics;
var
  i: integer;
  x: integer;
  TabWidth: integer;
  TabAppearance: TSpkToolbarAppearance;
  MenuButtonWidth: Integer;
  AdditionalPadding: Boolean;
  MenuButtonTextWidth: Integer;
begin
  if FInternalUpdating or FUpdating then
    exit;
  if FMetricsValid then
    exit;

  FBuffer.Free;
  FBuffer := TBitmap.Create;
  {$ifdef LCLCocoa}
   FBuffer.SetSize(round(GetCanvasScaleFactor*Width), round(GetCanvasScaleFactor*CalcToolbarHeight));
   CGContextScaleCTM(TCocoaBitmapContext(FBuffer.Canvas.Handle).CGContext, GetCanvasScaleFactor, GetCanvasScaleFactor);
  {$ELSE}

   FBuffer.SetSize(Width, CalcToolbarHeight);
  {$ENDIF} 

Christian
« Last Edit: June 23, 2021, 03:20:40 pm by ChristianH »

wp

  • Hero Member
  • *****
  • Posts: 8546
Re: Blurry Rendering of SPKToolbar under cocoa
« Reply #8 on: June 23, 2021, 05:05:11 pm »
Thanks. Since your modification is inside an {$IFDEF LCLCocoa} directive it is not harmful for the other widgetsets and I will apply it although I cannot test it (I do not have a mac).

Nevertheless, I think this is only a workaround for a problem which must be deeper inside the canvas because SpkToolbar uses only standard canvas routines to draw the text (Canvas.TextOut) - therefore, text output should be correct for all platforms.

Maybe you can help to further narrow down the issue at least for a bugreport: Create a form and add the following OnPaint handler:
Code: Text  [Select][+][-]
  1. procedure TForm1.FormPaint(Sender: TObject);
  2. begin
  3.   Canvas.Font.Assign(Font);
  4.   Canvas.TextOut(10, 10, 'Hello world');
  5. end;  
When run at high-dpi, is this output blurred?

BTW, do you work with Laz trunk? There's a lot of activity with cocoa, and there is some chance that this issue already has been fixed.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

ChristianH

  • New Member
  • *
  • Posts: 32
Re: Blurry Rendering of SPKToolbar under cocoa
« Reply #9 on: June 23, 2021, 05:42:21 pm »
I assume this problem comes into action when you use a bitmap for buffering. I also had to fix the paint function like this:

{$IFDEF LCLCocoa}
  StretchBlt(canvas.handle,0,0,Width,Height,FBuffer.Canvas.Handle,0,0,
   FBuffer.Width, FBuffer.Height, SRCCOPY);
{$ELSE}
  canvas.draw(0, 0, FBuffer);
{$ENDIF}

and of course in the uses clause there has to be a:

uses
  {$ifdef LCLCocoa}
  CocoaGDIObjects, MacOSAll,
  {$endif}

Christian

wp

  • Hero Member
  • *****
  • Posts: 8546
Re: Blurry Rendering of SPKToolbar under cocoa
« Reply #10 on: June 23, 2021, 07:05:18 pm »
I applied your patch, please test carefully - I could not test myself...
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

ChristianH

  • New Member
  • *
  • Posts: 32
Re: Blurry Rendering of SPKToolbar under cocoa
« Reply #11 on: June 23, 2021, 09:44:01 pm »
Many thanks,

since I use this in a real project which I am currently port to Mac I test this through its paces.

Oh there is one thing I probably did not copied properly:

 SetBounds(Left, Top, FBuffer.Width, FBuffer.Height);

Code: Pascal  [Select][+][-]
  1. procedure TSpkToolbar.ValidateMetrics;
  2. var
  3.   i: integer;
  4.   x: integer;
  5.   TabWidth: integer;
  6.   TabAppearance: TSpkToolbarAppearance;
  7.   MenuButtonWidth: Integer;
  8.   AdditionalPadding: Boolean;
  9.   MenuButtonTextWidth: Integer;
  10.  {$IFDEF LCLCocoa}
  11.   scalefactor: Double;
  12.  {$ENDIF}
  13. begin
  14.   if FInternalUpdating or FUpdating then
  15.     exit;
  16.   if FMetricsValid then
  17.     exit;
  18.  
  19.   FBuffer.Free;
  20.   FBuffer := TBitmap.Create;
  21.  {$IFDEF LCLCocoa}
  22.   scalefactor := GetCanvasScaleFactor;
  23.   FBuffer.SetSize(round(scaleFactor*Width), round(scaleFactor*CalcToolbarHeight));
  24.   CGContextScaleCTM(TCocoaBitmapContext(FBuffer.Canvas.Handle).CGContext, scaleFactor, scaleFactor);
  25.  {$ELSE}
  26.   FBuffer.SetSize(Width, CalcToolbarHeight);
  27.  {$ENDIF}
  28.   SetBounds(Left, Top, Width, CalcToolbarHeight);
The SetBounds should be like if there is no scaling.

Sorry, I forgot to post this line in the previous post.

Christian
« Last Edit: June 23, 2021, 09:56:22 pm by ChristianH »

wp

  • Hero Member
  • *****
  • Posts: 8546
Re: Blurry Rendering of SPKToolbar under cocoa
« Reply #12 on: June 23, 2021, 10:28:46 pm »
This makes sense. You scale the buffer but paint the buffer on the unscaled canvas; therefore the bounds must have the unscaled size.

Fixed.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2618
    • havefunsoft.com
Re: Blurry Rendering of SPKToolbar under cocoa
« Reply #13 on: June 24, 2021, 08:19:04 pm »
I saw that virtualtreeview has a couple of "hacks" in order to draw the output in the correct scaling.
Not a hacks but the adaptation to the designed behavior

What is happening with VirtualTreeView is that the "backbuffer" drawn is "twice" (actually GetCanvasScaleFactor) as large as the "logical" size of the control.
When the backbuffer is drawn it would actually fill out every physical pixel of the screen and would not  be blurred.
« Last Edit: June 24, 2021, 08:22:20 pm by skalogryz »

wp

  • Hero Member
  • *****
  • Posts: 8546
Re: Blurry Rendering of SPKToolbar under cocoa
« Reply #14 on: June 24, 2021, 09:48:46 pm »
I saw that virtualtreeview has a couple of "hacks" in order to draw the output in the correct scaling.
Not a hacks but the adaptation to the designed behavior
Don't blame the OP: Your own word in r63695 commit message "VTV: adding mac Retina support hack.", and in the laz.virtualtrees unit
Code: Pascal  [Select][+][-]
  1. uses
  2.   {$ifdef LCLCocoa}
  3.   MacOSAll, // hack: low-level access to Cocoa drawins is going to be used
  4.             //       in order to support Cocoa HighDPI implementation
;)
« Last Edit: June 24, 2021, 09:50:25 pm by wp »
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

 

TinyPortal © 2005-2018