Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > Размер QFont


Автор: math64 3.2.2013, 22:41
Как задать высоту QFont, чтобы текст влез в заданный прямоугольник?

Автор: Amp 3.2.2013, 23:15
http://forum.vingrad.ru/index.php?showtopic=351360&view=findpost&p=2486250 например

Автор: math64 4.2.2013, 07:49
Это под WinAPI. А мне нужно под Qt. Вывожу строку из одного символа. И обрезать межсторочный и межсимвольный интервал.
Код

        uint c = 0x1F0A1;
        QString s = QString::fromUcs4(&c, 1);
        QFont font ("Quivira", ?);
        painter.setBrush(Qt::white);
        painter.setPen(Qt::NoPen);
        painter.drawRect(x, y, w, h);
        painter.setPen(Qt::black);
        painter.setFont(font);
        painter.drawText(?, ?, s);

Автор: Amp 4.2.2013, 10:36
Цитата(math64 @  4.2.2013,  07:49 Найти цитируемый пост)
Это под WinAPI. А мне нужно под Qt.

Смысл тот же. Вычисляется прямоугольник в который вписывается текст для некоторого размера шрифта и потом подбирается коэфициент в соответствии с которым размер шрифта меняется.

Автор: math64 4.2.2013, 11:01
Теоретически это понятно, но практически не работает - иначе бы не стал открывать тему. Приходится подбирать магические константы, которые при изменении размера окна уже не подходят.

Автор: Amp 4.2.2013, 11:33
Переписал быстренько на питоне, вроде как надо работает:

Код

def paintEvent(self, event):
    painter = QPainter()

    text = "Ololo ololo ololo"
    rect = self.rect()
    font = QFont()

    painter.begin(self)
    
    font.setPointSize(rect.height() * float(72) / self.logicalDpiY())
    painter.setFont(font)

    text_rect = painter.fontMetrics().boundingRect(text)

    if text_rect.width() > rect.width():
        font.setPointSize(float(rect.width()) / text_rect.width() * font.pointSize())
        painter.setFont(font)

    painter.drawText(rect, Qt.AlignCenter, text)
    
    painter.end()

Автор: math64 4.2.2013, 12:58
Мне почему-то приходится умножать высоту на 2 чтобы получилось правильно:
Код

        uint c = 0x1F0A1;
        QString s = QString::fromUcs4(&c, 1);
        painter.setBrush(Qt::white);
        painter.setPen(Qt::NoPen);
        painter.drawRect(x, y, w, h);
        painter.setPen(Qt::black);
        QFont font("Quivira");
        font.setPointSize(h*72/logicalDpiY());
        painter.setFont(font);
        QRect r = painter.fontMetrics().boundingRect(s);
        if (r.height() > h) {
            font.setPointSize(font.pointSize()*h*2/r.height());
            painter.setFont(font);
        }
        QRect r2 = painter.fontMetrics().boundingRect(s);
        qDebug() << w << h << r << r2;
        painter.drawText(x - r2.left(), y + h, s);

Вывод qDebug:
74 134 QRect(6,-131 47x184) QRect(9,-189 67x265)

Автор: Amp 4.2.2013, 13:59
Ты карточную колоду что ли фонтами делаешь?

Автор: math64 4.2.2013, 14:16
Да, на устройстве с чёрно-белым экраном - обычные PNG плохо смотрятся и масштабируются, а QPicture там нет.

Автор: Amp 4.2.2013, 16:50
Так чего бы svg не взять?

Автор: math64 4.2.2013, 18:32
svg там тем более нет - видно сразу - нет соответствующего заголовочного файла. Разве что взять исходники и откомпилировать самому. QGraphicsView тоже нет - сначала хотел просто QSoloCards перекомпилировать.

Автор: Amp 5.2.2013, 12:32
Можешь сконвертировать символ в QPainterPath и работать уже как с вектором. Если выводить именно как текст, то скорее всего необходимо будет учитывать значения base/descender/ascender lines,  bearing left/right и т.п., чтобы сделать все "впритык". И, возможно, для совсем уж pixel perfect подгонки алгоритм будет итерационным.

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