簡體   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