diff options
author | Jens Bache-Wiig <jbache@trolltech.com> | 2010-09-20 18:27:00 +0200 |
---|---|---|
committer | Jens Bache-Wiig <jbache@trolltech.com> | 2010-09-20 18:27:00 +0200 |
commit | 645b4b7ad0e69ae9063f56c33108209349317c08 (patch) | |
tree | c5740b9cb9d1c16d14251aff5b2172174d2a4565 /src | |
parent | fd0c78bb37e36dbdabe298e42c4931ea40fde1f3 (diff) |
Add text align and baseline
Diffstat (limited to 'src')
-rw-r--r-- | src/context2d.cpp | 119 | ||||
-rw-r--r-- | src/context2d.h | 14 |
2 files changed, 124 insertions, 9 deletions
diff --git a/src/context2d.cpp b/src/context2d.cpp index 7d275fa..726fa4e 100644 --- a/src/context2d.cpp +++ b/src/context2d.cpp @@ -43,6 +43,7 @@ static const double Q_PI = 3.14159265358979323846; // pi #include <QGraphicsItem> +#include <QApplication> #include <QStyleOptionGraphicsItem> #include <QGraphicsDropShadowEffect> @@ -477,17 +478,78 @@ void Context2D::setShadowColor(const QString &str) QString Context2D::textBaseline() { switch(m_state.textBaseline) { + case Context2D::Alphabetic: + return QLatin1String("alphabetic"); + case Context2D::Hanging: + return QLatin1String("hanging"); + case Context2D::Bottom: + return QLatin1String("bottom"); + case Context2D::Top: + return QLatin1String("top"); + case Context2D::Middle: + return QLatin1String("middle"); default: - return "middle"; + Q_ASSERT("invalid value"); + return QLatin1String("start"); } } -void Context2D::setTextBaseline(const QString &) +void Context2D::setTextBaseline(const QString &baseline) +{ + if (baseline==QLatin1String("alphabetic")) + m_state.textBaseline = Context2D::Alphabetic; + else if (baseline == QLatin1String("hanging")) + m_state.textBaseline = Context2D::Hanging; + else if (baseline == QLatin1String("top")) + m_state.textBaseline = Context2D::Top; + else if (baseline == QLatin1String("bottom")) + m_state.textBaseline = Context2D::Bottom; + else if (baseline == QLatin1String("middle")) + m_state.textBaseline = Context2D::Middle; + else { + m_state.textBaseline = Context2D::Alphabetic; + qWarning() << ("Context2D: invalid baseline:" + baseline); + } + m_state.flags |= DirtyTextBaseline; +} + +QString Context2D::textAlign() { - qDebug("Baseline not implemented"); + switch(m_state.textAlign) { + case Context2D::Left: + return QLatin1String("left"); + case Context2D::Right: + return QLatin1String("right"); + case Context2D::Center: + return QLatin1String("center"); + case Context2D::Start: + return QLatin1String("start"); + case Context2D::End: + return QLatin1String("end"); + default: + Q_ASSERT("invalid value"); + qWarning() << ("Context2D::invalid textAlign"); + return QLatin1String("start"); + } +} +void Context2D::setTextAlign(const QString &baseline) +{ + if (baseline==QLatin1String("start")) + m_state.textAlign = Context2D::Start; + else if (baseline == QLatin1String("end")) + m_state.textAlign = Context2D::End; + else if (baseline == QLatin1String("left")) + m_state.textAlign = Context2D::Left; + else if (baseline == QLatin1String("right")) + m_state.textAlign = Context2D::Right; + else if (baseline == QLatin1String("center")) + m_state.textAlign = Context2D::Center; + else { + m_state.textAlign= Context2D::Start; + qWarning("Context2D: invalid text align"); + } // ### alphabetic, ideographic, hanging - m_state.flags |= DirtyTextBaseline; } @@ -563,9 +625,46 @@ void Context2D::fillRect(qreal x, qreal y, qreal w, qreal h) scheduleChange(); } +int Context2D::baseLineOffset(Context2D::TextBaseLine value, const QFontMetrics &metrics) +{ + int offset; + switch(value) { + case Context2D::Top: + break; + case Context2D::Alphabetic: + case Context2D::Middle: + case Context2D::Hanging: + offset = metrics.ascent(); + break; + case Context2D::Bottom: + offset = metrics.height(); + break; + } + return offset; +} + +int Context2D::textAlignOffset(Context2D::TextAlign value, const QFontMetrics &metrics, const QString &text) +{ + int offset; + if (value == Context2D::Start) + value = qApp->layoutDirection() == Qt::LeftToRight ? Context2D::Left : Context2D::Right; + else if (value == Context2D::End) + value = qApp->layoutDirection() == Qt::LeftToRight ? Context2D::Right: Context2D::Left; + switch(value) { + case Context2D::Center: + offset = metrics.width(text)/2; + break; + case Context2D::Right: + offset = metrics.width(text); + case Context2D::Left: + default: + break; + } + return offset; +} + void Context2D::fillText(const QString &text, qreal x, qreal y) { - qDebug("here"); beginPainting(); m_painter.save(); m_painter.setPen(QPen(m_state.fillStyle, m_state.lineWidth)); @@ -573,8 +672,10 @@ void Context2D::fillText(const QString &text, qreal x, qreal y) QFont font; font.setBold(true); m_painter.setFont(m_state.font); + int yoffset = baseLineOffset(m_state.textBaseline, m_painter.fontMetrics()); + int xoffset = textAlignOffset(m_state.textAlign, m_painter.fontMetrics(), text); QTextOption opt; // Adjust baseLine etc - m_painter.drawText(QRectF(x, y, m_pixmap.width(), m_painter.fontMetrics().height()), text, opt); + m_painter.drawText(QRectF(x-xoffset, y-yoffset, m_pixmap.width(), m_painter.fontMetrics().height()), text, opt); m_painter.restore(); scheduleChange(); } @@ -589,7 +690,11 @@ void Context2D::strokeText(const QString &text, qreal x, qreal y) QPainterPath textPath; QFont font = m_state.font; font.setStyleStrategy(QFont::ForceOutline); - textPath.addText(x, y, font, text); + m_painter.setFont(font); + const QFontMetrics &metrics = m_painter.fontMetrics(); + int yoffset = baseLineOffset(m_state.textBaseline, metrics); + int xoffset = textAlignOffset(m_state.textAlign, metrics, text); + textPath.addText(x-xoffset, y-yoffset+metrics.ascent(), font, text); m_painter.strokePath(textPath, QPen(m_state.fillStyle, m_state.lineWidth)); m_painter.restore(); scheduleChange(); diff --git a/src/context2d.h b/src/context2d.h index 46b0644..57cf922 100644 --- a/src/context2d.h +++ b/src/context2d.h @@ -124,6 +124,10 @@ class Context2D : public QObject // fonts Q_PROPERTY(QString font READ font WRITE setFont) Q_PROPERTY(QString textBaseline READ textBaseline WRITE setTextBaseline) + Q_PROPERTY(QString textAlign READ textAlign WRITE setTextAlign) + + enum TextBaseLine { Alphabetic=0, Top, Middle, Bottom, Hanging}; + enum TextAlign { Start=0, End, Left, Right, Center}; public: Context2D(QObject *parent = 0); @@ -165,6 +169,8 @@ public: QString font(); void setTextBaseline(const QString &font); QString textBaseline(); + void setTextAlign(const QString &font); + QString textAlign(); // shadows qreal shadowOffsetX() const; // (default 0) @@ -285,10 +291,14 @@ private: QColor shadowColor; QPainter::CompositionMode globalCompositeOperation; QFont font; - int textAlign; - int textBaseline; + Context2D::TextAlign textAlign; + Context2D::TextBaseLine textBaseline; int flags; }; + + int baseLineOffset(Context2D::TextBaseLine value, const QFontMetrics &metrics); + int textAlignOffset(Context2D::TextAlign value, const QFontMetrics &metrics, const QString &string); + State m_state; QStack<State> m_stateStack; QPixmap m_pixmap; |