summaryrefslogtreecommitdiffstats
path: root/src/gui/text/qtextengine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/text/qtextengine.cpp')
-rw-r--r--src/gui/text/qtextengine.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index dae02def07..3d58d91169 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1174,6 +1174,7 @@ static void init(QTextEngine *e)
e->cacheGlyphs = false;
e->forceJustification = false;
e->visualMovement = false;
+ e->delayDecorations = false;
e->layoutData = 0;
@@ -2913,6 +2914,104 @@ int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation
return pos;
}
+void QTextEngine::addItemDecoration(QPainter *painter, const QLineF &line, ItemDecorationList *decorationList)
+{
+ if (delayDecorations) {
+ decorationList->append(ItemDecoration(line.x1(), line.x2(), line.y1(), painter->pen()));
+ } else {
+ painter->drawLine(line);
+ }
+}
+
+void QTextEngine::addUnderline(QPainter *painter, const QLineF &line)
+{
+ // qDebug() << "Adding underline:" << line;
+ addItemDecoration(painter, line, &underlineList);
+}
+
+void QTextEngine::addStrikeOut(QPainter *painter, const QLineF &line)
+{
+ addItemDecoration(painter, line, &strikeOutList);
+}
+
+void QTextEngine::addOverline(QPainter *painter, const QLineF &line)
+{
+ addItemDecoration(painter, line, &overlineList);
+}
+
+void QTextEngine::drawItemDecorationList(QPainter *painter, const ItemDecorationList &decorationList)
+{
+ // qDebug() << "Drawing" << decorationList.size() << "decorations";
+ if (decorationList.isEmpty())
+ return;
+
+ foreach (const ItemDecoration decoration, decorationList) {
+ painter->setPen(decoration.pen);
+ QLineF line(decoration.x1, decoration.y, decoration.x2, decoration.y);
+ painter->drawLine(line);
+ }
+}
+
+void QTextEngine::drawDecorations(QPainter *painter)
+{
+ QPen oldPen = painter->pen();
+
+ adjustUnderlines();
+ drawItemDecorationList(painter, underlineList);
+ drawItemDecorationList(painter, strikeOutList);
+ drawItemDecorationList(painter, overlineList);
+
+ painter->setPen(oldPen);
+ clearDecorations();
+}
+
+void QTextEngine::clearDecorations()
+{
+ underlineList.clear();
+ strikeOutList.clear();
+ overlineList.clear();
+}
+
+void QTextEngine::adjustUnderlines()
+{
+ // qDebug() << __PRETTY_FUNCTION__ << underlineList.count() << "underlines";
+ if (underlineList.isEmpty())
+ return;
+
+ ItemDecorationList::iterator start = underlineList.begin();
+ ItemDecorationList::iterator end = underlineList.end();
+ ItemDecorationList::iterator it = start;
+ qreal underlinePos = start->y;
+ qreal penWidth = start->pen.widthF();
+ qreal lastLineEnd = start->x1;
+
+ while (it != end) {
+ if (qFuzzyCompare(lastLineEnd, it->x1)) { // no gap between underlines
+ underlinePos = qMax(underlinePos, it->y);
+ penWidth = qMax(penWidth, it->pen.widthF());
+ } else { // gap between this and the last underline
+ adjustUnderlines(start, it, underlinePos, penWidth);
+ start = it;
+ underlinePos = start->y;
+ penWidth = start->pen.widthF();
+ }
+ lastLineEnd = it->x2;
+ ++it;
+ }
+
+ adjustUnderlines(start, end, underlinePos, penWidth);
+}
+
+void QTextEngine::adjustUnderlines(ItemDecorationList::iterator start,
+ ItemDecorationList::iterator end,
+ qreal underlinePos, qreal penWidth)
+{
+ for (ItemDecorationList::iterator it = start; it != end; ++it) {
+ it->y = underlinePos;
+ it->pen.setWidth(penWidth);
+ }
+}
+
QStackTextEngine::QStackTextEngine(const QString &string, const QFont &f)
: QTextEngine(string, f),
_layoutData(string, _memory, MemSize)