2015-02-23 114 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