Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

canvas.textWidth для разных стилей


Страницы:   1 2 3

novichek ©   (2010-01-18 22:31:00) 

Устанавливаю стиль в fsItalic.
canvas.textWidth возвращает то же самое что и при отсутствии стиля.
В результате конец текста обрезан немного.

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

в процессе мучения, из-за выхода текста за размеры, набросал для теста:

procedure TForm1.Button1Click(Sender: TObject);
const
//  test = 'Проверка связи ры ры ры рычаг';
 test = 'test test test test';
var
 bmp: TBitmap;
 x1, x2, x3, x4: Integer;

 procedure drawbmp(offset: Integer);
 begin
    bmp.Canvas.FillRect(bmp.Canvas.ClipRect);
    bmp.Canvas.TextOut(0, 0, test);
    form1.Canvas.Draw(0, offset, bmp);
 end;

begin

 bmp:= TBitmap.Create;
 bmp.Canvas.Brush.Color:= clBlack;
 bmp.Canvas.Font.Color:= clWhite;

 bmp.Canvas.Font.Name:= 'Comic Sans MS';
 bmp.Canvas.Font.Size:= 40;
 bmp.Height:= bmp.Canvas.TextHeight('Py');

 bmp.Canvas.Font.Style:=[];
 x1:= bmp.Canvas.TextWidth(test);
 bmp.Width:= x1;
 drawbmp(0);

 bmp.Canvas.Font.Style:=[fsItalic];
 x2:= bmp.Canvas.TextWidth(test);
 bmp.Width:= x2;
 drawbmp(bmp.Height + 10);

 bmp.Canvas.Font.Style:=[fsBold];
 x3:= bmp.Canvas.TextWidth(test);
 bmp.Width:= x3;
 drawbmp(bmp.Height*2 + 10*2);

 bmp.Canvas.Font.Style:=[fsBold, fsItalic];
 x4:= bmp.Canvas.TextWidth(test);
 bmp.Width:= x4;
 drawbmp(bmp.Height*3 + 10*3);

 bmp.Free;

 ShowMessage('[] - '+IntToStr(x1)+',  [fsItalic] - '+IntToStr(x2)+',  [fsBold] - '+IntToStr(x3)+',  [fsBold, fsItalic] - '+IntToStr(x4));

end;

с чего и сделал вывод, что возвращаемые значения ширины немного не понятные..

как узнать  для данного шрифта правильный размер при fsItalic ?


antonn   (2010-01-19 21:24:00) [1]

например потому что есть текстурные шрифты


Anatoly Podgoretsky   (2010-01-19 21:17:00) [2]

> Игорь Шевченко  (19.01.2010 20:45:38)  [38]

Вот поэтому и системой и делается простой расчет, нафига им нетривиальность.


Anatoly Podgoretsky   (2010-01-19 21:16:00) [3]

> Демо  (19.01.2010 17:36:33)  [33]

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


Игорь Шевченко   (2010-01-19 20:45:00) [4]

Для расчета позиций символов с учетом их взаимного расположения нужно вызывать функции GetKerningPairs и(или) GetCharacterPlacement

Все это я к чему - вывод текста может оказаться весьма нетривиальным занятием


Демо   (2010-01-19 20:22:00) [5]


> Игорь Шевченко ©   (19.01.10 19:45) [36]
> Демо ©   (19.01.10 19:32) [35] Одни и те же символы по соседству
> с разными символами могут быть придвинуты к соседнему или
> наоборот, отодвинуты от соседа. То есть, для получения размера
> строки важна не сумма ширин отдельных символов, а сумма
> с учетом их взаимного расположения.


Понятно.
У меня вывод был посимвольный, поэтомусмещение вычислялось относительно предыдущего символа.
Вроде как всё было нормально. Ничто никуда не съезжало.


Игорь Шевченко   (2010-01-19 19:45:00) [6]

Демо ©   (19.01.10 19:32) [35]

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


Демо   (2010-01-19 19:32:00) [7]


> А ничего, что размер символа зависит от его позиции ?


Поясни мысль?


Игорь Шевченко   (2010-01-19 17:45:00) [8]

Демо ©   (19.01.10 17:36) [33]

А ничего, что размер символа зависит от его позиции ?


Демо   (2010-01-19 17:36:00) [9]

В своё время была у меня такая задача.
Я поступил таким образом:

Для каждого стиля завёл массив
   WSym: array[Char] of Integer;
   HSym: array[Char] of Integer;
   WSymBold: array[Char] of Integer;
   HSymBold: array[Char] of Integer;
   WSymItalic: array[Char] of Integer;
   HSymItalic: array[Char] of Integer;
   WSymUnderLine: array[Char] of Integer;
   HSymUnderLine: array[Char] of Integer;


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


Игорь Шевченко   (2010-01-19 15:55:00) [10]

antonn ©   (19.01.10 15:53) [31]


> все таки это смахивает больше на костыль


Разумеется. Для некостыльных решений я привел три ссылки, еще у Фэня в книжке подробно обсуждается эта проблема.


antonn   (2010-01-19 15:53:00) [11]

все таки это смахивает больше на костыль :)


Игорь Шевченко   (2010-01-19 15:43:00) [12]

antonn ©   (19.01.10 13:53) [29]

Я вчера малость попробовал, так чтобы слово fluff влезло, надо высоту шрифта прибавлять. Шрифт брал размером 72, с засечками и без них.


antonn   (2010-01-19 13:53:00) [13]

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


Anatoly Podgoretsky   (2010-01-19 13:11:00) [14]

> antonn  (19.01.2010 12:46:27)  [27]

Не ищи не ерунды, это ошибка (особенность) в генофонде. Борются добавляя предопределенное смещение


antonn   (2010-01-19 12:46:00) [15]


> А ты не пробовал просто DrawText использовать с флагом DT_CALCRECT?

с ним такая же ерунда


Демо   (2010-01-19 09:54:00) [16]


> novichek   (19.01.10 01:49) [25]


А ты не пробовал просто DrawText использовать с флагом DT_CALCRECT?


novichek   (2010-01-19 01:49:00) [17]

нормально вроде бы входит..

 function GetWidthText(bmp: TBitmap; text: String): Integer;
 var
   arr: array[0..0] of TABC;
 begin
   if trim(text)='' then exit(0);
   result:= bmp.Canvas.TextWidth(text);
   GetCharABCWidthsW(bmp.Canvas.Handle, ord(text[system.Length(text)]), ord(text[system.Length(text)]), arr);
   if arr[0].abcC < 0 then result:= result - arr[0].abcC;
 end;


Игорь Шевченко   (2010-01-19 01:39:00) [18]

novichek   (19.01.10 01:23) [23]

Попробуй, чтобы влезло слово fluff или Fluff


novichek   (2010-01-19 01:23:00) [19]

GetCharABCWidthsW(bmp.Canvas.Handle, ord(test[length(test)]), ord(test[length(test)]), arr);
dOverhangTrailing:= bmp.Canvas.TextWidth(test);

if arr[0].abcC < 0 then dOverhangTrailing:= dOverhangTrailing + (arr[0].abcC*-1);

bmp.Width:= dOverhangTrailing;


novichek   (2010-01-19 01:10:00) [20]

попробывал явно задать чуть побольше ширину и отрисовать текст

   bmp.Canvas.TextOut(0, 0, test);

затем думал установить реальную ширину, используя крайнюю позицию

   bmp.Width:= bmp.Canvas.PenPos.X;

нифига.. всё равно не учитывается Italic..

я так понял никто тут не поможет?


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо