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

Вниз

GetTextExtentExPoint с учетом табуляций?   Найти похожие ветки 

 
AlexeyT ©   (2006-09-30 08:41) [0]

Используется GetTextExtentExPoint для получения позиций символов в строке. Строка юникодная (сразу предупреждаю), например арабские символы.

Вопрос такой: Как получить позиции символов, если строка печаталась с учетом табуляций: т.е. через TabbedTextOut ? Может, какая отдельная функция есть, или эту как-то использовать с табуляциями можно?
Спасибо.


 
guav ©   (2006-09-30 15:14) [1]

Скорее всего, это GetTabbedTextExtent .

Рекомендую использовать DrawTextEx , как самую универсальную из функций вывода текста, она сама себе и есть "аналог GetTextExtentExPoint" http://delphimaster.net/view/1-1159471239/


 
AlexeyT ©   (2006-09-30 16:02) [2]

>Скорее всего, это GetTabbedTextExtent .

Не совсем: она не возвращает ширины промежуточных символов, только ширину всей строки. А нужны ширины символов...

DrawTextEx также не возвращает эти значения...


 
guav ©   (2006-09-30 18:23) [3]

> Не совсем: она не возвращает ширины промежуточных символов,
> только ширину всей строки.

Понял проблему.  
Тогда не знаю такой функции.

Видимо, придётся или вызывать GetTabbedTextExtent для каждого nCount от 1 до длины строки.

Другой вариант, отказаться от TabbedTextExtent  и вызывать GetTextExtentExPoint, самому просчитывать табуляцию и вызывать ExtTextOut.


 
AlexeyT ©   (2006-09-30 20:15) [4]

>Понял проблему.  
>Тогда не знаю такой функции.
>Видимо, придётся или вызывать GetTabbedTextExtent для каждого nCount от 1 до длины строки.

Этого я и боялся...


 
guav ©   (2006-09-30 22:14) [5]

Могу ещё посоветовать попытаться поотлаживать стандартный edit, узнать какие функции он вызывает. Edit Control решает твою задачу при определении позиции курсора.

в Riched20.dll (библиотеке, реализующей Rich Edit Control в экспорте) используется ExtTextOut и GetCharWidth (это видно по импорту этих и не-импорту аналогов). Т.е. там способ похож на
> отказаться от TabbedTextExtent  и вызывать GetTextExtentExPoint,
> самому просчитывать табуляцию и вызывать ExtTextOut.


 
AlexeyT ©   (2006-10-01 10:54) [6]

2guav

Ага, спасибо.
В общем, я пока остановился на втором твоем совете - вывод через TextOut с заменой табуляции пробелами и просчет позиций через GetTextExtentExPoint.

Почему не первый способ - потому, что подсчет длин промежуточных строк не годится в случае юникода: там длина промежуточной строки может *превышать* длину всей строки. Такое бывает.


 
AlexeyT ©   (2006-10-01 11:48) [7]

Вот врапперы, которые я в итоге написал, с учетом табуляций задаваемого размера. Может, еще кому пригодится.
//Win32Platform - это переменная из SysUtils

procedure StringOut(Canvas: TCanvas; const X, Y: integer; const Str: WideString; TabSize: word = 8);
var
 S: WideString;
begin
 S:= SReplaceTabsW(Str, TabSize);

 if Win32Platform=VER_PLATFORM_WIN32_NT
   then Windows.TextOutW(Canvas.Handle, X, Y, PWChar(S), Length(S))
   else Windows.TextOutA(Canvas.Handle, X, Y, PChar(string(S)), Length(S));
end;

type
 TStringExtent = array[0..cMaxTextWidth] of integer;

function StringExtent(Canvas: TCanvas; const Str: WideString; var Ext: TStringExtent; TabSize: word = 8): boolean;
var
 S: WideString;
 Dx: array[0..cMaxTabSize*cMaxTextWidth] of integer;
 Size: TSize;
 i, j: integer;
begin
 S:= SReplaceTabsW(Str, TabSize);

 FillChar(Dx, SizeOf(Dx), 0);
 if Win32Platform=VER_PLATFORM_WIN32_NT
   then Result:= GetTextExtentExPointW(Canvas.Handle, PWChar(S), Length(S), 0, nil, @Dx[1], Size)
   else Result:= GetTextExtentExPointA(Canvas.Handle, PChar(string(S)), Length(S), 0, nil, @Dx[1], Size);

 FillChar(Ext, SizeOf(Ext), 0);
 if Result then
   begin
   i:= 0;
   j:= 0;
   repeat
     Inc(i);
     Inc(j);
     if i>Length(Str) then Break;
     if Str[i]=#9 then Inc(j, TabSize-1);
     Ext[i]:= Dx[j];
   until false;
   end;
end;


 
guav ©   (2006-10-01 18:50) [8]

> В общем, я пока остановился на втором твоем совете - вывод
> через TextOut с заменой табуляции пробелами и просчет позиций
> через GetTextExtentExPoint.

Заменять табы пробелами не обязательно. Я имел в виду другое.
ExtTextOut принимает массив позиций, похожий на массив, возвращаемый GetTextExtentExPoint.
Т.е. вызвали GetTextExtentExPoint, затем для табов сами просчитали позиции согласно жеаемым табстопам и через ExtTextOut выводим точно так, как рассчитали используя GetTextExtentExPoint.
Это сложнее чем вышеприведенный код, зато табы можно сделать не "длиными пробелами" а "настоящими табами".


> там длина промежуточной строки может *превышать* длину всей
> строки. Такое бывает.

Хм. интересно. А как так ?


 
AlexeyT ©   (2006-10-01 22:04) [9]


> , затем для табов сами просчитали позиции согласно жеаемым
> табстопам и через ExtTextOut выводим точно так, как рассчитали
> используя GetTextExtentExPoint.
> Это сложнее чем вышеприведенный код, зато табы можно сделать
> не "длиными пробелами" а "настоящими табами".


Интересно. ExtTextOut оказывается может выводит по заданным позициям?..
Да, для "настоящих табов" так наверное и нужно делать - я пока оставлю свой вариант.


> > там длина промежуточной строки может *превышать* длину
> всей
> > строки. Такое бывает.
>
> Хм. интересно. А как так ?


Вот так, увидел экспериментально. Был поток каких-то юникодных символов, неотображаемых моими шрифтами - квадратики. Так вот когда квадратиков было много (40 подряд, например), это были "короткие квадратики" (шириной 2-3). Когда они переносились на след. строку и их было мало (5-10), рисовались как "полные квадратики", (с шириной=высоте). Это TextOut так выводила.



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

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

Наверх




Память: 0.5 MB
Время: 0.042 c
15-1169130890
Stanislav
2007-01-18 17:34
2007.02.11
Кто настраивал GPS/GPRS трекеры?


4-1159453855
Dib@zol
2006-09-28 18:30
2007.02.11
Глюк с перерисовкой окна


1-1165021404
allrussia
2006-12-02 04:03
2007.02.11
Закрепление и привязка компонентов на форме


15-1169485507
Virgo_Style
2007-01-22 20:05
2007.02.11
День авиации ПВО


1-1166602375
bear99
2006-12-20 11:12
2007.02.11
Удалений информации с дика