GetTextExtentPoint32 и Simulated Fonts
От: Аноним  
Дата: 30.03.05 09:22
Оценка:
Для вывода текста мне необходимо вычислить размер BoundingRectangle.
Использую для этой цели GetTextExtentPoint32. Но если используемый вариант шрифта синтезируется из основного (в частности Italic для Tahoma), то результат оказывается не верным (в моём случае overhang не включается в общий размер). Как корректно выйти из данной ситуации?
Сейчас попробую как предложено в http://rsdn.ru/Forum/Message.aspx?mid=44480&only=1
Автор: Dutchman
Дата: 11.04.02
, но такой выход я не считаю хорошим. Во-первых есть вероятность столкнуться с проблемами выванными Clipping. И во-вторых Громоздко.
Re: GetTextExtentPoint32 и Simulated Fonts
От: Andrew S Россия http://alchemy-lab.com
Дата: 30.03.05 09:38
Оценка:
А>Для вывода текста мне необходимо вычислить размер BoundingRectangle.
А>Использую для этой цели GetTextExtentPoint32. Но если используемый вариант шрифта синтезируется из основного (в частности Italic для Tahoma), то результат оказывается не верным (в моём случае overhang не включается в общий размер). Как корректно выйти из данной ситуации?
А>Сейчас попробую как предложено в http://rsdn.ru/Forum/Message.aspx?mid=44480&only=1
Автор: Dutchman
Дата: 11.04.02
, но такой выход я не считаю хорошим. Во-первых есть вероятность столкнуться с проблемами выванными Clipping. И во-вторых Громоздко.


А DrawText с DT_CALCRECT тоже некорректно отрабатывает?
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[2]: GetTextExtentPoint32 и Simulated Fonts
От: Аноним  
Дата: 30.03.05 10:37
Оценка:
AS>А DrawText с DT_CALCRECT тоже некорректно отрабатывает?
Тоже некорректно. Размеры получаются аналогичные.
Re: GetTextExtentPoint32 и Simulated Fonts
От: Аноним  
Дата: 30.03.05 12:31
Оценка:
После дальнейших экспериментов выяснилось, что Simulated Fonts здесь играют не столь значительную роль.
Неточности могут проявляться и с другими шрифтами.
Как оказалось GetTextExtentPoint32 определяет вовсе не высоту/ширину строки как расстояние между крайними печатаемыми пикселями.
/Дальше я буду говорить только о ширине./
А как рассотяние от reference point до … точки куда сместиться reference point при TextOut с включеным TA_UPDATECP.

Упрощённо (не учитываем лигатуры, упрощенный кернинг)


Для каждого символа строки:
От refpoint смещаем на A, рисуем букву шириной B (смещаем на B), смещаем на C.

(Получаем расстояние от reference point перед выводом строки, до reference point после)

Это позволяет склеивать строку из кусочков последовательным вызовом TextOut, но даёт неверные результаты при опеределении какой же прямоугольник нужно выделить для той или иной строки. (почему DrawText даёт такой же результат остаётся не ясным).

Но не учтенным оказывается расстояние A первого символа и расстояние C последнего. Именно на эти величины и нужна коррекция. Если требуется определить расстояние от левого края первого символа, до правого края последнего, то коррекцию производить для любых значений A и С.

Если же требуется определить прямоугольник в который осуществлять вывод TextOut и при этом не столкнуться с Clipping, то только для отрицательных значений A и С.


BOOL GetTextExtentPoint32Adj(HDC    hDC,
        LPCSTR  lpStr,
        DWORD  dwLen, 
        LPSIZE sz, 
                BOOL maxSize)
{
    ABC abc;
    if (!::GetTextExtentPoint32(hDC, lpStr, dwLen, sz))
        return FALSE;
    if (!::GetCharABCWidths(hDC, lpStr[0], lpStr[0], &abc))
        return FALSE;
    if (maxSize || abc.abcA < 0)
        sz->cx-=abc.abcA;
    if(!::GetCharABCWidths(hDC, lpStr[dwLen-1], lpStr[dwLen-1], &abc))
        return FALSE;
    if (maxSize || abc.abcC < 0 )
        sz->cx-=abc.abcC;
    return TRUE;
}

Kirill Erofeev /tempo1232003 -at- yahoo.com/
Re[2]: GetTextExtentPoint32 и Simulated Fonts
От: The_Thing Россия
Дата: 21.05.09 13:59
Оценка:
Здравствуйте, Аноним, Вы писали:

Знаю, что пост старый, но столкнулся с этой проблемой только сейчас.

Может не на все случаи жизни подходит, не знаю всех случаев. Но у меня считало точно (обычный многострочный текст)
Мелочь, а кому-нить поможет
CSize CComent::GetSizeText(CDC *pDC, CString strText)
{
    LPCTSTR strBeg = strText;
    LPCTSTR strEnd = strBeg;
    LPCTSTR strCur = strBeg;
    size_t szLen = strText.GetLength();

    CSize sz(0, 0);
    while( *strEnd != NULL && 
        (strEnd - strBeg) < szLen )
    {
        while( *strEnd != _T('\r') &&
            *strEnd != _T('\n') && 
            *strEnd != NULL )
            ++strEnd;
        CSize _sz = pDC->GetTextExtent(strBeg, strEnd - strCur);
        sz.cx = max(sz.cx, _sz.cx);
        sz.cy += _sz.cy;
        if( *strEnd == _T('\r') &&
            *(strEnd+1) == _T('\n') )
            ++strEnd;
        strCur = ++strEnd;
    }
    return sz;
}


...
    CSize sz = GetSizeText(pDC, m_strText);
    CRect rc(m_pt.x, m_pt.y,
        m_pt.x + sz.cx+1, m_pt.y + sz.cy+1);
    // пиксель в пиксель :-)
    pDC->DrawText(m_strText, rc, DT_CENTER | DT_PATH_ELLIPSIS);

    pDC->Rectangle( m_pt.x, m_pt.y,
        m_pt.x + sz.cx+1, m_pt.y + sz.cy );
...
размер drawtext textout
Re[3]: GetTextExtentPoint32 и Simulated Fonts
От: rus blood Россия  
Дата: 21.05.09 16:00
Оценка:
Здравствуйте, The_Thing, Вы писали:

T_T>
T_T>CSize CComent::GetSizeText(CDC *pDC, CString strText)
T_T>{
T_T>    while( *strEnd != NULL && 
T_T>        (strEnd - strBeg) < szLen )
T_T>    {
T_T>        while( *strEnd != _T('\r') &&
T_T>            *strEnd != _T('\n') && 
T_T>            *strEnd != NULL )
T_T>            ++strEnd;
...................................
T_T>        if( *strEnd == _T('\r') &&
T_T>            *(strEnd+1) == _T('\n') )
T_T>            ++strEnd;
T_T>        strCur = ++strEnd;
T_T>    }
T_T>


Унылая попытка избежать пропуск нулевого символа...

Сделаю предположение, что этот код некорректно обработает табуляции...
Имею скафандр — готов путешествовать!
Re[4]: GetTextExtentPoint32 и Simulated Fonts
От: Carc Россия http://www.amlpages.com/home.php
Дата: 21.05.09 19:39
Оценка:
Здравствуйте, rus blood, Вы писали:
RB>Унылая попытка избежать пропуск нулевого символа...
ASSERT(!IsBadStringPtr((LPCTSTR)strText,INFINITE)); //Рулит адназначно!
Aml Pages Home
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.