![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
определение максимально размера шрифта
novichek © (2010-01-09 23:12:00)добрый вечер!
есть канва, есть строка.
необходимо определить максимальный размер шрифта канвы для вывода не нем данной строки.
пока делаю так:
устанавливаю размер шрифта канвы в 1.
в цикле увеличиваю размер шрифта пока canvas.TextWidth(myString) меньше ширины битмапа.
затем проверяю по высоте если больше то откатываю в цикле на 1 пока TextHight вернет значение меньше высоты.
прошу Вас подсказать, нет ли более изящного (быстрого, правильного,..) решения ?
вычислений много, хотелось бы без всяких циклов, более производительнее вычислять.. возможно?
Дмитрий С (2010-01-10 14:30:00) [1]Можно сократить количество итераций цикла, усложнив алгоритм в [6] как при быстром поиске.
novichek (2010-01-10 11:51:00) [2]KilkennyCat ©, спасибо большое, в далеке сознания была такая мысль )
KilkennyCat (2010-01-10 11:23:00) [3]Да это еще вопрос, выгадается ли... выполнение Font.Size := Font.Size - 1; с последующим сравнением намного быстрее, чем fz = Int (bitmap.width * fz / x )
KilkennyCat (2010-01-10 11:21:00) [4]что-либо прогнозировать разумно только для моноширинных шрифтов. Хотя, конечно, можно рассчитать некоторую зависимость и снизить число итераций цикла. Но на мой взгляд, учитывая не такой уж большой диапазон (от 6 до 18, да? иначе читать уже неудобно), какие-либо дополнительные вычисления не имеют смысла, ибо отнимут много времени на разработку, причем настолько много, что не компенсируется выгаданными микросекундами и за сотню лет использования программой всеми китайцами.
novichek (2010-01-10 11:15:00) [5]ну в принципе я так и делал с самого начала...
я вот всё пытаюсь отойти от цикла как-то.
например:
fz = bitmap.canvas.font.size;
x:= bitmap.canvas.textWidth(MaxString);
и вот тут как-то бы вычислить новый fz, что бы X был наиболее приближен к bitmap.width
я надеюсь что это же пропорционально и, например, новый
fz = Int (bitmap.width * fz / x )
что-то такое.. будет работать правильно?
KilkennyCat (2010-01-10 01:11:00) [6]угу. используй [6] и не парься.
novichek (2010-01-10 01:08:00) [7]KilkennyCat, если я правильно понял, то у меня задача чуть другая.
у меня есть жесткое значение ширины и высоты канвы.
мне нужно узнать, какой максимальный размер шрифта установить, что бы максимальная строка вошла как раз вплотную.
KilkennyCat (2010-01-10 01:03:00) [8]предложенное мною решение позволяет загнать весь текст, не вычисляя самую длинную строку.
KilkennyCat (2010-01-10 01:02:00) [9]
> смутило "возвращает значение высоты "
Разумеется. Текст имеет не только ширину, и может иметь не только одну строку. Тебе высота нужна? нет. ну дык и наплюй.
novichek (2010-01-10 00:57:00) [10]простите, наверное я не так понял, как то заумно написано:
DT_CALCRECT
Выясняет ширину и высоту прямоугольника. Если имеется несколько строк текста, функция DrawText использует ширину прямоугольника, указанную параметром lpRect и продлевает основу прямоугольника, чтобы ограничить последнюю строку текста. Если самое большое слово шире, чем прямоугольник, ширина дополняется. Если текст - меньше, чем ширина прямоугольника, ширина уменьшается. Если есть только одна строка текста, DrawText изменяет правую сторону прямоугольника так, чтобы она ограничивала последнюю букву в строке. И в том, и в другом случае,
DrawText возвращает значение высоты отформатированного текста, но не выводит текст.
так же меня смутило "возвращает значение высоты "....
Юрий Зотов (2010-01-10 00:56:00) [11]S - самая длинная строка.
with Canvas do
while TextWidth(S) > ClipRect.Right do
Font.Size := Font.Size - 1;
KilkennyCat (2010-01-10 00:50:00) [12]
> я так понимаю он сожмется или растянется..
я так понимаю, ты справку не читал. он вообще даже не отобразится. указанный мной флаг позволяет определить необходимые размеры области, на которой будет в дальнейшем отображен текст. Соответственно, тупым последовательным приближением, или умным бинарным, подбирается размер шрифта, при котором необходимые размеры области совпадут с имеющимися.
novichek (2010-01-10 00:16:00) [13]KilkennyCat ©, я так понимаю он сожмется или растянется..
сжатый вывод некрасивый...
суть в том, что имеется массив строк, который буду по времени выводить на нкаве.. я должен определить максимальную строку и определить размер шрифта канвы, что бы при выводе максимальная строка как раз вошла.. по тупому объяснил, но думаю поняли.
размер шрифта для каждой строки должен быть один..
novichek (2010-01-10 00:11:00) [14]хм.. вот сделал:
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;
KilkennyCat (2010-01-10 00:02:00) [15]drawtext с флагом dt_CalcRect
{RASkov} (2010-01-09 23:48:00) [16]> [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;
.....