2015-02-23 102 views
3

我正在计算最大字体大小,以便在Text中适合TCxLabel的ClientRect。但我无法让它工作。 (见图片)计算最大字体大小

enter image description here

的字体大小是大和thxt没有绘制corrent地方。

这里如何重现:

放置一个tcxLabel一个空表上,并allign标签客户

添加FORMCREATE和FormResize事件:

procedure TForm48.FormCreate(Sender: TObject); 
begin 
    CalculateNewFontSize; 
end; 

procedure TForm48.FormResize(Sender: TObject); 
begin 
    CalculateNewFontSize; 
end; 

,并最终实现CalculateNewFontSize :

使用 数学;

procedure TForm48.CalculateNewFontSize; 
var 
    ClientSize, TextSize: TSize; 
begin 

    ClientSize.cx := cxLabel1.Width; 
    ClientSize.cy := cxLabel1.Height; 

    cxLabel1.Style.Font.Size := 10; 
    TextSize := cxLabel1.Canvas.TextExtent(Text); 

    if TextSize.cx * TextSize.cx = 0 then 
    exit; 

    cxLabel1.Style.Font.Size := cxLabel1.Style.Font.Size * Trunc(Min(ClientSize.cx/TextSize.cx, ClientSize.cy/TextSize.cy) + 0.5); 
end; 

是否有人知道如何计算字体大小和浩正确地放置文本?

+1

'cxLabel1.Style.Font.Size:= cxLabel1.Style.Font.Size * n'其中'n'是一个整数意味着你没有覆盖字体大小的空间。 – 2015-02-23 08:25:12

+0

由于Font.Size是一个整数,我需要n也是一个整数!?! – 2015-02-23 08:34:32

+0

因此,如果您以12的大小开始,那么您认为下一个较大的值是24?使用MulDiv。 – 2015-02-23 08:44:36

回答

4

我会使用这些方针的东西:

function LargestFontSizeToFitWidth(Canvas: TCanvas; Text: string; 
    Width: Integer): Integer; 
var 
    Font: TFont; 
    FontRecall: TFontRecall; 
    InitialTextWidth: Integer; 
begin 
    Font := Canvas.Font; 
    FontRecall := TFontRecall.Create(Font); 
    try 
    InitialTextWidth := Canvas.TextWidth(Text); 
    Font.Size := MulDiv(Font.Size, Width, InitialTextWidth); 

    if InitialTextWidth < Width then 
    begin 
     while True do 
     begin 
     Font.Size := Font.Size + 1; 
     if Canvas.TextWidth(Text) > Width then 
     begin 
      Result := Font.Size - 1; 
      exit; 
     end; 
     end; 
    end; 

    if InitialTextWidth > Width then 
    begin 
     while True do 
     begin 
     Font.Size := Font.Size - 1; 
     if Canvas.TextWidth(Text) <= Width then 
     begin 
      Result := Font.Size; 
      exit; 
     end; 
     end; 
    end; 
    finally 
    FontRecall.Free; 
    end; 
end; 

做一个初步的估计,然后通过一次一个的增量修改大小来进行微调。这很容易理解和验证正确性,并且相当有效。在典型的使用中,代码只会呼叫TextWidth少数几次。

+0

感谢您的帮助David我已经根据您的代码创建了我的组件,我只想与您和世界其他地区分享结果:D http://pastebin.com/aK6nZNZk – 2015-02-23 17:26:13

3

文字大小不会线性取决于字体大小。所以,你最好由一个递增或递减的字体大小和计算文本的大小,或找到二进制搜索需要的大小(最好,如果大小显著不同)

+0

是的,这是我的第一个解决方案,但我在纯数学中接受 – 2015-02-23 08:36:10

+1

由于不同的字体元素(字母元素,符号间空格等)的大小因纯数学的大小不同而不同(对于非等宽字体)一个复杂的方式。例如,对于某些字体大小可以存在连字符(示例 - 连接的ff),对于其他大小可以存在直径。 – MBo 2015-02-23 09:00:44