繁体   English   中英

QPainter :: drawText,为每个角色获取边界框

[英]QPainter::drawText, get bounding boxes for each character

我正在使用QPainter在QImage上绘制多行文字。 但是,我还需要在每个角色的边界框周围显示一个彩色矩形。

所以我需要知道每个角色在绘制时的边界框。

例如,对于

painter.drawText(QRect(100, 100, 200, 200), Qt::TextWordWrap, "line\nline2", &r);

我需要获得10个矩形,考虑换行,自动换行,制表符等。

例如,由于换行符,第二个'l'的矩形将位于第一个'l'的矩形下方,而不是'e'的右侧。

像这张照片中红色矩形的坐标(我把它们放在手边,所以它们不是真正的正确位置):

在此输入图像描述

这可能不是最好的解决方案,但它是我能想到的最好的解决方案。

我相信你必须“自己动手”。 也就是说,不是绘制文本块,而是一次绘制一个字符。 然后,您可以使用QFontMetrics获取每个角色的边界框。

这是一个小工作,但不是太糟糕。 像(伪代码,而不是代码):

QFontMetrics fm(myFont, paintDevice);
int x = startX;
int y = startY;
for (unsigned int i = 0; i < numChars; i++)
{
    char myChar = mystr[i];  // get character to print/bound
    QRect rect = fm.boundingRect( myChar );   // get that char's bounding box
    painter.drawText(x, y, Qt::TextWordWrap, mystr[i], &r);  // output char
    painter.drawRect(...); // draw char's bounding box using 'rect'
    x += rect.width();     // advance current position horizontally

    // TODO:
    // if y > lineLen      // handle cr
    //     x = startX;
    //     y += line height

}

查看QFontMetrics,它有许多不同的方法来获取边界框,最小边界框等。

QFontMetrics 4.7

啊......我现在看到你正在使用的重载返回实际的边界矩形。 如果您愿意,您可以使用它并跳过QFontMetrics - 否则整体算法是相同的。

您可以使用QFontMetrics::boundingRect(QChar)检索单个字符的边界框,但它们必须以偏移量( QFontMetrics::ascent以及左边前面字符的QFontMetrics::width呈现因为它们是相对于字体的基线而不是相对于完整字符串的边界框的底部。
还必须单独处理几行。 QFontMetrics::lineSpacing为您提供偏移量。

QPainter painter(this);
painter.setFont(QFont("Arial", 72));

auto pen = painter.pen();

QString text{"line\nline2\ngg\n`"};
QRect boundingRect;
painter.drawText(rect(), Qt::AlignLeft | Qt::AlignTop, text, &boundingRect);
painter.drawRect(boundingRect.adjusted(0, 0, -pen.width(), -pen.width()));

pen.setColor(Qt::red);
painter.setPen(pen);
const auto lines = text.split('\n');
const auto fm = painter.fontMetrics();
for (int linei = 0; linei < lines.size(); ++linei) {
    const auto & line = lines[linei];
    for (int chi = 0; chi < line.size(); ++chi) {
        const auto bounds = fm.boundingRect(line[chi]);
        const auto xoffset = bounds.x() + fm.width(line, chi);
        const auto lineOffset = linei * fm.lineSpacing() + fm.ascent();
        const auto yoffset = lineOffset + bounds.y();
        painter.drawRect(QRect{xoffset, yoffset, bounds.width(), bounds.height()});
    }
}

结果是

遗憾的是,这并不完美。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM