Support rendering CSS 'border' property for html table
We supported CSS 'border-width', 'border-style' and 'border-color' for HTML tables since 8a9bec35fb0c60a0e5990c1a12ffe6f39fdbf2d. Now we also support the 'border' property, which is shorthand to set all four borders' width, style and color. Fixes: QTBUG-123167 Pick-to: 6.6 Change-Id: I5f29b94ab9facf412a9c230d554efb5c69368b6b Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> (cherry picked from commit 26e75d452eeb2762fa3ece1c63e94d01587c6260) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
f02ccd86c7
commit
732962d604
@ -979,9 +979,11 @@ void ValueExtractor::borderValue(const Declaration &decl, int *width, QCss::Bord
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.color = parseBrushValue(decl.d->values.at(i), pal);
|
data.color = parseBrushValue(decl.d->values.at(i), pal);
|
||||||
*color = brushFromData(data.color, pal);
|
if (data.color.type != BrushData::Invalid) {
|
||||||
if (data.color.type != BrushData::DependsOnThePalette)
|
*color = brushFromData(data.color, pal);
|
||||||
decl.d->parsed = QVariant::fromValue<BorderData>(data);
|
if (data.color.type != BrushData::DependsOnThePalette)
|
||||||
|
decl.d->parsed = QVariant::fromValue<BorderData>(data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parseShorthandBackgroundProperty(const QList<QCss::Value> &values, BrushData *brush, QString *image, Repeat *repeat, Qt::Alignment *alignment, const QPalette &pal)
|
static void parseShorthandBackgroundProperty(const QList<QCss::Value> &values, BrushData *brush, QString *image, Repeat *repeat, Qt::Alignment *alignment, const QPalette &pal)
|
||||||
|
@ -1818,11 +1818,20 @@ void QTextDocumentLayoutPrivate::drawTableCell(const QRectF &cellRect, QPainter
|
|||||||
if (r >= headerRowCount)
|
if (r >= headerRowCount)
|
||||||
topMargin += td->headerHeight.toReal();
|
topMargin += td->headerHeight.toReal();
|
||||||
|
|
||||||
if (!td->borderCollapse && td->border != 0) {
|
// If cell border configured, don't draw default border for cells. It will be taken care later by
|
||||||
|
// drawTableCellBorder().
|
||||||
|
bool cellBorderConfigured = (cell.format().hasProperty(QTextFormat::TableCellLeftBorder) ||
|
||||||
|
cell.format().hasProperty(QTextFormat::TableCellTopBorder) ||
|
||||||
|
cell.format().hasProperty(QTextFormat::TableCellRightBorder) ||
|
||||||
|
cell.format().hasProperty(QTextFormat::TableCellBottomBorder));
|
||||||
|
|
||||||
|
if (!td->borderCollapse && td->border != 0 && !cellBorderConfigured) {
|
||||||
const QBrush oldBrush = painter->brush();
|
const QBrush oldBrush = painter->brush();
|
||||||
const QPen oldPen = painter->pen();
|
const QPen oldPen = painter->pen();
|
||||||
|
|
||||||
const qreal border = td->border.toReal();
|
// If border is configured for the table (and not explicitly for the cell), then
|
||||||
|
// always draw 1px border around the cell
|
||||||
|
const qreal border = 1;
|
||||||
|
|
||||||
QRectF borderRect(cellRect.left() - border, cellRect.top() - border, cellRect.width() + border, cellRect.height() + border);
|
QRectF borderRect(cellRect.left() - border, cellRect.top() - border, cellRect.width() + border, cellRect.height() + border);
|
||||||
|
|
||||||
@ -1885,7 +1894,8 @@ void QTextDocumentLayoutPrivate::drawTableCell(const QRectF &cellRect, QPainter
|
|||||||
}
|
}
|
||||||
|
|
||||||
// paint over the background - otherwise we would have to adjust the background paint cellRect for the border values
|
// paint over the background - otherwise we would have to adjust the background paint cellRect for the border values
|
||||||
drawTableCellBorder(cellRect, painter, table, td, cell);
|
if (cellBorderConfigured)
|
||||||
|
drawTableCellBorder(cellRect, painter, table, td, cell);
|
||||||
|
|
||||||
const QFixed verticalOffset = td->cellVerticalOffsets.at(c + r * table->columns());
|
const QFixed verticalOffset = td->cellVerticalOffsets.at(c + r * table->columns());
|
||||||
|
|
||||||
|
@ -1181,7 +1181,7 @@ void QTextHtmlParserNode::applyCssDeclarations(const QList<QCss::Declaration> &d
|
|||||||
QCss::ValueExtractor extractor(declarations);
|
QCss::ValueExtractor extractor(declarations);
|
||||||
extractor.extractBox(margin, padding);
|
extractor.extractBox(margin, padding);
|
||||||
|
|
||||||
if (id == Html_td || id == Html_th) {
|
auto getBorderValues = [&extractor](qreal *borderWidth, QBrush *borderBrush, QTextFrameFormat::BorderStyle *borderStyles) {
|
||||||
QCss::BorderStyle cssStyles[4];
|
QCss::BorderStyle cssStyles[4];
|
||||||
int cssBorder[4];
|
int cssBorder[4];
|
||||||
QSize cssRadii[4]; // unused
|
QSize cssRadii[4]; // unused
|
||||||
@ -1193,12 +1193,16 @@ void QTextHtmlParserNode::applyCssDeclarations(const QList<QCss::Declaration> &d
|
|||||||
// QCss::BorderWidth parsing below which expects a single value
|
// QCss::BorderWidth parsing below which expects a single value
|
||||||
// will not work as expected - which in this case does not matter
|
// will not work as expected - which in this case does not matter
|
||||||
// because tableBorder is not relevant for cells.
|
// because tableBorder is not relevant for cells.
|
||||||
extractor.extractBorder(cssBorder, tableCellBorderBrush, cssStyles, cssRadii);
|
bool hit = extractor.extractBorder(cssBorder, borderBrush, cssStyles, cssRadii);
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
tableCellBorderStyle[i] = toQTextFrameFormat(cssStyles[i]);
|
borderStyles[i] = toQTextFrameFormat(cssStyles[i]);
|
||||||
tableCellBorder[i] = static_cast<qreal>(cssBorder[i]);
|
borderWidth[i] = static_cast<qreal>(cssBorder[i]);
|
||||||
}
|
}
|
||||||
}
|
return hit;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (id == Html_td || id == Html_th)
|
||||||
|
getBorderValues(tableCellBorder, tableCellBorderBrush, tableCellBorderStyle);
|
||||||
|
|
||||||
for (int i = 0; i < declarations.size(); ++i) {
|
for (int i = 0; i < declarations.size(); ++i) {
|
||||||
const QCss::Declaration &decl = declarations.at(i);
|
const QCss::Declaration &decl = declarations.at(i);
|
||||||
@ -1220,6 +1224,19 @@ void QTextHtmlParserNode::applyCssDeclarations(const QList<QCss::Declaration> &d
|
|||||||
tableBorder = borders[0];
|
tableBorder = borders[0];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case QCss::Border: {
|
||||||
|
qreal tblBorder[4];
|
||||||
|
QBrush tblBorderBrush[4];
|
||||||
|
QTextFrameFormat::BorderStyle tblBorderStyle[4];
|
||||||
|
if (getBorderValues(tblBorder, tblBorderBrush, tblBorderStyle)) {
|
||||||
|
tableBorder = tblBorder[0];
|
||||||
|
if (tblBorderBrush[0].color().isValid())
|
||||||
|
borderBrush = tblBorderBrush[0];
|
||||||
|
if (tblBorderStyle[0] != static_cast<QTextFrameFormat::BorderStyle>(-1))
|
||||||
|
borderStyle = tblBorderStyle[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case QCss::BorderCollapse:
|
case QCss::BorderCollapse:
|
||||||
borderCollapse = decl.borderCollapseValue();
|
borderCollapse = decl.borderCollapseValue();
|
||||||
break;
|
break;
|
||||||
@ -1697,7 +1714,8 @@ void QTextHtmlParser::applyAttributes(const QStringList &attributes)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Html_table:
|
case Html_table:
|
||||||
if (key == "border"_L1) {
|
// If table border already set through css style, prefer that one otherwise consider this value
|
||||||
|
if (key == "border"_L1 && !node->tableBorder) {
|
||||||
setFloatAttribute(&node->tableBorder, value);
|
setFloatAttribute(&node->tableBorder, value);
|
||||||
} else if (key == "bgcolor"_L1) {
|
} else if (key == "bgcolor"_L1) {
|
||||||
QColor c = QColor::fromString(value);
|
QColor c = QColor::fromString(value);
|
||||||
|
@ -75,6 +75,8 @@ private slots:
|
|||||||
#endif
|
#endif
|
||||||
void checkBorderAttributes_data();
|
void checkBorderAttributes_data();
|
||||||
void checkBorderAttributes();
|
void checkBorderAttributes();
|
||||||
|
void checkTableBorderAttributes_data();
|
||||||
|
void checkTableBorderAttributes();
|
||||||
|
|
||||||
#ifndef QT_NO_WIDGETS
|
#ifndef QT_NO_WIDGETS
|
||||||
void columnWidthWithSpans();
|
void columnWidthWithSpans();
|
||||||
@ -1261,6 +1263,72 @@ void tst_QTextTable::checkBorderAttributes()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QTextTable::checkTableBorderAttributes_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QString>("html");
|
||||||
|
QTest::addColumn<qreal>("tableBorderWidth");
|
||||||
|
QTest::addColumn<QTextFrameFormat::BorderStyle>("tableBorderStyle");
|
||||||
|
QTest::addColumn<QBrush>("tableBorderBrush");
|
||||||
|
|
||||||
|
const QString tableHtmlStart = QStringLiteral("<html><head><style>");
|
||||||
|
const QString tableHtmlEnd1 = QStringLiteral("</style></head><body>"
|
||||||
|
"<table><tr><td>One</td><td>Two</td></tr></table>"
|
||||||
|
"</body></html>");
|
||||||
|
const QString tableHtmlEnd2 = QStringLiteral("</style></head><body>"
|
||||||
|
"<table border=10><tr><td>One</td><td>Two</td></tr></table>"
|
||||||
|
"</body></html>");
|
||||||
|
|
||||||
|
QTest::newRow("table-border-attributes-shorthand")
|
||||||
|
<< QString("%1"
|
||||||
|
"table {"
|
||||||
|
"border: 2px solid red;"
|
||||||
|
"}"
|
||||||
|
"%2").arg(tableHtmlStart).arg(tableHtmlEnd1)
|
||||||
|
<< 2.0 << QTextFrameFormat::BorderStyle_Solid << QBrush(Qt::red);
|
||||||
|
|
||||||
|
QTest::newRow("table-border-attributes-explicit")
|
||||||
|
<< QString("%1"
|
||||||
|
"table {"
|
||||||
|
"border-width: 2px;"
|
||||||
|
"border-color: red;"
|
||||||
|
"border-style: dashed;"
|
||||||
|
"}"
|
||||||
|
"%2").arg(tableHtmlStart).arg(tableHtmlEnd1)
|
||||||
|
<< 2.0 << QTextFrameFormat::BorderStyle_Dashed << QBrush(Qt::red);
|
||||||
|
|
||||||
|
QTest::newRow("table-border-override")
|
||||||
|
<< QString("%1"
|
||||||
|
"table {"
|
||||||
|
"border: 2px solid red;"
|
||||||
|
"}"
|
||||||
|
"%2").arg(tableHtmlStart).arg(tableHtmlEnd2)
|
||||||
|
<< 2.0 << QTextFrameFormat::BorderStyle_Solid << QBrush(Qt::red);
|
||||||
|
|
||||||
|
QTest::newRow("table-border-default")
|
||||||
|
<< QString("%1"
|
||||||
|
"%2").arg(tableHtmlStart).arg(tableHtmlEnd2)
|
||||||
|
<< 10.0 << QTextFrameFormat::BorderStyle_Outset << QBrush(Qt::darkGray);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QTextTable::checkTableBorderAttributes()
|
||||||
|
{
|
||||||
|
QFETCH(QString, html);
|
||||||
|
QFETCH(qreal, tableBorderWidth);
|
||||||
|
QFETCH(QTextFrameFormat::BorderStyle, tableBorderStyle);
|
||||||
|
QFETCH(QBrush, tableBorderBrush);
|
||||||
|
|
||||||
|
QTextDocument doc;
|
||||||
|
doc.setHtml(html);
|
||||||
|
QTextCursor cursor(doc.firstBlock());
|
||||||
|
cursor.movePosition(QTextCursor::Right);
|
||||||
|
|
||||||
|
QTextTable *currentTable = cursor.currentTable();
|
||||||
|
QVERIFY(currentTable);
|
||||||
|
QCOMPARE(currentTable->format().border(), tableBorderWidth);
|
||||||
|
QCOMPARE(currentTable->format().borderStyle(), tableBorderStyle);
|
||||||
|
QCOMPARE(currentTable->format().borderBrush(), tableBorderBrush);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_WIDGETS
|
#ifndef QT_NO_WIDGETS
|
||||||
void tst_QTextTable::columnWidthWithSpans()
|
void tst_QTextTable::columnWidthWithSpans()
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user