Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.03.14;
Скачать: CL | DM;

Вниз

определение максимально размера шрифта   Найти похожие ветки 

 
novichek   (2010-01-09 23:12) [0]

добрый вечер!
есть канва, есть строка.
необходимо определить максимальный размер шрифта канвы для вывода не нем данной строки.

пока делаю так:

устанавливаю размер шрифта канвы в 1.
в цикле увеличиваю размер шрифта пока canvas.TextWidth(myString) меньше ширины битмапа.
затем проверяю по высоте если больше то откатываю в цикле на 1 пока TextHight вернет значение меньше высоты.

прошу Вас подсказать, нет ли более изящного (быстрого, правильного,..)  решения ?

вычислений много, хотелось бы без всяких циклов, более производительнее вычислять.. возможно?


 
{RASkov} ©   (2010-01-09 23:48) [1]

> [0] novichek   (09.01.10 23:12)

Попробуй var LFont: TLogFont; R: TRect канвы, S: String данная строка и примерно так:

 .....
 LFont.lfHeight := R.Bottom-R.Top;
 if LFont.lfHeight = 0 then LFont.lfHeight:=1;
 
 LFont.lfWidth  := (R.Right-R.Left) div Length(S);
 if LFont.lfWidth  = 0 then LFont.lfWidth :=1;
 .....


 
KilkennyCat ©   (2010-01-10 00:02) [2]

drawtext с флагом dt_CalcRect


 
novichek   (2010-01-10 00:11) [3]

хм.. вот сделал:

 function calcMaxSizeFont(val: String; w, y: Integer): Word;
 var
   LFont: TLogFont;
 begin
   if (w<2) or (h<2) then exit(1);
   LFont.lfHeight := y;
   LFont.lfWidth  := w div Length(val);
 end;

немножко непонятно, а как же узнать сам размер-то шрифта?
и так же наверное нужно учитывать что за шрифт у канвы..

я пока делаю так уродливо:

 function calcMaxSizeFont(val: String; w, y: Integer): Word;
 var
   canv: TCanvas;
 begin
   if (w<10) or (h<10) then exit(1);
   canv:= TCanvas.Create;
   canv.Font:= b1.Canvas.Font;
   canv.Font.Size:= 1;
   while canv.TextHeight("yЁ") < h do canv.Font.Size:= canv.Font.Size + 1;
   canv.Font.Size:= canv.Font.Size - 1;
   while canv.TextWidth(val) > w do canv.Font.Size:= canv.Font.Size - 1;
   result:= canv.Font.Size;
   canv.Free;
 end;


 
novichek   (2010-01-10 00:16) [4]

KilkennyCat ©, я так понимаю он сожмется или растянется..
сжатый вывод некрасивый...

суть в том, что имеется массив строк, который буду по времени выводить на нкаве.. я должен определить максимальную строку и определить размер шрифта канвы, что бы при выводе максимальная строка как раз вошла.. по тупому объяснил, но думаю поняли.
размер шрифта для каждой строки должен быть один..


 
KilkennyCat ©   (2010-01-10 00:50) [5]


> я так понимаю он сожмется или растянется..

я так понимаю, ты справку не читал. он вообще даже не отобразится. указанный мной флаг позволяет определить необходимые размеры области, на которой будет в дальнейшем отображен текст. Соответственно, тупым последовательным приближением, или умным бинарным, подбирается размер шрифта, при котором необходимые размеры области совпадут с имеющимися.


 
Юрий Зотов ©   (2010-01-10 00:56) [6]

S - самая длинная строка.

with Canvas do
 while TextWidth(S) > ClipRect.Right  do
   Font.Size := Font.Size - 1;


 
novichek   (2010-01-10 00:57) [7]

простите, наверное я не так понял, как то заумно написано:

DT_CALCRECT  
Выясняет ширину и высоту прямоугольника. Если имеется несколько строк текста, функция DrawText использует ширину прямоугольника, указанную параметром lpRect и продлевает основу прямоугольника, чтобы ограничить последнюю строку текста. Если самое большое слово шире, чем прямоугольник, ширина дополняется. Если текст - меньше, чем ширина прямоугольника, ширина уменьшается. Если есть только одна строка текста, DrawText изменяет правую сторону прямоугольника так, чтобы она ограничивала последнюю букву в строке. И в том, и в другом случае,

DrawText возвращает значение высоты отформатированного текста, но не выводит текст.

так же меня смутило "возвращает значение высоты "....


 
KilkennyCat ©   (2010-01-10 01:02) [8]


> смутило "возвращает значение высоты "

Разумеется. Текст имеет не только ширину, и может иметь не только одну строку. Тебе высота нужна? нет. ну дык и наплюй.


 
KilkennyCat ©   (2010-01-10 01:03) [9]

предложенное мною решение позволяет загнать весь текст, не вычисляя самую длинную строку.


 
novichek   (2010-01-10 01:08) [10]

KilkennyCat, если я правильно понял, то у меня задача чуть другая.
у меня есть жесткое значение ширины и высоты канвы.
мне нужно узнать, какой максимальный размер шрифта установить, что бы максимальная строка вошла как раз вплотную.


 
KilkennyCat ©   (2010-01-10 01:11) [11]

угу. используй [6] и не парься.


 
novichek   (2010-01-10 11:15) [12]

ну в принципе я так и делал с самого начала...
я вот всё пытаюсь отойти от цикла как-то.
например:

 fz = bitmap.canvas.font.size;

 x:= bitmap.canvas.textWidth(MaxString);
 
 и вот тут как-то бы вычислить новый fz, что бы X был наиболее приближен к bitmap.width
 я надеюсь что это же пропорционально и, например, новый
 fz = Int (bitmap.width * fz / x )

что-то такое.. будет работать правильно?


 
KilkennyCat ©   (2010-01-10 11:21) [13]

что-либо прогнозировать разумно только для моноширинных шрифтов. Хотя, конечно, можно рассчитать некоторую зависимость и снизить число итераций цикла. Но на мой взгляд, учитывая не такой уж большой диапазон (от 6 до 18, да? иначе читать уже неудобно), какие-либо дополнительные вычисления не имеют смысла, ибо отнимут много времени на разработку, причем настолько много, что не компенсируется выгаданными микросекундами и за сотню лет использования программой всеми китайцами.


 
KilkennyCat ©   (2010-01-10 11:23) [14]

Да это еще вопрос, выгадается ли... выполнение  Font.Size := Font.Size - 1; с последующим сравнением намного быстрее, чем  fz = Int (bitmap.width * fz / x )


 
novichek   (2010-01-10 11:51) [15]

KilkennyCat ©, спасибо большое,  в далеке сознания была такая мысль )


 
Дмитрий С ©   (2010-01-10 14:30) [16]

Можно сократить количество итераций цикла, усложнив алгоритм в [6] как при быстром поиске.



Страницы: 1 вся ветка

Текущий архив: 2010.03.14;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.012 c
2-1263006697
Иван
2010-01-09 06:11
2010.03.14
Ошибка Project raised exception class EIBInterBaseError with ...


15-1261508714
chery
2009-12-22 22:05
2010.03.14
помогите пожалуйста написать программу в Delphi


2-1263269002
Умник
2010-01-12 07:03
2010.03.14
Различаются ли коды не стандартных клавиатур?


15-1261659128
Olegz77
2009-12-24 15:52
2010.03.14
Миниатюра окна в панели задач Windows Vista


15-1258652658
Копир
2009-11-19 20:44
2010.03.14
В России, наконец-то, отменена смертная казнь...