Solved

Canvas.TextWidth is not correct!

Posted on 2000-04-19
8
952 Views
Last Modified: 2010-05-18
Problems with exactly scaling a Font:

I tried to fit a text into an Image, so that it starts on the left side and ends on the right side of the Image (as excactly as possible; I know, that
Font.Size is not available for all integer values!).

I used the following simple code:


  cvs:=Image.Canvas;
  tw:=cvs.TextWidth(ed_Text.Text);
  cvs.Font.Size:=30;
  while ((tw>=Image.Width) and (cvs.Font.Size>3))   do begin
    cvs.Font.Size:=cvs.Font.Size-1;
    tw:=cvs.TextWidth(ed_Text.Text);
  end; // while ...
  cvs.Textout(0,0,s);


(Hereby I will assume, that the Image is high enough to contain
the text, so I do not have to check this here).

The result: the text starts on the left, but does only fill about 80%
of the window leaving blanks on the right side. So it seems to me, that cvs.TextWidth returns a value,
which is too small (I can always find an existing Font.Size, which has a better fit!).

I could solve the problem this way:
  tw:=round(1.2 * cvs.TextWidth(ed_Text.Text);
but I think, there must be a more exact way to get the correct
size of the Font on the canvas to ensure exact scaling.

100 Points for a different approach to solve the problem of fitting
the text in width (or also in height), which results in a more exact
fit.

Thanks for any help

Gamba


0
Comment
Question by:Gamba
8 Comments
 
LVL 9

Expert Comment

by:ITugay
ID: 2729877
Hi Gamba,

try this sample
-----------
var tw,fs : integer;
    S     : string;
    cnv   : TCanvas;
begin
   cnv:=Image1.Canvas;
   cnv.Font.Size:=6;
   S:='sample';
   repeat
      cnv.Font.Size:=cnv.Font.Size+1;
      tw:=cnv.TextWidth(S);
   until Image1.Width < tw;
   cnv.Font.Size:=cnv.Font.Size-1; // you miss it in your sample
   cnv.TextOut(0,0,S);
end;
-----

Igor.
0
 
LVL 3

Expert Comment

by:shenqw
ID: 2729904
s=what?

I think you forgot s:=ed_Text.Text
0
 
LVL 9

Expert Comment

by:ITugay
ID: 2729929
S:='sample';) It's working sample, I check it before public.
----
Igor.
0
 

Author Comment

by:Gamba
ID: 2730211
Thanks, ITugay,
this works o.k., I added the
Height-Part and changed the line
with Font.Size:=Font.Size-1 (see comment). I did not expect it to be
a problem of the missed line!

Do you think, finding the correct Font.Size has to be done iterative
or can it be calculated somehow??

(please add a answer statement and
you will receive the points in any case).




procedure Draw;
var tw,th: integer;
    s     : string;
    cnv   : TCanvas;
    prevsize : word;
    prevw,prevh : integer;
begin
   cnv:=Image.Canvas;
   cnv.Rectangle(0,0,Image.Width,Image.Height);
   cnv.Font.Size:=5;
   prevw:=cnv.TextWidth(s);
   prevh:=cnv.TextHeight(s);
   tw:=prevw;
   th:=prevh;
   s:=ed_Text.Text;
   repeat
     if ((tw<>prevw) or (th<>prevh)) and ((Image.Width >= tw) or (Image.Height >= th))
     then begin
       prevsize:=cnv.Font.Size;
       prevw:=tw;
       prevh:=th;
     end; // if (tw<>prevw) or (th<>prevh)
     cnv.Font.Size:=cnv.Font.Size+1;
     tw:=cnv.TextWidth(s);
     th:=cnv.TextHeight(s);
   until ((Image.Width < tw) or (Image.Height < th));
   cnv.Font.Size:=prevsize;
     (* instead of cnv.Font.Size:=cnv.Font.Size-1, cause cnv.Font.Size-1 has not necessary other
      tw and th *)
   cnv.TextOut(0,0,S);
end;



Gamba


0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 9

Expert Comment

by:ITugay
ID: 2730241
Ok, just a moment...
0
 
LVL 2

Expert Comment

by:mullet_attack
ID: 2730929
If you want an exact fit, use a truetype font. Using the default windows font cause Windows to perform a best-fit calculation of a scaled up/down font.

TextWidth returns the correct width in pixels only for truetype fonts and the pre-defined sizes of system fonts.

ITugay's sample doesn't work properly without a true-type font.
0
 
LVL 9

Accepted Solution

by:
ITugay earned 100 total points
ID: 2733648
mulet_attack,
try it at first then make your insennuations.
-----------

Hi Gamba,
Sorry for delay. Calculation of text metrics is very difficult, let TextWidth and TextHeight do it for you. I simplifyed your algorythm, now it look like this:
---------

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
   with Image do with Canvas do
   begin
     Font.Name:='MS Serif'; // not truetype font (for mullet_attack especially)
     Font.Size:=6;
     repeat
        Font.Size:=Font.Size+1;
     until (Width < TextWidth(Ed_text.Text))
        or (Height < TextHeight(Ed_text.Text));
     Font.Size:=Font.Size-1;
     TextOut(0,0,Ed_text.Text);
   end;
end;
----------

Best regards,
Igor.
0
 

Author Comment

by:Gamba
ID: 2733736
Thanks

Gamba
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now