Эффективно рисовать текст вокруг QPainterPath - PullRequest
0 голосов
/ 02 апреля 2019

Следующий код рисует текст вокруг QPainterPath:

QString text = "Short text";
QPainterPath rawPath;
// fill path ...

while (...)
{
    double percent = ...;
    double angle = rawPath.angleAtPercent(percent);
    QPointF point = rawPath.pointAtPercent(percent);

    m_painter.save();

    m_painter.translate(point);
    m_painter.rotate(-angle);

    // Version 1:
    //m_painter.drawText(0, 0, text.at(currentChar));

    // Version 2:
    QPainterPath p2;
    p2.addText(0, 0, font, text.at(currentChar));
    m_painter.drawPath(p2);

    m_painter.restore();
}

Графический результат, как и ожидалось, но производительность как версии 1, так и версии 2 очень низкая. Узким местом является QPainter::drawText() соответственно QPainterPath::addText() метод. Есть ли более эффективный способ рисования текста вокруг пути?

С уважением,

1 Ответ

1 голос
/ 02 апреля 2019

Нет встроенного метода для рисования текста по пути.

Но, если QPainter недостаточно эффективен, вы можете получить некоторые преимущества, создав новый путь с вашим текстом ирисование после цикла (вы не будете использовать QPainter::save() и QPainter::restore() в цикле):

void paintEvent(QPaintEvent* event)
    {
        QString text = "Short text";
        text = text.repeated(1000); // Check with a very long text
        QPainterPath rawPath;
        rawPath.addEllipse(QRect(0, 0, 200, 200));

        QPainterPath path;

        double const step = 1.0 / double(text.length());
        double percent = 0.0;
        for(QChar const& c: text)
        {
            double angle = rawPath.angleAtPercent(percent);
            QPointF point = rawPath.pointAtPercent(percent);

            QTransform mat;
            mat.rotate(-angle);
            QPainterPath p2;
            p2.addText(0, 0, font(), c);
            p2 = mat.map(p2);
            path.addPath(p2.translated(point));
            percent += step;
        }

        QPainter painter(this);
        painter.drawPath(path.translated(100, 100));
    }
...