Jump to content
stewag64

Set font size automatically depending on display size

Recommended Posts

I develop a smartphone app with a tabcontrol with several tabs for some years already.

 

In order to size controls I use TGridPanelLayouts but in order to also scale font-sizes, I am still using various layout packages.

That is because I realized that the "standard" font-size is often too small on larger devices.

 

Layout packages have two drawbacks:

1. There is a bunch of layouts to update for every change in the app

2. You can never catch all existing Android display sizes, as I realize when I look at my app at other person's smartphones.

 

That is why I want to get rid of layout packages and find an algorithm that allows me to set font-sizes for labels, buttons and memos, depending on screen.width (or other device parameter).

 

Is there a general approach for this?

Does it also respect different device's dpi?

 

Thanks for any advice 

Steffen  

    

layouts.jpg

Share this post


Link to post

This is my solution. I iterate font size until it fits the control.

Not sure if it works for high-dpi screens. Would it?

 

function SetFontSize(LongestText: String; MaxWidth: Single; MarginPerc: Integer): Integer;
{LongestText: string to be adapted
 MaxWidth: width of tab, button or label
 MarginPerc: side-margin in percent}
var
  i: Integer;
  bmp: TBitmap;
  TextWidth: Single;
begin
  Result := 10;
  bmp := TBitmap.Create(1, 1);
  try
    for i := 10 to 50 do
    begin
      bmp.Canvas.Font.Size := i;
      bmp.Canvas.Font.Style := []; // optional, bold
      bmp.Canvas.Fill.Kind := TBrushKind.Solid;
      bmp.Canvas.Fill.Color := TAlphaColorRec.Black;

      TextWidth := bmp.Canvas.TextWidth(LongestText);
      TextWidth := TextWidth * (1 + MarginPerc / 100);

      if TextWidth > MaxWidth then
      begin
        Result := i;
        Break;
      end;
    end;
  finally
    bmp.Free;
  end;
end;

 

Edited by stewag64

Share this post


Link to post

"Maxwidth" will take of course a variable, such as button1.width, not a number. 

Share this post


Link to post

Interesting approach. 👍
Don't you get then varying font sizes for each control, by differing MaxWidths?
How do you control that there is a unique look-and-feel, do you use always the same width spaces for all components?

Maybe you have some screenshots available, to get a better idea.

Edited by Rollo62

Share this post


Link to post

I use the function only for the longest strings and then choose the same fontsize for other components.

For some I apply font.size +n or -n.

Edited by Stewag

Share this post


Link to post

For this form, in order to give the central TMemo the maximal space, TGridPanelLayoutRowCollection are not set to "Percent" but to "Absolute". Row heights are then set according to the size of their contents plus some additional space. The memo [2] takes the remaining space:  

with GridPanelLayout1 do
  begin
    Rowcollection[0].Value := imgLogo.height * 1.3;
    Rowcollection[1].Value := mBeschreibung.height * 1.3;
    Rowcollection[3].Value := Layout2.height + 4; // mBewertung
    Rowcollection[4].Value := Layout6.height; // Button
    Rowcollection[5].Value := ckbAusblenden.height * 1.5;
    Rowcollection[2].Value := (Screen.Height - (Rowcollection[0].Value + Rowcollection[1].Value + Rowcollection[3].Value
      + Rowcollection[4].Value + Rowcollection[5].Value)) *1.1 //1.1 because of margins
  end;


 

Edited by stewag64

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×