Как получить правильную ширину символа для TrueType
От: Balrog Россия  
Дата: 08.01.04 09:13
Оценка:
Функции GetCharWidth и GetCharABSWidths возвращают ширину символа, однако если распечатываешь символы с указанной шириной они иногда наезжают друг на друга, а вот функция TextOut распечатывает последовательности символов нормально. Но мне нужно знать ширину символов. Что посоветуете?

08.01.04 13:05: Перенесено из 'C/C++'
man /dev/hands
Re: Как получить правильную ширину символа для TrueType
От: SchweinDeBurg Россия https://zarezky.spb.ru/
Дата: 08.01.04 09:51
Оценка:
Здравствуйте, Balrog, Вы писали:

B>Функции GetCharWidth и GetCharABSWidths возвращают ширину символа, однако если распечатываешь символы с указанной шириной они иногда наезжают друг на друга, а вот функция TextOut распечатывает последовательности символов нормально. Но мне нужно знать ширину символов. Что посоветуете?


GetTextExtentPoint32()

P.S.
Это бы лучше в WinAPI/MFC спрашивать.
- Искренне ваш, Поросенок Пафнутий
Re: Как получить правильную ширину символа для TrueType
От: adontz Грузия http://adontz.wordpress.com/
Дата: 08.01.04 11:11
Оценка: 1 (1)
Здравствуйте, Balrog, Вы писали:

B>Функции GetCharWidth и GetCharABSWidths возвращают ширину символа, однако если распечатываешь символы с указанной шириной они иногда наезжают друг на друга, а вот функция TextOut распечатывает последовательности символов нормально. Но мне нужно знать ширину символов. Что посоветуете?


У символовов помимо их собственной ширины есть ещё расстояние между ними. причём разное для разных пар символов.
Например AV AA, между AA расстояние положительное, а между AV может быть и отрицательным, то есть V началась (верхний левый кончик) там где A (нижний правый кончик) ещё не закончилась (в смысле по горизонтали)
Называеться это чудо кажется кёрнинг. Как это смотреть не знаю, а вот то что символы нельзя выводить по одному знаю.

Есть исклюшения! Courier New и иже с ними fixed-width шрифты. У них вроде interleaving входит в заявленную ширину символа.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re: Как получить правильную ширину символа для TrueType
От: Chaka Украина  
Дата: 08.01.04 11:33
Оценка:
Здравствуйте, Balrog, Вы писали:

B>Функции GetCharWidth и GetCharABSWidths возвращают ширину символа, однако если распечатываешь символы с указанной шириной они иногда наезжают друг на друга, а вот функция TextOut распечатывает последовательности символов нормально. Но мне нужно знать ширину символов. Что посоветуете?


Использовать DrawText с указанием в параметре uFormat флажка DT_CALCRECT — при этом текст не выводится, а модифицируется параметр lpRect (в результате он содержит размеры прямоугольника, достаточного для того, чтобы в него вместился текст).
WBR, Chaka
Re: Как получить правильную ширину символа для TrueType
От: Thanatos Украина  
Дата: 08.01.04 11:37
Оценка:
Здравствуйте, Balrog, Вы писали:

B>Функции GetCharWidth и GetCharABSWidths возвращают ширину символа, однако если распечатываешь символы с указанной шириной они иногда наезжают друг на друга, а вот функция TextOut распечатывает последовательности символов нормально. Но мне нужно знать ширину символов. Что посоветуете?


Считать нужно ширину всей строки.
Попробуй GetTextMetrics (но — _только_ для TrueType).
Лучший дар, который мы получили от природы и который лишает нас всякого права жаловаться – это возможность сбежать. /М.Монтень/
Re: Как получить правильную ширину символа для TrueType
От: MaximE Великобритания  
Дата: 09.01.04 00:47
Оценка:
Balrog wrote:

> Функции GetCharWidth и GetCharABSWidths возвращают ширину символа, однако если распечатываешь символы с указанной шириной они иногда наезжают друг на друга, а вот функция TextOut распечатывает последовательности символов нормально. Но мне нужно знать ширину символов. Что посоветуете?


GetCharABCWidths() возвращает значения, которые надо сложить, чтобы получить ширину символа.

Также есть таблица кернинга (у не bitmap шрифтов), в которой записано значение дополнительного интервала (положительный или отрицательный) между определенными парами символов (такими как, например, WA LT ГЛ и т.д.). Этот интервал нужно прибавить к ширине первого символа.

Вот тебе класс — генератор ширин (advance). Сгенерированые им ширины передавай в ф-цию ExtTextOut() в последнем параметре lpDx. Функция GetCharacterPlacement() обеспечивает ту же функциональность, что и данный класс, но содержит ошибки, которые делают ее использование практически невозможным.

inline
DWORD
make_dword(char a, char b)
     {
     return static_cast<DWORD>(reinterpret_cast<unsigned char&>(a)) << 16
         | reinterpret_cast<unsigned char&>(b);
     }

inline
DWORD
make_dword(WORD a, WORD b)
     {
     return static_cast<DWORD>(a) << 16 | b;
     }

class advance_generator
     {
     public:
         typedef std::vector<int> advances;
         typedef std::hash_map<DWORD, int, mtn::identity<DWORD> > kerning_pairs;

     public:
         advance_generator(HDC ref_dc)
             : abcs_(0x100)
             {
             META_VERIFY(::GetCharABCWidths(ref_dc, 0, abcs_.size() - 1, &abcs_[0]));

             DWORD const kerning_pairs_num(::GetKerningPairs(ref_dc, ~0, 0));
             META_ASSERT(kerning_pairs_num || S_OK == ::GetLastError());

             if(kerning_pairs_num)
                 {
                 std::vector<KERNINGPAIR> kp(kerning_pairs_num);
                 META_VERIFY(kerning_pairs_num == ::GetKerningPairs(ref_dc, kerning_pairs_num, &kp[0]));

                 for_const_begin_end(std::vector<KERNINGPAIR>, kp, i)
                     {
                     kerning_pairs_.insert(kerning_pairs::value_type(make_dword(i->wFirst, i->wSecond), i->iKernAmount));
                     }
                 }
             }

     public:
         void generate(char const* text, size_t lenght, int max_width, bool truncate, advances& a) const
             {
             advances result(lenght);

             size_t last_char(0);
             forr(int t(0); last_char < lenght; ++last_char)
                 {
                 ABC const& abc = abcs_[text[last_char]];
                 result[last_char] = abc.abcA + abc.abcB + abc.abcC;

                 if(last_char < lenght - 1)
                     {
                     kerning_pairs::const_iterator pair(kerning_pairs_.find(make_dword(text[last_char], text[last_char + 1])));
                     if(pair != kerning_pairs_.end())
                         {
                         result[last_char] += pair->second;
                         }
                     }

                 if(truncate && (t += result[last_char]) > max_width)
                     break;
                 }

             advances(result.begin(), result.begin() + last_char).swap(a);
             }

     private:
         std::vector<ABC> abcs_;
         kerning_pairs kerning_pairs_;
     };


--
Maxim Egorushkin
MetaCommunications Engineering
http://www.meta-comm.com/engineering/
Posted via RSDN NNTP Server 1.8 beta
Re[2]: Как получить правильную ширину символа для TrueType
От: Balrog Россия  
Дата: 09.01.04 14:19
Оценка:
Мне не нужен кернинг. Мне не нужно узнавать расстояние между символами. Я пишу небольшую утилитку для себя, которая генерирует наборы символов для скинов к Winamp и QCD. Поэтому там каждый символ должен умещатся строго в прямоугольник. В общем проблему я решил, дело был не в АПИшных функциях: я смещение символа в строке неправильно считал. Возникла другая проблема: если шрифт сделать курсивным, то ширина символов по идее должна увеличиться, но она не увеличивается.
man /dev/hands
Re[3]: Как получить правильную ширину символа для TrueType
От: Balrog Россия  
Дата: 09.01.04 14:26
Оценка:
код используется такой:


void OutText(HDC dc)
{
    int Width = 0;
    int Offset = 0;
    char sz[2] = "\0";
    for(int i = 32; i <= 255; i++) {
        MoveToEx(dc, Offset + 1, 0, NULL);
        sz[0] = i;
        GetCharWidth(dc, i, i, &Width);
        TextOut(dc, Offset, 2, sz, 1);
        Offset += Width + 1;
        LineTo(dc, Offset, 0);
    }
}


Сверху ещё рисуется линия по ширине символа, сдвинутая на один пиксел
man /dev/hands
Re[3]: Как получить правильную ширину символа для TrueType
От: MaximE Великобритания  
Дата: 11.01.04 23:15
Оценка:
Balrog wrote:

> Мне не нужен кернинг. Мне не нужно узнавать расстояние между символами.


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

--
Maxim Egorushkin
MetaCommunications Engineering
http://www.meta-comm.com/engineering/
Posted via RSDN NNTP Server 1.8 beta
Re: Как получить правильную ширину символа для TrueType
От: Аноним  
Дата: 13.01.04 00:00
Оценка:
Здравствуйте, Balrog, Вы писали:

B>Функции GetCharWidth и GetCharABSWidths возвращают ширину символа, однако если распечатываешь символы с указанной шириной они иногда наезжают друг на друга, а вот функция TextOut распечатывает последовательности символов нормально. Но мне нужно знать ширину символов. Что посоветуете?



GetCharABSWidths. abcB — ширина самой картинки символа — то, что нужно.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.