summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>2016-03-30 13:15:02 +0200
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>2016-04-19 09:32:10 +0000
commit7094466f7d0c2176eb3080021a4ea5d220555df9 (patch)
treec1f633f1f3ce805a9af78c8e31e5f70ef6d29694 /src/gui
parentb3fcaea5f2b97d3f562add97aee48cbb469c875a (diff)
Interpret fixed CSS line-height as minimum rather than absolute
The QTextBlockFormat::FixedHeight overrides the line height regardless of its calculated height. If the line contains objects or text which is higher than the specified line height, using FixedHeight will cause them to overlap with the previous line. This is not what happens in normal web browsers. The expected behavior is that the line height given in CSS is the minimum height, but that we still reserve space needed to display everything without overlaps. To make it possible for people to retain the old behavior, we introduce the -qt-line-height-type property, which allows them to override the default. This also fixes output from toHtml() to use the new property rather than set the minimum height of the paragraph or the "line-spacing" property, which does not exist in either CSS nor in Qt. [ChangeLog][QtGui][Important Behavior Changes] When line height is specified in pixels, this is now interpreted as the minimum line height rather than an absolute line height to avoid overlaps. To get the old behavior, use the -qt-line-height-type property in CSS and set it to "fixed". Task-number: QTBUG-51962 Change-Id: Ic2dde649b69209672170dad4c2de1e1c432a1078 Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/text/qcssparser.cpp1
-rw-r--r--src/gui/text/qcssparser_p.h1
-rw-r--r--src/gui/text/qtextdocument.cpp17
-rw-r--r--src/gui/text/qtexthtmlparser.cpp44
-rw-r--r--src/gui/text/qtexthtmlparser_p.h1
5 files changed, 47 insertions, 17 deletions
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp
index b9e05e726e..53d4e3fa36 100644
--- a/src/gui/text/qcssparser.cpp
+++ b/src/gui/text/qcssparser.cpp
@@ -67,6 +67,7 @@ struct QCssKnownValue
static const QCssKnownValue properties[NumProperties - 1] = {
{ "-qt-background-role", QtBackgroundRole },
{ "-qt-block-indent", QtBlockIndent },
+ { "-qt-line-height-type", QtLineHeightType },
{ "-qt-list-indent", QtListIndent },
{ "-qt-list-number-prefix", QtListNumberPrefix },
{ "-qt-list-number-suffix", QtListNumberSuffix },
diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h
index b7692d32aa..4da7b62dba 100644
--- a/src/gui/text/qcssparser_p.h
+++ b/src/gui/text/qcssparser_p.h
@@ -189,6 +189,7 @@ enum Property {
QtListNumberPrefix,
QtListNumberSuffix,
LineHeight,
+ QtLineHeightType,
NumProperties
};
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index f50f771c07..febd5da488 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -2763,26 +2763,25 @@ void QTextHtmlExporter::emitBlockAttributes(const QTextBlock &block)
}
if (format.lineHeightType() != QTextBlockFormat::SingleHeight) {
+ html += QLatin1String(" line-height:")
+ + QString::number(format.lineHeight());
switch (format.lineHeightType()) {
case QTextBlockFormat::ProportionalHeight:
+ html += QLatin1String("%;");
+ break;
case QTextBlockFormat::FixedHeight:
- html += QLatin1String(" line-height:");
+ html += QLatin1String("; -qt-line-height-type: fixed;");
break;
case QTextBlockFormat::MinimumHeight:
- html += QLatin1String(" min-height:");
+ html += QLatin1String("px;");
break;
case QTextBlockFormat::LineDistanceHeight:
- html += QLatin1String(" line-spacing:");
+ html += QLatin1String("; -qt-line-height-type: line-distance;");
break;
- case QTextBlockFormat::SingleHeight:
default:
+ html += QLatin1String(";");
break; // Should never reach here
}
- html += QString::number(format.lineHeight());
- if (format.lineHeightType() == QTextBlockFormat::ProportionalHeight)
- html += QLatin1String("%;");
- else
- html += QLatin1String("px;");
}
emitPageBreakPolicy(format.pageBreakPolicy());
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index d8e12f7024..576ff7d935 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -492,7 +492,7 @@ static QString quoteNewline(const QString &s)
QTextHtmlParserNode::QTextHtmlParserNode()
: parent(0), id(Html_unknown),
- cssFloat(QTextFrameFormat::InFlow), hasOwnListStyle(false),
+ cssFloat(QTextFrameFormat::InFlow), hasOwnListStyle(false), hasOwnLineHeightType(false),
hasCssListIndent(false), isEmptyParagraph(false), isTextFrame(false), isRootFrame(false),
displayMode(QTextHtmlElement::DisplayInline), hasHref(false),
listStyle(QTextListFormat::ListStyleUndefined), imageWidth(-1), imageHeight(-1), tableBorder(0),
@@ -1198,20 +1198,48 @@ void QTextHtmlParserNode::applyCssDeclarations(const QVector<QCss::Declaration>
case QCss::QtBlockIndent:
blockFormat.setIndent(decl.d->values.first().variant.toInt());
break;
- case QCss::LineHeight: {
+ case QCss::QtLineHeightType: {
+ QString lineHeightTypeName = decl.d->values.first().variant.toString();
+ QTextBlockFormat::LineHeightTypes lineHeightType;
+ if (lineHeightTypeName.compare(QLatin1String("proportional"), Qt::CaseInsensitive) == 0)
+ lineHeightType = QTextBlockFormat::ProportionalHeight;
+ else if (lineHeightTypeName.compare(QLatin1String("fixed"), Qt::CaseInsensitive) == 0)
+ lineHeightType = QTextBlockFormat::FixedHeight;
+ else if (lineHeightTypeName.compare(QLatin1String("minimum"), Qt::CaseInsensitive) == 0)
+ lineHeightType = QTextBlockFormat::MinimumHeight;
+ else if (lineHeightTypeName.compare(QLatin1String("line-distance"), Qt::CaseInsensitive) == 0)
+ lineHeightType = QTextBlockFormat::LineDistanceHeight;
+ else
+ lineHeightType = QTextBlockFormat::SingleHeight;
+
+ blockFormat.setProperty(QTextBlockFormat::LineHeightType, lineHeightType);
+ hasOwnLineHeightType = true;
+ }
+ break;
+ case QCss::LineHeight: {
qreal lineHeight;
+ QTextBlockFormat::LineHeightTypes lineHeightType;
if (decl.realValue(&lineHeight, "px")) {
- blockFormat.setLineHeight(lineHeight, QTextBlockFormat::FixedHeight);
+ lineHeightType = QTextBlockFormat::MinimumHeight;
} else {
bool ok;
QString value = decl.d->values.first().toString();
lineHeight = value.toDouble(&ok);
- if (ok)
- blockFormat.setLineHeight(lineHeight, QTextBlockFormat::ProportionalHeight);
- else
- blockFormat.setLineHeight(0, QTextBlockFormat::SingleHeight);
+ if (ok) {
+ lineHeightType = QTextBlockFormat::ProportionalHeight;
+ } else {
+ lineHeight = 0.0;
+ lineHeightType = QTextBlockFormat::SingleHeight;
+ }
}
- break; }
+
+ // Only override line height type if specified in same node
+ if (hasOwnLineHeightType)
+ lineHeightType = QTextBlockFormat::LineHeightTypes(blockFormat.lineHeightType());
+
+ blockFormat.setLineHeight(lineHeight, lineHeightType);
+ break;
+ }
case QCss::TextIndent: {
qreal indent = 0;
if (decl.realValue(&indent, "px"))
diff --git a/src/gui/text/qtexthtmlparser_p.h b/src/gui/text/qtexthtmlparser_p.h
index 8e5a90be0b..4c0dd967f9 100644
--- a/src/gui/text/qtexthtmlparser_p.h
+++ b/src/gui/text/qtexthtmlparser_p.h
@@ -171,6 +171,7 @@ struct QTextHtmlParserNode {
QTextBlockFormat blockFormat;
uint cssFloat : 2;
uint hasOwnListStyle : 1;
+ uint hasOwnLineHeightType : 1;
uint hasCssListIndent : 1;
uint isEmptyParagraph : 1;
uint isTextFrame : 1;