diff options
author | Liang Qi <liang.qi@qt.io> | 2019-08-27 09:45:52 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2019-08-27 09:45:52 +0200 |
commit | 0f1f7fb97fd0dd572ad61a0ebaef68c2bba72e57 (patch) | |
tree | e1f3f1b58aa69904e6bc629e88ed68fca858f83a /src/gui/text | |
parent | e8c70fb07f01b492b721451c00496f860eb40be0 (diff) | |
parent | 5bb178c479a247720fbc3fbb7f06a32b725193ac (diff) |
Merge remote-tracking branch 'origin/dev' into 5.14
Conflicts:
src/widgets/kernel/qwidget.cpp
src/widgets/kernel/qwidget_p.h
src/widgets/kernel/qwidgetrepaintmanager.cpp
src/widgets/kernel/qwidgetwindow.cpp
tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
Change-Id: Ifae457d0427be8e2465e474b055722e11b3b1e5c
Diffstat (limited to 'src/gui/text')
-rw-r--r-- | src/gui/text/qcssparser.cpp | 13 | ||||
-rw-r--r-- | src/gui/text/qcssparser_p.h | 2 | ||||
-rw-r--r-- | src/gui/text/qfont.cpp | 8 | ||||
-rw-r--r-- | src/gui/text/qfont_p.h | 10 | ||||
-rw-r--r-- | src/gui/text/qfontmetrics.cpp | 8 | ||||
-rw-r--r-- | src/gui/text/qtextdocument.cpp | 80 | ||||
-rw-r--r-- | src/gui/text/qtextdocumentfragment.cpp | 26 | ||||
-rw-r--r-- | src/gui/text/qtexthtmlparser.cpp | 34 | ||||
-rw-r--r-- | src/gui/text/qtexthtmlparser_p.h | 8 |
9 files changed, 138 insertions, 51 deletions
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index 45f1ca596e..ce7c7610c1 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -92,6 +92,7 @@ static const QCssKnownValue properties[NumProperties - 1] = { { "border-bottom-right-radius", BorderBottomRightRadius }, { "border-bottom-style", BorderBottomStyle }, { "border-bottom-width", BorderBottomWidth }, + { "border-collapse", BorderCollapse }, { "border-color", BorderColor }, { "border-image", BorderImage }, { "border-left", BorderLeft }, @@ -611,11 +612,7 @@ bool ValueExtractor::extractBorder(int *borders, QBrush *colors, BorderStyle *st case BorderRightStyle: styles[RightEdge] = decl.styleValue(); break; case BorderStyles: decl.styleValues(styles); break; -#ifndef QT_OS_ANDROID_GCC_48_WORKAROUND case BorderTopLeftRadius: radii[0] = sizeValue(decl); break; -#else - case BorderTopLeftRadius: new(radii)QSize(sizeValue(decl)); break; -#endif case BorderTopRightRadius: radii[1] = sizeValue(decl); break; case BorderBottomLeftRadius: radii[2] = sizeValue(decl); break; case BorderBottomRightRadius: radii[3] = sizeValue(decl); break; @@ -1732,6 +1729,14 @@ void Declaration::borderImageValue(QString *image, int *cuts, *h = *v; } +bool Declaration::borderCollapseValue() const +{ + if (d->values.count() != 1) + return false; + else + return d->values.at(0).toString() == QLatin1String("collapse"); +} + QIcon Declaration::iconValue() const { if (d->parsed.isValid()) diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h index ddc46803ae..ab85e76cf3 100644 --- a/src/gui/text/qcssparser_p.h +++ b/src/gui/text/qcssparser_p.h @@ -122,6 +122,7 @@ enum Property { BorderRight, BorderTop, BorderBottom, + BorderCollapse, Padding, PaddingLeft, PaddingRight, @@ -478,6 +479,7 @@ struct Q_GUI_EXPORT Declaration QIcon iconValue() const; void borderImageValue(QString *image, int *cuts, TileMode *h, TileMode *v) const; + bool borderCollapseValue() const; }; QT_CSS_DECLARE_TYPEINFO(Declaration, Q_MOVABLE_TYPE) diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 97e73f0723..3c1a052f37 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -180,14 +180,14 @@ Q_GUI_EXPORT int qt_defaultDpi() } QFontPrivate::QFontPrivate() - : engineData(0), dpi(qt_defaultDpi()), screen(0), + : engineData(0), dpi(qt_defaultDpi()), underline(false), overline(false), strikeOut(false), kerning(true), capital(0), letterSpacingIsAbsolute(false), scFont(0) { } QFontPrivate::QFontPrivate(const QFontPrivate &other) - : request(other.request), engineData(0), dpi(other.dpi), screen(other.screen), + : request(other.request), engineData(0), dpi(other.dpi), underline(other.underline), overline(other.overline), strikeOut(other.strikeOut), kerning(other.kerning), capital(other.capital), letterSpacingIsAbsolute(other.letterSpacingIsAbsolute), @@ -581,11 +581,9 @@ QFont::QFont(const QFont &font, const QPaintDevice *pd) { Q_ASSERT(pd); const int dpi = pd->logicalDpiY(); - const int screen = 0; - if (font.d->dpi != dpi || font.d->screen != screen ) { + if (font.d->dpi != dpi) { d = new QFontPrivate(*font.d); d->dpi = dpi; - d->screen = screen; } else { d = font.d; } diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h index 466e19e9cc..adbb7a0121 100644 --- a/src/gui/text/qfont_p.h +++ b/src/gui/text/qfont_p.h @@ -185,7 +185,6 @@ public: QFontDef request; mutable QFontEngineData *engineData; int dpi; - int screen; uint underline : 1; uint overline : 1; @@ -230,19 +229,17 @@ public: void clear(); struct Key { - Key() : script(0), multi(0), screen(0) { } - Key(const QFontDef &d, uchar c, bool m = 0, uchar s = 0) - : def(d), script(c), multi(m), screen(s) { } + Key() : script(0), multi(0) { } + Key(const QFontDef &d, uchar c, bool m = 0) + : def(d), script(c), multi(m) { } QFontDef def; uchar script; uchar multi: 1; - uchar screen: 7; inline bool operator<(const Key &other) const { if (script != other.script) return script < other.script; - if (screen != other.screen) return screen < other.screen; if (multi != other.multi) return multi < other.multi; if (multi && def.fallBackFamilies.size() != other.def.fallBackFamilies.size()) return def.fallBackFamilies.size() < other.def.fallBackFamilies.size(); @@ -251,7 +248,6 @@ public: inline bool operator==(const Key &other) const { return script == other.script - && screen == other.screen && multi == other.multi && (!multi || def.fallBackFamilies == other.def.fallBackFamilies) && def == other.def; diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index c85dd4e1e3..d3e4f11e8c 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -185,11 +185,9 @@ QFontMetrics::QFontMetrics(const QFont &font, const QPaintDevice *paintdevice) #endif { const int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi(); - const int screen = 0; - if (font.d->dpi != dpi || font.d->screen != screen ) { + if (font.d->dpi != dpi) { d = new QFontPrivate(*font.d); d->dpi = dpi; - d->screen = screen; } else { d = font.d; } @@ -1178,11 +1176,9 @@ QFontMetricsF::QFontMetricsF(const QFont &font, const QPaintDevice *paintdevice) #endif { int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi(); - const int screen = 0; - if (font.d->dpi != dpi || font.d->screen != screen ) { + if (font.d->dpi != dpi) { d = new QFontPrivate(*font.d); d->dpi = dpi; - d->screen = screen; } else { d = font.d; } diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index dc34a96918..c80617f929 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -2593,51 +2593,43 @@ void QTextHtmlExporter::emitFloatStyle(QTextFrameFormat::Position pos, StyleMode html += QLatin1Char('\"'); } -void QTextHtmlExporter::emitBorderStyle(QTextFrameFormat::BorderStyle style) +static QLatin1String richtextBorderStyleToHtmlBorderStyle(QTextFrameFormat::BorderStyle style) { - Q_ASSERT(style <= QTextFrameFormat::BorderStyle_Outset); - - html += QLatin1String(" border-style:"); - switch (style) { case QTextFrameFormat::BorderStyle_None: - html += QLatin1String("none"); - break; + return QLatin1String("none"); case QTextFrameFormat::BorderStyle_Dotted: - html += QLatin1String("dotted"); - break; + return QLatin1String("dotted"); case QTextFrameFormat::BorderStyle_Dashed: - html += QLatin1String("dashed"); - break; + return QLatin1String("dashed"); case QTextFrameFormat::BorderStyle_Solid: - html += QLatin1String("solid"); - break; + return QLatin1String("solid"); case QTextFrameFormat::BorderStyle_Double: - html += QLatin1String("double"); - break; + return QLatin1String("double"); case QTextFrameFormat::BorderStyle_DotDash: - html += QLatin1String("dot-dash"); - break; + return QLatin1String("dot-dash"); case QTextFrameFormat::BorderStyle_DotDotDash: - html += QLatin1String("dot-dot-dash"); - break; + return QLatin1String("dot-dot-dash"); case QTextFrameFormat::BorderStyle_Groove: - html += QLatin1String("groove"); - break; + return QLatin1String("groove"); case QTextFrameFormat::BorderStyle_Ridge: - html += QLatin1String("ridge"); - break; + return QLatin1String("ridge"); case QTextFrameFormat::BorderStyle_Inset: - html += QLatin1String("inset"); - break; + return QLatin1String("inset"); case QTextFrameFormat::BorderStyle_Outset: - html += QLatin1String("outset"); - break; + return QLatin1String("outset"); default: - Q_ASSERT(false); - break; + Q_UNREACHABLE(); }; + return QLatin1String(""); +} + +void QTextHtmlExporter::emitBorderStyle(QTextFrameFormat::BorderStyle style) +{ + Q_ASSERT(style <= QTextFrameFormat::BorderStyle_Outset); + html += QLatin1String(" border-style:"); + html += richtextBorderStyleToHtmlBorderStyle(style); html += QLatin1Char(';'); } @@ -3204,6 +3196,33 @@ void QTextHtmlExporter::emitTable(const QTextTable *table) if (cellFormat.hasProperty(QTextFormat::TableCellBottomPadding)) styleString += QLatin1String(" padding-bottom:") + QString::number(cellFormat.bottomPadding()) + QLatin1Char(';'); + if (cellFormat.hasProperty(QTextFormat::TableCellTopBorder)) + styleString += QLatin1String(" border-top:") + QString::number(cellFormat.topBorder()) + QLatin1String("px;"); + if (cellFormat.hasProperty(QTextFormat::TableCellRightBorder)) + styleString += QLatin1String(" border-right:") + QString::number(cellFormat.rightBorder()) + QLatin1String("px;"); + if (cellFormat.hasProperty(QTextFormat::TableCellBottomBorder)) + styleString += QLatin1String(" border-bottom:") + QString::number(cellFormat.bottomBorder()) + QLatin1String("px;"); + if (cellFormat.hasProperty(QTextFormat::TableCellLeftBorder)) + styleString += QLatin1String(" border-left:") + QString::number(cellFormat.leftBorder()) + QLatin1String("px;"); + + if (cellFormat.hasProperty(QTextFormat::TableCellTopBorderBrush)) + styleString += QLatin1String(" border-top-color:") + cellFormat.topBorderBrush().color().name() + QLatin1Char(';'); + if (cellFormat.hasProperty(QTextFormat::TableCellRightBorderBrush)) + styleString += QLatin1String(" border-right-color:") + cellFormat.rightBorderBrush().color().name() + QLatin1Char(';'); + if (cellFormat.hasProperty(QTextFormat::TableCellBottomBorderBrush)) + styleString += QLatin1String(" border-bottom-color:") + cellFormat.bottomBorderBrush().color().name() + QLatin1Char(';'); + if (cellFormat.hasProperty(QTextFormat::TableCellLeftBorderBrush)) + styleString += QLatin1String(" border-left-color:") + cellFormat.leftBorderBrush().color().name() + QLatin1Char(';'); + + if (cellFormat.hasProperty(QTextFormat::TableCellTopBorderStyle)) + styleString += QLatin1String(" border-top-style:") + richtextBorderStyleToHtmlBorderStyle(cellFormat.topBorderStyle()) + QLatin1Char(';'); + if (cellFormat.hasProperty(QTextFormat::TableCellRightBorderStyle)) + styleString += QLatin1String(" border-right-style:") + richtextBorderStyleToHtmlBorderStyle(cellFormat.rightBorderStyle()) + QLatin1Char(';'); + if (cellFormat.hasProperty(QTextFormat::TableCellBottomBorderStyle)) + styleString += QLatin1String(" border-bottom-style:") + richtextBorderStyleToHtmlBorderStyle(cellFormat.bottomBorderStyle()) + QLatin1Char(';'); + if (cellFormat.hasProperty(QTextFormat::TableCellLeftBorderStyle)) + styleString += QLatin1String(" border-left-style:") + richtextBorderStyleToHtmlBorderStyle(cellFormat.leftBorderStyle()) + QLatin1Char(';'); + if (!styleString.isEmpty()) html += QLatin1String(" style=\"") + styleString + QLatin1Char('\"'); @@ -3310,6 +3329,9 @@ void QTextHtmlExporter::emitFrameStyle(const QTextFrameFormat &format, FrameType QString::number(format.leftMargin()), QString::number(format.rightMargin())); + if (format.property(QTextFormat::TableBorderCollapse).toBool()) + html += QLatin1String(" border-collapse:collapse;"); + if (html.length() == originalHtmlLength) // nothing emitted? html.chop(styleAttribute.size()); else diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp index 34698b2fb0..723e5c907c 100644 --- a/src/gui/text/qtextdocumentfragment.cpp +++ b/src/gui/text/qtextdocumentfragment.cpp @@ -986,6 +986,7 @@ QTextHtmlImporter::Table QTextHtmlImporter::scanTable(int tableNodeIdx) tableFmt.setColumns(table.columns); tableFmt.setColumnWidthConstraints(columnWidths); tableFmt.setHeaderRowCount(tableHeaderRowCount); + tableFmt.setBorderCollapse(node.borderCollapse); fmt = tableFmt; } @@ -1061,6 +1062,31 @@ QTextHtmlImporter::ProcessNodeResult QTextHtmlImporter::processBlockNode() fmt.setLeftPadding(leftPadding(currentNodeIdx)); if (rightPadding(currentNodeIdx) >= 0) fmt.setRightPadding(rightPadding(currentNodeIdx)); + if (tableCellBorder(currentNodeIdx, QCss::TopEdge) > 0) + fmt.setTopBorder(tableCellBorder(currentNodeIdx, QCss::TopEdge)); + if (tableCellBorder(currentNodeIdx, QCss::RightEdge) > 0) + fmt.setRightBorder(tableCellBorder(currentNodeIdx, QCss::RightEdge)); + if (tableCellBorder(currentNodeIdx, QCss::BottomEdge) > 0) + fmt.setBottomBorder(tableCellBorder(currentNodeIdx, QCss::BottomEdge)); + if (tableCellBorder(currentNodeIdx, QCss::LeftEdge) > 0) + fmt.setLeftBorder(tableCellBorder(currentNodeIdx, QCss::LeftEdge)); + if (tableCellBorderStyle(currentNodeIdx, QCss::TopEdge) != QTextFrameFormat::BorderStyle_None) + fmt.setTopBorderStyle(tableCellBorderStyle(currentNodeIdx, QCss::TopEdge)); + if (tableCellBorderStyle(currentNodeIdx, QCss::RightEdge) != QTextFrameFormat::BorderStyle_None) + fmt.setRightBorderStyle(tableCellBorderStyle(currentNodeIdx, QCss::RightEdge)); + if (tableCellBorderStyle(currentNodeIdx, QCss::BottomEdge) != QTextFrameFormat::BorderStyle_None) + fmt.setBottomBorderStyle(tableCellBorderStyle(currentNodeIdx, QCss::BottomEdge)); + if (tableCellBorderStyle(currentNodeIdx, QCss::LeftEdge) != QTextFrameFormat::BorderStyle_None) + fmt.setLeftBorderStyle(tableCellBorderStyle(currentNodeIdx, QCss::LeftEdge)); + if (tableCellBorderBrush(currentNodeIdx, QCss::TopEdge) != Qt::NoBrush) + fmt.setTopBorderBrush(tableCellBorderBrush(currentNodeIdx, QCss::TopEdge)); + if (tableCellBorderBrush(currentNodeIdx, QCss::RightEdge) != Qt::NoBrush) + fmt.setRightBorderBrush(tableCellBorderBrush(currentNodeIdx, QCss::RightEdge)); + if (tableCellBorderBrush(currentNodeIdx, QCss::BottomEdge) != Qt::NoBrush) + fmt.setBottomBorderBrush(tableCellBorderBrush(currentNodeIdx, QCss::BottomEdge)); + if (tableCellBorderBrush(currentNodeIdx, QCss::LeftEdge) != Qt::NoBrush) + fmt.setLeftBorderBrush(tableCellBorderBrush(currentNodeIdx, QCss::LeftEdge)); + cell.setFormat(fmt); cursor.setPosition(cell.firstPosition()); diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index 43b32e7e2c..5d37982a8b 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -491,12 +491,19 @@ QTextHtmlParserNode::QTextHtmlParserNode() listStyle(QTextListFormat::ListStyleUndefined), imageWidth(-1), imageHeight(-1), tableBorder(0), tableCellRowSpan(1), tableCellColSpan(1), tableCellSpacing(2), tableCellPadding(0), borderBrush(Qt::darkGray), borderStyle(QTextFrameFormat::BorderStyle_Outset), + borderCollapse(false), userState(-1), cssListIndent(0), wsm(WhiteSpaceModeUndefined) { margin[QTextHtmlParser::MarginLeft] = 0; margin[QTextHtmlParser::MarginRight] = 0; margin[QTextHtmlParser::MarginTop] = 0; margin[QTextHtmlParser::MarginBottom] = 0; + + for (int i = 0; i < 4; ++i) { + tableCellBorderStyle[i] = QTextFrameFormat::BorderStyle_None; + tableCellBorder[i] = 0; + tableCellBorderBrush[i] = Qt::NoBrush; + } } void QTextHtmlParser::dumpHtml() @@ -1169,6 +1176,25 @@ void QTextHtmlParserNode::applyCssDeclarations(const QVector<QCss::Declaration> QCss::ValueExtractor extractor(declarations); extractor.extractBox(margin, padding); + if (id == Html_td || id == Html_th) { + QCss::BorderStyle cssStyles[4]; + int cssBorder[4]; + QSize cssRadii[4]; // unused + for (int i = 0; i < 4; ++i) { + cssStyles[i] = QCss::BorderStyle_None; + cssBorder[i] = 0; + } + // this will parse (and cache) "border-width" as a list so the + // QCss::BorderWidth parsing below which expects a single value + // will not work as expected - which in this case does not matter + // because tableBorder is not relevant for cells. + extractor.extractBorder(cssBorder, tableCellBorderBrush, cssStyles, cssRadii); + for (int i = 0; i < 4; ++i) { + tableCellBorderStyle[i] = static_cast<QTextFrameFormat::BorderStyle>(cssStyles[i] - 1); + tableCellBorder[i] = static_cast<qreal>(cssBorder[i]); + } + } + for (int i = 0; i < declarations.count(); ++i) { const QCss::Declaration &decl = declarations.at(i); if (decl.d->values.isEmpty()) continue; @@ -1186,6 +1212,9 @@ void QTextHtmlParserNode::applyCssDeclarations(const QVector<QCss::Declaration> case QCss::BorderWidth: tableBorder = extractor.lengthValue(decl); break; + case QCss::BorderCollapse: + borderCollapse = decl.borderCollapseValue(); + break; case QCss::Color: charFormat.setForeground(decl.colorValue()); break; case QCss::Float: cssFloat = QTextFrameFormat::InFlow; @@ -1654,6 +1683,11 @@ void QTextHtmlParser::applyAttributes(const QStringList &attributes) if (!c.isValid()) qWarning("QTextHtmlParser::applyAttributes: Unknown color name '%s'",value.toLatin1().constData()); node->charFormat.setBackground(c); + } else if (key == QLatin1String("bordercolor")) { + QColor c; c.setNamedColor(value); + if (!c.isValid()) + qWarning("QTextHtmlParser::applyAttributes: Unknown color name '%s'",value.toLatin1().constData()); + node->borderBrush = c; } else if (key == QLatin1String("background")) { node->applyBackgroundImage(value, resourceProvider); } else if (key == QLatin1String("cellspacing")) { diff --git a/src/gui/text/qtexthtmlparser_p.h b/src/gui/text/qtexthtmlparser_p.h index ff5f5b4c35..31f558709f 100644 --- a/src/gui/text/qtexthtmlparser_p.h +++ b/src/gui/text/qtexthtmlparser_p.h @@ -195,8 +195,12 @@ struct QTextHtmlParserNode { int tableCellColSpan; qreal tableCellSpacing; qreal tableCellPadding; + qreal tableCellBorder[4]; + QBrush tableCellBorderBrush[4]; + QTextFrameFormat::BorderStyle tableCellBorderStyle[4]; QBrush borderBrush; QTextFrameFormat::BorderStyle borderStyle; + bool borderCollapse; int userState; int cssListIndent; @@ -290,6 +294,10 @@ public: inline int leftPadding(int i) const { return at(i).padding[MarginLeft]; } inline int rightPadding(int i) const { return at(i).padding[MarginRight]; } + inline qreal tableCellBorder(int i, int edge) const { return at(i).tableCellBorder[edge]; } + inline QTextFrameFormat::BorderStyle tableCellBorderStyle(int i, int edge) const { return at(i).tableCellBorderStyle[edge]; } + inline QBrush tableCellBorderBrush(int i, int edge) const { return at(i).tableCellBorderBrush[edge]; } + void dumpHtml(); void parse(const QString &text, const QTextDocument *resourceProvider); |