diff options
author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2014-09-16 14:18:36 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2014-09-18 00:13:28 +0200 |
commit | 9b556afc5a2507077dff54c18a2b19c7df3c4575 (patch) | |
tree | c64534b406f6856ae5a3061a676af9285b248be0 /src/gui/text/qtextlayout.cpp | |
parent | 82dbea55a746b5ba58316186b201dc6505782d17 (diff) |
Fix menu mnemonic inside ligatures
The code to draw underlines on specific characters in widget menu could
not handle ligatures. Instead of using special code to handle this case
this patch changes the mnemonic underlines to use normal format-ranges
making the text engine deal with splitting ligatures as necessary.
Task-number: QTBUG-20960
Change-Id: I6159110eae7aa8c819af16ba4a393d758871e2e0
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
Diffstat (limited to 'src/gui/text/qtextlayout.cpp')
-rw-r--r-- | src/gui/text/qtextlayout.cpp | 155 |
1 files changed, 39 insertions, 116 deletions
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 9919ce6bb4..ad00396553 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -2021,79 +2021,6 @@ int QTextLine::textLength() const return eng->lines[index].length + eng->lines[index].trailingSpaces; } -static void drawMenuText(QPainter *p, QFixed x, QFixed y, const QScriptItem &si, QTextItemInt &gf, QTextEngine *eng, - int start, int glyph_start) -{ - int ge = glyph_start + gf.glyphs.numGlyphs; - int gs = glyph_start; - int end = start + gf.num_chars; - unsigned short *logClusters = eng->logClusters(&si); - QGlyphLayout glyphs = eng->shapedGlyphs(&si); - QFixed orig_width = gf.width; - - int *ul = eng->underlinePositions; - if (ul) - while (*ul != -1 && *ul < start) - ++ul; - bool rtl = si.analysis.bidiLevel % 2; - if (rtl) - x += si.width; - - do { - int gtmp = ge; - int stmp = end; - if (ul && *ul != -1 && *ul < end) { - stmp = *ul; - gtmp = logClusters[*ul-si.position]; - } - - gf.glyphs = glyphs.mid(gs, gtmp - gs); - gf.num_chars = stmp - start; - gf.chars = eng->layoutData->string.unicode() + start; - QFixed w = 0; - while (gs < gtmp) { - w += glyphs.effectiveAdvance(gs); - ++gs; - } - start = stmp; - gf.width = w; - if (rtl) - x -= w; - if (gf.num_chars) - QPainterPrivate::get(p)->drawTextItem(QPointF(x.toReal(), y.toReal()), gf, eng); - if (!rtl) - x += w; - if (ul && *ul != -1 && *ul < end) { - // draw underline - gtmp = (*ul == end-1) ? ge : logClusters[*ul+1-si.position]; - ++stmp; - gf.glyphs = glyphs.mid(gs, gtmp - gs); - gf.num_chars = stmp - start; - gf.chars = eng->layoutData->string.unicode() + start; - gf.logClusters = logClusters + start - si.position; - w = 0; - while (gs < gtmp) { - w += glyphs.effectiveAdvance(gs); - ++gs; - } - ++start; - gf.width = w; - gf.underlineStyle = QTextCharFormat::SingleUnderline; - if (rtl) - x -= w; - QPainterPrivate::get(p)->drawTextItem(QPointF(x.toReal(), y.toReal()), gf, eng); - if (!rtl) - x += w; - gf.underlineStyle = QTextCharFormat::NoUnderline; - ++gf.chars; - ++ul; - } - } while (gs < ge); - - gf.width = orig_width; -} - - static void setPenAndDrawBackground(QPainter *p, const QPen &defaultPen, const QTextCharFormat &chf, const QRectF &r) { QBrush c = chf.foreground(); @@ -2483,52 +2410,48 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR Q_ASSERT(gf.fontEngine); - if (eng->underlinePositions) { - // can't have selections in this case - drawMenuText(p, iterator.x, itemBaseLine, si, gf, eng, iterator.itemStart, iterator.glyphsStart); - } else { - QPointF pos(iterator.x.toReal(), itemBaseLine.toReal()); - if (format.penProperty(QTextFormat::TextOutline).style() != Qt::NoPen) { - QPainterPath path; - path.setFillRule(Qt::WindingFill); - - if (gf.glyphs.numGlyphs) - gf.fontEngine->addOutlineToPath(pos.x(), pos.y(), gf.glyphs, &path, gf.flags); - if (gf.flags) { - const QFontEngine *fe = gf.fontEngine; - const qreal lw = fe->lineThickness().toReal(); - if (gf.flags & QTextItem::Underline) { - qreal offs = fe->underlinePosition().toReal(); - path.addRect(pos.x(), pos.y() + offs, gf.width.toReal(), lw); - } - if (gf.flags & QTextItem::Overline) { - qreal offs = fe->ascent().toReal() + 1; - path.addRect(pos.x(), pos.y() - offs, gf.width.toReal(), lw); - } - if (gf.flags & QTextItem::StrikeOut) { - qreal offs = fe->ascent().toReal() / 3; - path.addRect(pos.x(), pos.y() - offs, gf.width.toReal(), lw); - } + QPointF pos(iterator.x.toReal(), itemBaseLine.toReal()); + if (format.penProperty(QTextFormat::TextOutline).style() != Qt::NoPen) { + QPainterPath path; + path.setFillRule(Qt::WindingFill); + + if (gf.glyphs.numGlyphs) + gf.fontEngine->addOutlineToPath(pos.x(), pos.y(), gf.glyphs, &path, gf.flags); + if (gf.flags) { + const QFontEngine *fe = gf.fontEngine; + const qreal lw = fe->lineThickness().toReal(); + if (gf.flags & QTextItem::Underline) { + qreal offs = fe->underlinePosition().toReal(); + path.addRect(pos.x(), pos.y() + offs, gf.width.toReal(), lw); + } + if (gf.flags & QTextItem::Overline) { + qreal offs = fe->ascent().toReal() + 1; + path.addRect(pos.x(), pos.y() - offs, gf.width.toReal(), lw); + } + if (gf.flags & QTextItem::StrikeOut) { + qreal offs = fe->ascent().toReal() / 3; + path.addRect(pos.x(), pos.y() - offs, gf.width.toReal(), lw); } - - p->save(); - p->setRenderHint(QPainter::Antialiasing); - //Currently QPen with a Qt::NoPen style still returns a default - //QBrush which != Qt::NoBrush so we need this specialcase to reset it - if (p->pen().style() == Qt::NoPen) - p->setBrush(Qt::NoBrush); - else - p->setBrush(p->pen().brush()); - - p->setPen(format.textOutline()); - p->drawPath(path); - p->restore(); - } else { - if (noText) - gf.glyphs.numGlyphs = 0; // slightly less elegant than it should be - QPainterPrivate::get(p)->drawTextItem(pos, gf, eng); } + + p->save(); + p->setRenderHint(QPainter::Antialiasing); + //Currently QPen with a Qt::NoPen style still returns a default + //QBrush which != Qt::NoBrush so we need this specialcase to reset it + if (p->pen().style() == Qt::NoPen) + p->setBrush(Qt::NoBrush); + else + p->setBrush(p->pen().brush()); + + p->setPen(format.textOutline()); + p->drawPath(path); + p->restore(); + } else { + if (noText) + gf.glyphs.numGlyphs = 0; // slightly less elegant than it should be + QPainterPrivate::get(p)->drawTextItem(pos, gf, eng); } + if (si.analysis.flags == QScriptAnalysis::Space && (eng->option.flags() & QTextOption::ShowTabsAndSpaces)) { QBrush c = format.foreground(); |