Created
March 23, 2023 12:44
-
-
Save Waqar144/a58f29b235b667e6133f4beafeccb763 to your computer and use it in GitHub Desktop.
Using QGlyphRun for RTL text
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static void drawRTLTextWithDecorations(int xStart, QPainter *painter, QTextLayout *layout, const QVector<QTextLayout::FormatRange> &decorations) | |
{ | |
const auto glyphRuns = layout->glyphRuns(); | |
struct Glyph { | |
quint32 glyphIndex; | |
QPointF pos; | |
}; | |
QVector<Glyph> glyphs; | |
QRawFont f; | |
// layout->glyphRuns() contains QGlyphRuns in arbitrary order so collect it into a list | |
for (const auto &gr : glyphRuns) { | |
const auto glyphIndexes = gr.glyphIndexes(); | |
const auto positions = gr.positions(); | |
for (int i = 0; i < glyphIndexes.size(); ++i) { | |
glyphs.push_back({glyphIndexes[i], positions[i]}); | |
} | |
if (!f.isValid()) { | |
f = gr.rawFont(); | |
} | |
} | |
// sort them by descending order for rtl | |
std::sort(glyphs.begin(), glyphs.end(), [](Glyph l, Glyph r) { | |
return l.pos.x() > r.pos.x(); | |
}); | |
auto glyphRunForRange = [&glyphs, &f](int start, int length) -> std::optional<QGlyphRun> { | |
QGlyphRun r; | |
r.setRawFont(f); | |
QVector<quint32> glyphIndices; | |
QVector<QPointF> positions; | |
for (int i = start; i < (start + length); ++i) { | |
glyphIndices << glyphs[i].glyphIndex; | |
positions << glyphs[i].pos; | |
} | |
r.setGlyphIndexes(glyphIndices); | |
r.setPositions(positions); | |
return r; | |
}; | |
// glyphrun for decoration | |
QVector<QGlyphRun> newGlyphRuns; | |
for (const auto &fr : decorations) { | |
const auto &fmt = fr.format; | |
if (fmt.hasProperty(QTextCharFormat::ForegroundBrush) || fmt.hasProperty(QTextCharFormat::BackgroundBrush)) { | |
auto run = glyphRunForRange(fr.start, fr.length); | |
if (run.has_value()) { | |
newGlyphRuns << run.value(); | |
} | |
} | |
} | |
painter->setPen(Qt::red); | |
for (const auto &r : newGlyphRuns) { | |
painter->drawGlyphRun(QPointF(-xStart, 0), r); | |
// painter->fillRect(r.boundingRect(), Qt::green); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment