Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2010.03.14;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.005 c
2-1263237497
Olya
2010-01-11 22:18
2010.03.14
как записать символ в юникоде


2-1262704561
Sunktor
2010-01-05 18:16
2010.03.14
MinWidth по количеству кнопок в CoolBar.Bands


2-1262964582
Иван
2010-01-08 18:29
2010.03.14
Количество записей


15-1260999367
Германн
2009-12-17 00:36
2010.03.14
"Линия задержки"


15-1262038333
Германн
2009-12-29 01:12
2010.03.14
LCACC.EXE.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский