Форум: "Начинающим";
Текущий архив: 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