OSDN Git Service

implement strikeout and overline text decoration via QPainterPath
authorIvailo Monev <xakepa10@gmail.com>
Sun, 9 Jan 2022 15:42:29 +0000 (17:42 +0200)
committerIvailo Monev <xakepa10@gmail.com>
Sun, 9 Jan 2022 15:42:29 +0000 (17:42 +0200)
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
src/gui/painting/qpainter.cpp
src/gui/painting/qpainterpath.cpp
src/gui/text/qtextlayout.cpp

index a096569..62ef535 100644 (file)
@@ -5052,8 +5052,6 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
     pen.setWidthF(fe->lineThickness().toReal());
     pen.setCapStyle(Qt::FlatCap);
 
-    QLineF line(pos.x(), pos.y(), pos.x() + qFloor(width), pos.y());
-
     const qreal underlineOffset = fe->underlinePosition().toReal();
     // deliberately ceil the offset to avoid the underline coming too close to
     // the text above it.
@@ -5079,7 +5077,7 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
         painter->fillRect(pos.x(), 0, qCeil(width), qMin(wave.height(), descent), wave);
         painter->restore();
     } else if (underlineStyle != QTextCharFormat::NoUnderline) {
-        QLineF underLine(line.x1(), underlinePos, line.x2(), underlinePos);
+        QLineF underLine(pos.x(), underlinePos, pos.x() + qFloor(width), underlinePos);
 
         QColor uc = charFormat.underlineColor();
         if (uc.isValid())
@@ -5089,26 +5087,6 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
         painter->setPen(pen);
         painter->drawLine(underLine);
     }
-
-    pen.setStyle(Qt::SolidLine);
-    pen.setColor(oldPen.color());
-
-    if (flags & QTextItem::StrikeOut) {
-        QLineF strikeOutLine = line;
-        strikeOutLine.translate(0., - fe->ascent().toReal() / 3.);
-        painter->setPen(pen);
-        painter->drawLine(strikeOutLine);
-    }
-
-    if (flags & QTextItem::Overline) {
-        QLineF overLine = line;
-        overLine.translate(0., - fe->ascent().toReal());
-        painter->setPen(pen);
-        painter->drawLine(overLine);
-    }
-
-    painter->setPen(oldPen);
-    painter->setBrush(oldBrush);
 }
 
 void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
index 088ba44..23fd2ce 100644 (file)
@@ -1149,6 +1149,21 @@ void QPainterPath::addText(const QPointF &point, const QFont &f, const QString &
         engine->stringToCMap(text.unicode(), nglyphs, &glyphs, &nglyphs, shaperflags);
         engine->addOutlineToPath(point.x(), point.y(), glyphs, this);
     }
+
+    const QFontMetricsF fontmetrics(f);
+    const qreal linewidth = fontmetrics.lineWidth();
+    const qreal textwidth = (fontmetrics.width('x') * text.size());
+#if 0
+    if (f.underline()) {
+        addRect(point.x(), point.y() + fontmetrics.underlinePos(), textwidth, linewidth);
+    }
+#endif
+    if (f.overline()) {
+        addRect(point.x(), point.y() - fontmetrics.overlinePos(), textwidth, linewidth);
+    }
+    if (f.strikeOut()) {
+        addRect(point.x(), point.y() - fontmetrics.strikeOutPos(), textwidth, linewidth);
+    }
 }
 
 /*!
index b98489f..d87468f 100644 (file)
@@ -2180,24 +2180,7 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR
                 QPainterPath path;
                 path.setFillRule(Qt::WindingFill);
 
-                if (gf.glyphs.numGlyphs)
-                    gf.fontEngine->addOutlineToPath(pos.x(), pos.y(), gf.glyphs, &path);
-                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);
-                    }
-                }
+                path.addText(pos, f, gf.text());
 
                 p->save();
                 //Currently QPen with a Qt::NoPen style still returns a default