Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Рисование текста в RECT


Автор: suxxor 4.5.2012, 16:56
Есть HDC, это картинка, также есть RECT это область на картинке в которой необходимо нарисовать текст.

ВОПРОС: Нужно автоматически выбирать размер шрифта для вписывания в RECT. Нужно подобрать максимальный размер шрифта, чтоб текст не вылизал за границы

Автор: Amp 4.5.2012, 17:28
Перебираешь размеры шрифта, вызывая GetTextExtentPoint32. Если результат начинает влезать - останавливаешься. Начинаешь с размера шрифта, который заведомо больше высоты заданного RECT. То есть берешь RECT, прибавляешь пару пикселей, переводишь в поинты и задаешь изначальной высотой шрифта. Как-то так.

Добавлено через 3 минуты и 24 секунды
Либо, получив размер текста, для некоторого шрифта по-умолчанию изменить его размер пропорционально тому насколько он влезает/ не влезает.

Автор: suxxor 4.5.2012, 17:43
Код

RECT rc = {0};
SIZE size = {0};

int iFontSize = 1;

while(1)
{
    HFONT hFont = CreateFont(iFontSize++, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);

    // копируем "hFont" в "hDC"

    GetTextExtentPoint32(hDC, text, lenght, &size);

    if(size.cx > rc.right || size.cy > rc.bottom)
        return iFontSize - 2; // или на сколько уменьшать лучше?
}


поправьте если неправильно

Автор: Amp 4.5.2012, 19:18
Если left/top отличны от 0, то right - left, bottom - top.

Автор: suxxor 4.5.2012, 19:22
Amp, okay - они NULL

осталось вышенаписанный цикл оптимизировать, чтоб уменьшить потребление памяти (к примеру с какой высоты начинать CreateFont итд)

Автор: suxxor 4.5.2012, 21:28
и ещё проблема: мне нужно уместить слово (макс. из 4-5 символов) в иконке 32x32, получается нечитаемый текст, как исправить?

Автор: Amp 5.5.2012, 10:36
Как я и писал - составить пропорцию. Например высота и ширина области 32 на 100. 32 пиксела - это 24 поинта (если брать стандартный dpi равный 96). Выставляем такой шрифт, получаем размер текста. Если он по ширине влезает - ок. В противном случае вычисляем размер шрифта как 24 * (ширина области, в данном случае 100) / (ширина полученного текста) и от этого пляшем. Как-то так, думаю, что должно сработать.

Цитата(suxxor @  4.5.2012,  21:28 Найти цитируемый пост)
мне нужно уместить слово (макс. из 4-5 символов) в иконке 32x32, получается нечитаемый текст, как исправить? 

Может отрисовывать текст без сглаживания?

Автор: suxxor 5.5.2012, 10:51
Можно пример этих вычислений? Я без этого непонимаю!

Цитата
Может отрисовывать текст без сглаживания? 

Ай, с ним и без него - получается УГ

Автор: Amp 5.5.2012, 12:33
На API не пишу, впрочем из кода итак все понятно:

Код

wxBitmap DrawAndFitText(const wxString& text, const wxRect &rect)
{
    wxBitmap bitmap;
    wxMemoryDC dc;
    wxFont font;
    
    bitmap.Create(rect.GetWidth(), rect.GetHeight(), 24);
    
    dc.SelectObject(bitmap);
    dc.SetBackground(*wxWHITE_BRUSH);
    dc.Clear();
    
    font.SetPointSize(rect.GetHeight() * 72.0 / dc.GetPPI().y);
    dc.SetFont(font);
    
    wxSize text_size = dc.GetTextExtent(text);
    
    if(text_size.x > rect.GetWidth())
    {
        font.SetPointSize(static_cast<float>(rect.GetWidth()) / text_size.x * font.GetPointSize());
        dc.SetFont(font);
    }
    
    dc.DrawLabel(text, rect, wxALIGN_LEFT | wxALIGN_TOP);
    
    dc.SelectObject(wxNullBitmap);
    
    return bitmap;
}

Автор: suxxor 5.5.2012, 13:18
Я так понял что это:
Код

font.SetPointSize(rect.GetHeight() * 72.0 / dc.GetPPI().y);


равно этому на WInAPI:
Код

MulDiv(ptSize, GetDeviceCaps(hDC, LOGPIXELSY), 72)


да??

метод SetPointSize это эквивалент CreateFont(*ЭТОГО*, ...)???

Автор: Amp 5.5.2012, 13:37
Судя по документации к CreateFont, MulDiv(...) должен идти со знаком минус. Впрочем, как я понимаю, CreateFont позволяет задавать сразу в высоту в пикселах, если передать ему высоту как положительный аргумент, поэтому можно обойтись без перевода pixel -> point.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)