summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJordi Pujol Foyo <jordi@vikingsoftware.com>2020-05-08 15:23:21 +0200
committerJordi Pujol Foyo <jordi@vikingsoftware.com>2020-08-26 16:40:10 +0200
commit560117351cd1e032c30e2691a2e933e3ebb84edd (patch)
tree9134bc2119f5ae0089642aeff842a4c67894a2bd
parentcba2d0443411b937586f259059e7f14c1cf5b512 (diff)
Allow arbitrary baseline shift in QTextCharacterFormat
Added 6 new methods in QTextFormat and QTextDocument to allow setting/getting specific % positioning for baseline and super/ subscript. Modified QTextLayout to honor those new settings. [ChangeLog][QtGui][QTextLayout,QTextFormat,QTextDocument] Allow text layout modification based on baseline offset and super/subscript % height positioning Fixes: QTBUG-18260 Change-Id: I0796f18224aac8df6baf8359c35022fd98fe64ef Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
-rw-r--r--src/gui/text/qtextdocument.cpp87
-rw-r--r--src/gui/text/qtextdocument.h9
-rw-r--r--src/gui/text/qtextformat.cpp58
-rw-r--r--src/gui/text/qtextformat.h18
-rw-r--r--src/gui/text/qtextformat_p.h7
-rw-r--r--src/gui/text/qtextlayout.cpp20
6 files changed, 194 insertions, 5 deletions
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index b95f55451a..f066853792 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -1733,6 +1733,93 @@ QFont QTextDocument::defaultFont() const
}
/*!
+ \fn void QTextDocument::setSuperScriptBaseline(qreal baseline)
+ \since 6.0
+
+ Sets the default superscript's base line as a % of font height to use in the document layout.
+ The default value is 50% (1/2 of height)
+
+ \sa superScriptBaseline(), setSubScriptBaseline(), subScriptBaseline(), setBaselineOffset(), baselineOffset()
+*/
+void QTextDocument::setSuperScriptBaseline(qreal baseline)
+{
+ Q_D(QTextDocument);
+ d->formats.setSuperScriptBaseline(baseline);
+}
+
+/*!
+ \fn qreal QTextDocument::superScriptBaseline() const
+ \since 6.0
+
+ Returns the superscript's base line as a % of font height used in the document layout.
+
+ \sa setSuperScriptBaseline(), setSubScriptBaseline(), subScriptBaseline(), setBaselineOffset(), baselineOffset()
+*/
+qreal QTextDocument::superScriptBaseline() const
+{
+ Q_D(const QTextDocument);
+ return d->formats.defaultTextFormat().superScriptBaseline();
+}
+
+/*!
+ \fn void QTextDocument::setSubScriptBaseline(qreal baseline)
+ \since 6.0
+
+ Sets the default subscript's base line as a % of font height to use in the document layout.
+ The default value is 16.67% (1/6 of height)
+
+ \sa subScriptBaseline(), setSuperScriptBaseline(), superScriptBaseline(), setBaselineOffset(), baselineOffset()
+*/
+void QTextDocument::setSubScriptBaseline(qreal baseline)
+{
+ Q_D(QTextDocument);
+ d->formats.setSubScriptBaseline(baseline);
+}
+
+/*!
+ \fn qreal QTextDocument::subScriptBaseline() const
+ \since 6.0
+
+ Returns the superscript's base line as a % of font height used in the document layout.
+
+ \sa setSubScriptBaseline(), setSuperScriptBaseline(), superScriptBaseline(), setBaselineOffset(), baselineOffset()
+*/
+qreal QTextDocument::subScriptBaseline() const
+{
+ Q_D(const QTextDocument);
+ return d->formats.defaultTextFormat().subScriptBaseline();
+}
+
+/*!
+ \fn void QTextDocument::setBaselineOffset(qreal baseline)
+ \since 6.0
+
+ Sets the baseline (in % of height) to use in the document layout. The default value is 0.
+ A positive value moves up the text, by the corresponding %; a negative value moves it down.
+
+ \sa baselineOffset(), setSubScriptBaseline(), subScriptBaseline(), setSuperScriptBaseline(), superScriptBaseline()
+*/
+void QTextDocument::setBaselineOffset(qreal baseline)
+{
+ Q_D(QTextDocument);
+ d->formats.setBaselineOffset(baseline);
+}
+
+/*!
+ \fn qreal QTextDocument::baselineOffset() const
+ \since 6.0
+
+ Returns the the baseline offset in % used in the document layout.
+
+ \sa setBaselineOffset(), setSubScriptBaseline(), subScriptBaseline(), setSuperScriptBaseline(), superScriptBaseline()
+*/
+qreal QTextDocument::baselineOffset() const
+{
+ Q_D(const QTextDocument);
+ return d->formats.defaultTextFormat().baselineOffset();
+}
+
+/*!
\fn void QTextDocument::modificationChanged(bool changed)
This signal is emitted whenever the content of the document
diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h
index 5de81e683c..0470ad52e9 100644
--- a/src/gui/text/qtextdocument.h
+++ b/src/gui/text/qtextdocument.h
@@ -208,6 +208,15 @@ public:
void setDefaultFont(const QFont &font);
QFont defaultFont() const;
+ void setSuperScriptBaseline(qreal baseline);
+ qreal superScriptBaseline() const;
+
+ void setSubScriptBaseline(qreal baseline);
+ qreal subScriptBaseline() const;
+
+ void setBaselineOffset(qreal baseline);
+ qreal baselineOffset() const;
+
int pageCount() const;
bool isModified() const;
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index 14b564fc73..faf1765219 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -635,6 +635,10 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt)
\value TextOutline
\value TextUnderlineStyle
\value TextToolTip Specifies the (optional) tool tip to be displayed for a fragment of text.
+ \value TextSuperScriptBaseline Specifies the baseline (in % of height) of superscript texts.
+ \value TextSubScriptBaseline Specifies the baseline (in % of height) of subscript texts.
+ \value TextBaselineOffset Specifies the baseline (in % of height) of text. A positive value moves up the text,
+ by the corresponding %; a negative value moves it down.
\value IsAnchor
\value AnchorHref
@@ -1795,6 +1799,60 @@ void QTextCharFormat::setUnderlineStyle(UnderlineStyle style)
\sa foreground(), setForeground(), clearBackground()
*/
+/*!
+ \fn void QTextCharFormat::setSuperScriptBaseline(qreal baseline)
+ \since 6.0
+
+ Sets the superscript's base line as a % of font height. The default value is 50% (1/2 of height)
+
+ \sa superScriptBaseline(), setSubScriptBaseline(), subScriptBaseline(), setBaselineOffset(), baselineOffset()
+*/
+
+/*!
+ \fn qreal QTextCharFormat::superScriptBaseline() const
+ \since 6.0
+
+ Returns the superscript's base line as a % of font height.
+
+ \sa setSuperScriptBaseline(), setSubScriptBaseline(), subScriptBaseline(), setBaselineOffset(), baselineOffset()
+*/
+
+/*!
+ \fn void QTextCharFormat::setSubScriptBaseline(qreal baseline)
+ \since 6.0
+
+ Sets the subscript's base line as a % of font height. The default value is 16.67% (1/6 of height)
+
+ \sa subScriptBaseline(), setSuperScriptBaseline(), superScriptBaseline(), setBaselineOffset(), baselineOffset()
+*/
+
+/*!
+ \fn qreal QTextCharFormat::subScriptBaseline() const
+ \since 6.0
+
+ Returns the subscript's base line as a % of font height.
+
+ \sa setSubScriptBaseline(), setSuperScriptBaseline(), superScriptBaseline(), setBaselineOffset(), baselineOffset()
+*/
+
+/*!
+ \fn void QTextCharFormat::setBaselineOffset(qreal baseline)
+ \since 6.0
+
+ Sets the baseline (in % of height) of text. A positive value moves up the text, by the corresponding %;
+ a negative value moves it down. The default value is 0.
+
+ \sa baselineOffset(), setSubScriptBaseline(), subScriptBaseline(), setSuperScriptBaseline(), superScriptBaseline()
+*/
+
+/*!
+ \fn qreal QTextCharFormat::baselineOffset() const
+ \since 6.0
+
+ Returns the the baseline offset in %.
+
+ \sa setBaselineOffset(), setSubScriptBaseline(), subScriptBaseline(), setSuperScriptBaseline(), superScriptBaseline()
+*/
/*!
\fn void QTextCharFormat::setAnchor(bool anchor)
diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h
index e12f033596..9d422786f0 100644
--- a/src/gui/text/qtextformat.h
+++ b/src/gui/text/qtextformat.h
@@ -213,6 +213,9 @@ public:
TextOutline = 0x2022,
TextUnderlineStyle = 0x2023,
TextToolTip = 0x2024,
+ TextSuperScriptBaseline = 0x2025,
+ TextSubScriptBaseline = 0x2026,
+ TextBaselineOffset = 0x2027,
IsAnchor = 0x2030,
AnchorHref = 0x2031,
@@ -570,6 +573,21 @@ public:
inline QString toolTip() const
{ return stringProperty(TextToolTip); }
+ inline void setSuperScriptBaseline(qreal baseline)
+ { setProperty(TextSuperScriptBaseline, baseline); }
+ inline qreal superScriptBaseline() const
+ { return hasProperty(TextSuperScriptBaseline) ? doubleProperty(TextSuperScriptBaseline) : 50.0; }
+
+ inline void setSubScriptBaseline(qreal baseline)
+ { setProperty(TextSubScriptBaseline, baseline); }
+ inline qreal subScriptBaseline() const
+ { return hasProperty(TextSubScriptBaseline) ? doubleProperty(TextSubScriptBaseline) : 100.0 / 6.0; }
+
+ inline void setBaselineOffset(qreal baseline)
+ { setProperty(TextBaselineOffset, baseline); }
+ inline qreal baselineOffset() const
+ { return hasProperty(TextBaselineOffset) ? doubleProperty(TextBaselineOffset) : 0.0; }
+
inline void setAnchor(bool anchor)
{ setProperty(IsAnchor, anchor); }
inline bool isAnchor() const
diff --git a/src/gui/text/qtextformat_p.h b/src/gui/text/qtextformat_p.h
index 862ef18e65..13815d06b3 100644
--- a/src/gui/text/qtextformat_p.h
+++ b/src/gui/text/qtextformat_p.h
@@ -101,8 +101,15 @@ public:
inline QFont defaultFont() const { return defaultFnt; }
void setDefaultFont(const QFont &f);
+ inline void setSuperScriptBaseline(qreal baseline) { defaultFormat.setSuperScriptBaseline(baseline); }
+ inline void setSubScriptBaseline(qreal baseline) { defaultFormat.setSubScriptBaseline(baseline); }
+ inline void setBaselineOffset(qreal baseline) { defaultFormat.setBaselineOffset(baseline); }
+
+ inline QTextCharFormat defaultTextFormat() const { return defaultFormat; }
+
private:
QFont defaultFnt;
+ QTextCharFormat defaultFormat;
Q_DISABLE_COPY_MOVE(QTextFormatCollection)
};
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index ec4270ea9c..cd064364d5 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -2511,6 +2511,8 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR
const QFixed y = QFixed::fromReal(pos.y()) + line.y + lineBase;
+ const QTextFormatCollection *formatCollection = eng->formatCollection();
+
bool suppressColors = (eng->option.flags() & QTextOption::SuppressColors);
while (!iterator.atEnd()) {
QScriptItem &si = iterator.next();
@@ -2525,10 +2527,12 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR
QFixed itemBaseLine = y;
QFont f = eng->font(si);
QTextCharFormat format;
+ if (formatCollection != nullptr)
+ format = formatCollection->defaultTextFormat();
+ if (eng->hasFormats() || selection || formatCollection) {
+ format.merge(eng->format(&si));
- if (eng->hasFormats() || selection) {
- format = eng->format(&si);
if (suppressColors) {
format.clearForeground();
format.clearBackground();
@@ -2540,14 +2544,20 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR
setPenAndDrawBackground(p, pen, format, QRectF(iterator.x.toReal(), (y - lineBase).toReal(),
iterator.itemWidth.toReal(), line.height().toReal()));
+ const qreal baseLineOffset = format.baselineOffset() / 100.0;
QTextCharFormat::VerticalAlignment valign = format.verticalAlignment();
- if (valign == QTextCharFormat::AlignSuperScript || valign == QTextCharFormat::AlignSubScript) {
+ if (valign == QTextCharFormat::AlignSuperScript
+ || valign == QTextCharFormat::AlignSubScript
+ || !qFuzzyIsNull(baseLineOffset))
+ {
QFontEngine *fe = f.d->engineForScript(si.analysis.script);
QFixed height = fe->ascent() + fe->descent();
+ itemBaseLine -= height * QFixed::fromReal(baseLineOffset);
+
if (valign == QTextCharFormat::AlignSubScript)
- itemBaseLine += height / 6;
+ itemBaseLine += height * QFixed::fromReal(format.subScriptBaseline() / 100.0);
else if (valign == QTextCharFormat::AlignSuperScript)
- itemBaseLine -= height / 2;
+ itemBaseLine -= height * QFixed::fromReal(format.superScriptBaseline() / 100.0);
}
}