Recent

Author Topic: BGRABitmap - System font  (Read 12889 times)

Dibo

  • Hero Member
  • *****
  • Posts: 1046
BGRABitmap - System font
« on: April 15, 2012, 06:42:27 pm »
Hi,

How works fonts in bgrabitmap? I want my font has the same typeface and size as the system font, but even when I set height from canvas TextHeight, BGRA font is bigger and looks different (see attached screen). This is my test code:
Code: [Select]
procedure TForm1.FormPaint(Sender: TObject);
var b: TBGRABitmap;
begin
  b := TBGRABitmap.Create(120,100);
  b.FontName := Canvas.Font.Name;
  b.FontHeight := Canvas.TextHeight('Test (BGRA)');
  b.TextOut(25,25,'Test (BGRA)', BGRABlack);
  b.Draw(Self.Canvas,0,0,False);
  b.Free;

  Canvas.Brush.Style := bsClear;
  Canvas.TextOut(25,50,'Test (Canvas)');
end; 

Regards

lainz

  • Guest
Re: BGRABitmap - System font
« Reply #1 on: April 15, 2012, 07:45:59 pm »
circular say something about using negative font height

also check this, not related to height but font conversion

Code: [Select]
procedure AssignFontToBGRA(Source: TFont; Dest: TBGRABitmap);
begin
  Dest.FontAntialias := True;

  Dest.FontName := Source.Name;
  Dest.FontStyle := Source.Style;
  Dest.FontOrientation := Source.Orientation;

  case Source.Quality of
    fqNonAntialiased: Dest.FontQuality := fqSystem;
    fqAntialiased: Dest.FontQuality := fqFineAntialiasing;
    fqProof: Dest.FontQuality := fqFineClearTypeRGB;
    fqDefault, fqDraft, fqCleartype, fqCleartypeNatural: Dest.FontQuality :=
        fqSystemClearType;
  end;

  Dest.FontHeight := Source.Height;

  //if (Dest.FontQuality = fqFineAntialiasing) or (Dest.FontQuality =
  //  fqFineClearTypeRGB) and (Dest.FontHeight = 0) then
  //  Dest.FontHeight := round(Source.GetTextHeight('QWERTY') * 1.15);
end;

circular

  • Hero Member
  • *****
  • Posts: 3058
    • Personal webpage
Re: BGRABitmap - System font
« Reply #2 on: April 15, 2012, 08:28:17 pm »
If you want to assign TextHeight value, then you should rather use FontFullHeight property. FontHeight is the "em" size.

You can use a negative value in FontHeight to specify the full height.

I recommend to use this :
Code: [Select]
b.FontFullHeight := Canvas.TextHeight('Test (BGRA)');
But you can also write :
Code: [Select]
b.FontHeight := -Canvas.TextHeight('Test (BGRA)');
You should obtain exactly the same "look" by specifying
Code: [Select]
b.FontQuality:= fqSystemClearType;
« Last Edit: April 15, 2012, 08:38:25 pm by circular »
Conscience is the debugger of the mind

Dibo

  • Hero Member
  • *****
  • Posts: 1046
Re: BGRABitmap - System font
« Reply #3 on: April 15, 2012, 09:28:05 pm »
It's better now but still bigger than canvas font (see attached screen). It's better when I don't copy font name (in bgra is by default "arial", in canvas is "default"). When I copy "default" to TBGRABitmap.Fontname then font is larger than before (second screen)
Code: [Select]
procedure TForm1.FormPaint(Sender: TObject);
var b: TBGRABitmap;
begin
  b := TBGRABitmap.Create(120,100);
  //b.FontName := Canvas.Font.Name;
  b.FontHeight := -Canvas.TextHeight('Test TextOut');
  b.FontStyle := Canvas.Font.Style;
  b.FontQuality := fqSystemClearType;

  b.TextOut(25,25,'Test TextOut', BGRABlack);
  b.Draw(Self.Canvas,0,0,False);
  b.Free;

  Canvas.Brush.Style := bsClear;
  Canvas.TextOut(25,50,'Test TextOut');
end;

On the screens: 1 is BGRABitmap, 2 is canvas, 3 is TLabel

circular

  • Hero Member
  • *****
  • Posts: 3058
    • Personal webpage
Re: BGRABitmap - System font
« Reply #4 on: April 16, 2012, 07:48:11 pm »
Yes, "default" is not really understood by BGRABitmap. What if you set font name to "Arial" both in the Canvas and in the BGRABitmap ?
Conscience is the debugger of the mind

Dibo

  • Hero Member
  • *****
  • Posts: 1046
Re: BGRABitmap - System font
« Reply #5 on: April 16, 2012, 08:05:09 pm »
Still some little difference but acceptable for me (see attached screen). It looks like difference is now in the width, height is fine.

circular

  • Hero Member
  • *****
  • Posts: 3058
    • Personal webpage
Re: BGRABitmap - System font
« Reply #6 on: April 16, 2012, 08:36:50 pm »
It seems that there is also a slight difference in the vertical direction. Because of font hinting (pixel align), the font size can jump. Here it jumps horizontally but not vertically.

There may also be a problem with fqSystemClearType mode. If you look closely, you can see that it is not ClearType but grayscale.
Conscience is the debugger of the mind

circular

  • Hero Member
  • *****
  • Posts: 3058
    • Personal webpage
Re: BGRABitmap - System font
« Reply #7 on: April 16, 2012, 08:48:52 pm »
Oh I know, the bitmap is transparent, so the ClearType mode cannot be applied.

With this code :
Code: [Select]
procedure TForm1.FormPaint(Sender: TObject);
var b: TBGRABitmap;
begin
  Canvas.Font.Name := 'Arial';

  b := TBGRABitmap.Create(200,100, ColorToBGRA(ColorToRGB(clBtnFace)));
  b.FontName := Canvas.Font.Name;
  b.FontHeight := -Canvas.TextHeight('Test TextOut (BGRA)');
  b.FontStyle := Canvas.Font.Style;
  b.FontQuality := fqSystemClearType;

  b.TextOut(25,25,'Test TextOut (BGRA)', BGRABlack);
  b.Draw(Self.Canvas,0,0,False);
  b.Free;

  Canvas.Brush.Style := bsClear;
  Canvas.TextOut(25,50,'Test TextOut (Canvas)');
end;

I have this result on Windows :
Conscience is the debugger of the mind

Dibo

  • Hero Member
  • *****
  • Posts: 1046
Re: BGRABitmap - System font
« Reply #8 on: April 16, 2012, 09:18:36 pm »
Doesn't help (screenshot). Maybe this is some QT issue. In my KDE, font looks bad after fresh system installation (many people have similar problems with KDE). So I changed something in system font configuration. If I remember correctly, I changed antyaliasing settings from default to custom:
- Use subpixel smoothing (sory, translated from polish) with option RGB
- Hinting style: medium

Maybe LCL font detect this and I must set something similar in bgra font?

Edit: Perhaps I changed something in the font DPI also
« Last Edit: April 16, 2012, 09:21:06 pm by Dibo »

circular

  • Hero Member
  • *****
  • Posts: 3058
    • Personal webpage
Re: BGRABitmap - System font
« Reply #9 on: April 17, 2012, 07:19:17 pm »
Apparently, ClearType (=subpixel smoothing) is not applied even with fqSystemClearType. So that means that when drawing on a bitmap, ClearType is not used.

Can you check this by creating a TBitmap, setting font quality to ClearType and draw some text on it, show it on a window and take a screenshot, and put it here ?
Conscience is the debugger of the mind

Dibo

  • Hero Member
  • *****
  • Posts: 1046
Re: BGRABitmap - System font
« Reply #10 on: April 17, 2012, 08:19:51 pm »
No problem. Screen attached. Size seems the same, but is very little quality difference.
Code: [Select]
var
  b: TBGRABitmap;
  b2: TBitmap;
begin
  Canvas.Font.Name := 'Arial';

  b := TBGRABitmap.Create(200,100, ColorToBGRA(ColorToRGB(clBtnFace)));
  b.FontName := Canvas.Font.Name;
  b.FontHeight := -Canvas.TextHeight('Test TextOut (BGRA)');
  b.FontStyle := Canvas.Font.Style;
  b.FontQuality := fqSystemClearType;

  b.TextOut(25,25,'Test TextOut (BGRA)', BGRABlack);
  b.Draw(Self.Canvas,0,0,False);
  b.Free;

  Canvas.Brush.Style := bsClear;
  Canvas.TextOut(25,50,'Test TextOut (Canvas)');

  b2 := TBitmap.Create;
  b2.SetSize(200, 100);
  b2.Canvas.Font.Name := 'Arial';
  b2.Canvas.Font.Quality := fqCleartype;
  b2.Canvas.Brush.Color := clBtnFace;
  b2.Canvas.FillRect(b2.Canvas.ClipRect);
  b2.Canvas.Brush.Style := bsClear;
  b2.Canvas.TextOut(25,0, 'Test TextOut (BMP)');
  Self.Canvas.Draw(0, 75, b2);
  b2.Free;
end;

PS: If you don't have time, we can break this ;) . After changing name to arial, size is ok for me.

circular

  • Hero Member
  • *****
  • Posts: 3058
    • Personal webpage
Re: BGRABitmap - System font
« Reply #11 on: April 17, 2012, 10:33:12 pm »
Ok. So clearly ClearType seem not to be available on bitmaps. In this case, if you want ClearType rendering, you must use fqFineClearTypeRGB.

I'm still puzzled by the size issue. What if you do :
Code: [Select]
var
  b: TBGRABitmap;
begin
  Canvas.Font.Name := 'Arial';
  Canvas.Font.Height := 20; //or another number

  b := TBGRABitmap.Create(200,100, ColorToBGRA(ColorToRGB(clBtnFace)));
  b.FontName := Canvas.Font.Name;
  b.FontHeight := -Canvas.Font.Height; //here using exactly the same value with sign fix
  b.FontStyle := Canvas.Font.Style;
  b.FontQuality := fqSystemClearType;
  b.TextOut(25,25,'Test TextOut (System)', BGRABlack);
  b.FontQuality := fqFineClearTypeRGB;
  b.TextOut(25,0,'Test TextOut (Fine)', BGRABlack);
  b.Draw(Self.Canvas,0,0,False);
  b.Free;

  Canvas.Brush.Style := bsClear;
  Canvas.TextOut(25,50,'Test TextOut (Canvas)');
end;
?
Conscience is the debugger of the mind

Dibo

  • Hero Member
  • *****
  • Posts: 1046
Re: BGRABitmap - System font
« Reply #12 on: April 18, 2012, 07:38:04 pm »
It looks better and better :) (screen)

circular

  • Hero Member
  • *****
  • Posts: 3058
    • Personal webpage
Re: BGRABitmap - System font
« Reply #13 on: April 18, 2012, 11:54:03 pm »
This is it. It cannot be better for now. :D
It may get better when LazFreeType is integrated in BGRABitmap, which is not yet ready at all.

So what you need to take into account is that TextHeight does not return the same value as the font height, so you should avoid going that way to keep the size equivalence.

About SystemClearType mode, maybe there is some option in TBitmap under QT to enable ClearType rendering. In the meantime, you can use FineClearType.

Regards.
Conscience is the debugger of the mind

lainz

  • Guest
Re: BGRABitmap - System font
« Reply #14 on: April 19, 2012, 01:47:33 am »
Someone can fix this

http://lazarus.freepascal.org/index.php/topic,16638.msg90689.html#msg90689

procedure height?

The full code is in the customdrawn_windows7.pas in BGRAControls.