Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2007.02.11;
Скачать: [xml.tar.bz2];

Вниз

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 вся ветка

Форум: "WinAPI";
Текущий архив: 2007.02.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.045 c
15-1169294773
Vovan #2
2007-01-20 15:06
2007.02.11
Большой EXE


1-1166135792
conless
2006-12-15 01:36
2007.02.11
ScrollBox, помогите разобраться!


8-1150218652
novarm44
2006-06-13 21:10
2007.02.11
Скорость прорисовки


1-1166031886
transp
2006-12-13 20:44
2007.02.11
Панель без "отрисовки"


3-1163930449
KIT
2006-11-19 13:00
2007.02.11
ПОМОГИТЕ С ЗАПРОСОМ





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский