Текущий архив: 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 - это переменная из SysUtilsprocedure 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.47 MB
Время: 0.041 c