问题
I have a graphiccontrol
and trying to draw text onto the canvas. Currently i am doing a Canvas.Textout()
but becuase i set the values manually if the canvas area grows the text does not. I would like to make the text also grow. For example.
{Sets the cards power and draws it on the tcard}
//------------------------------------------------------------
procedure TCard.DrawLPower(value: string);//left number
//------------------------------------------------------------
begin
if fbigcard = false then
begin
canvas.Font.Size := 8;
canvas.font.color := TColor($FFFFFF);
Canvas.TextOut(1,1,value);
end
else
begin
canvas.font.color := TColor($FFFFFF);
canvas.Font.Size := 12;
Canvas.TextOut(1,7,value);
canvas.Font.Color := CLBlack;
end;
end;
i check if the card/canvas is big and if so it will text out 1,7 if its not big it will text out 1,1. I am thinking if i use the methods textheight or text width it would auto fix that, but not sure how? and keep the numbers i draw in the same spot. Currently i do this in about 3 spots here are the other two.
{sets cards def and draws it to the tcard}
//------------------------------------------------------------
procedure TCard.DrawLDefence(value: string); //right number
//-------------------------------------------------------------
begin
if fBigcard = false then
begin
canvas.font.color := TColor($FFFFFF);
canvas.Font.Size := 8;
canvas.TextOut(32,1,value);
canvas.Font.Color := CLBlack;
end
else
begin
canvas.font.color := TColor($FFFFFF);
canvas.Font.Size := 12;
canvas.TextOut(115,7,value);
canvas.Font.Color := CLBlack;
end;
end;
{Sets and draws the cost to the TCard}
//-------------------------------------------------------------
procedure TCard.DrawLCost(value :string); //cost
//-------------------------------------------------------------
begin
if fbigcard = false then
begin
canvas.font.size := 8;
canvas.font.color := TColor($FFFFFF);
Canvas.textout(19,1,inttostr(CCost));
end
else
begin
canvas.font.size := 12;
canvas.font.color := TColor($FFFFFF);
Canvas.textout(65,7,inttostr(CCost));
canvas.Font.Color := CLBlack;
end;
end;
also if it helps, i am thinking i should keep the size as a var thus removing all the extra code..
回答1:
You want the text size to be dependend on the control size? Then you need to know or calculate which text should fit in which space, and then draw it.
Looking at your code, all three strings are output at Y=1
next to each other at different X coordinates. I suppose you hardcoded these coordinates for testing purposes and now you want to get that dynamic for any arbitrary control size.
So I assume the real question you are asking here is: How to calculate font size for a given text width? (Hopefully I am correct and I didn't write this answer in vain. You really should be more clear in your question though.)
The answer requires knowledge on how to distribute the strings among the width of the control and with which margin in between. Let's assume you want all three strings to be painted within half the width of the control and them to be separated by the width of two spaces (if not, at least ensure a margin proportional to the font size). AFAIK there is no routine that calculates font size for a given text size, so you have to work around: set the font small, and increase until the text fits:
procedure TCard.DrawValues(const Power, Defence, Cost: String);
var
FontRecall: TFontRecall;
S: String;
FontHeight: Integer;
begin
FontRecall := TFontRecall.Create(Canvas.Font);
try
S := Format(' %s %s %s', [Power, Defence, Cost]);
FontHeight := -1;
repeat
Inc(FontHeight);
Canvas.Font.Height := FontHeight + 1;
until Canvas.TextWidth(S) > ClientWidth div 2;
Canvas.Font.Height := FontHeight;
Canvas.TextOut(0, 1, S);
finally
FontRecall.Free;
end;
end;
Idealy, you would recalculate this FontHeight
only when the control size changes (override Resize
) or when the string changes.
来源:https://stackoverflow.com/questions/19731338/how-to-autodraw-the-text-based-on-graphiccontrols-size