diff --git a/samples/html/test/tables.htm b/samples/html/test/tables.htm
index 696bbbb590..e4ef17c990 100644
--- a/samples/html/test/tables.htm
+++ b/samples/html/test/tables.htm
@@ -34,6 +34,15 @@ tests page...
+
TABLE ALIGN moves the table, not the cell text:
+
+
+
+| Left-aligned cell text |
+More text |
+
+
+
Subsampling is shown there:
diff --git a/src/html/m_tables.cpp b/src/html/m_tables.cpp
index 9b3c62c5c0..85ecabb4bd 100644
--- a/src/html/m_tables.cpp
+++ b/src/html/m_tables.cpp
@@ -3,6 +3,7 @@
// Purpose: wxHtml module for tables
// Author: Vaclav Slavik
// Copyright: (c) 1999 Vaclav Slavik
+// (c) 2026 wxWidgets development team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
@@ -683,9 +684,25 @@ TAG_HANDLER_BEGIN(TABLE, "TABLE,TR,TD,TH")
TAG_HANDLER_VARS
wxHtmlTableCell* m_Table;
- wxString m_tAlign, m_rAlign;
+ wxString m_rAlign;
wxHtmlContainerCell *m_enclosingContainer;
+ void SetTableAlignment(wxHtmlContainerCell *c, const wxHtmlTag& tag)
+ {
+ wxString align;
+ if ( !tag.GetParamAsString("ALIGN", &align) )
+ return;
+
+ align.MakeUpper();
+
+ if ( align == "RIGHT" )
+ c->SetAlignHor(wxHTML_ALIGN_RIGHT);
+ else if ( align == "LEFT" )
+ c->SetAlignHor(wxHTML_ALIGN_LEFT);
+ else if ( align == "CENTER" )
+ c->SetAlignHor(wxHTML_ALIGN_CENTER);
+ }
+
// Call ParseInner() preserving background colour and mode after any
// changes done by it.
void CallParseInnerWithBg(const wxHtmlTag& tag, const wxColour& colBg)
@@ -721,7 +738,6 @@ TAG_HANDLER_BEGIN(TABLE, "TABLE,TR,TD,TH")
{
m_Table = nullptr;
m_enclosingContainer = nullptr;
- m_tAlign.clear();
m_rAlign.clear();
}
@@ -734,9 +750,11 @@ TAG_HANDLER_BEGIN(TABLE, "TABLE,TR,TD,TH")
if (tag.GetName() == wxT("TABLE"))
{
wxHtmlTableCell *oldt = m_Table;
+ const wxString oldRowAlign = m_rAlign;
wxHtmlContainerCell *oldEnclosing = m_enclosingContainer;
m_enclosingContainer = c = m_WParser->OpenContainer();
+ SetTableAlignment(c, tag);
m_Table = new wxHtmlTableCell(c, tag, m_WParser->GetPixelScale());
@@ -759,8 +777,6 @@ TAG_HANDLER_BEGIN(TABLE, "TABLE,TR,TD,TH")
m_Table->SetWidthFloat(0, wxHTML_UNITS_PIXELS);
}
int oldAlign = m_WParser->GetAlign();
- if (!tag.GetParamAsString(wxT("ALIGN"), &m_tAlign))
- m_tAlign.clear();
CallParseInnerWithBg(tag, m_Table->GetBackgroundColour());
@@ -769,6 +785,7 @@ TAG_HANDLER_BEGIN(TABLE, "TABLE,TR,TD,TH")
m_WParser->CloseContainer();
m_Table = oldt;
+ m_rAlign = oldRowAlign;
m_enclosingContainer = oldEnclosing;
return true; // ParseInner() called
@@ -781,8 +798,8 @@ TAG_HANDLER_BEGIN(TABLE, "TABLE,TR,TD,TH")
if (tag.GetName() == wxT("TR"))
{
m_Table->AddRow(tag);
- if (!tag.GetParamAsString(wxT("ALIGN"), &m_rAlign))
- m_rAlign = m_tAlign;
+ if ( !tag.GetParamAsString("ALIGN", &m_rAlign) )
+ m_rAlign.clear();
}
// new cell
diff --git a/tests/html/htmlparser.cpp b/tests/html/htmlparser.cpp
index 79854c7a03..a576116fbd 100644
--- a/tests/html/htmlparser.cpp
+++ b/tests/html/htmlparser.cpp
@@ -17,6 +17,7 @@
#ifndef WX_PRECOMP
+ #include "wx/bitmap.h"
#include "wx/dcmemory.h"
#include "wx/log.h"
#endif // WX_PRECOMP
@@ -25,6 +26,20 @@
#include
+namespace
+{
+
+const wxHtmlCell *GetFirstNonFormattingChild(const wxHtmlContainerCell *cell)
+{
+ const wxHtmlCell *child = cell->GetFirstChild();
+ while ( child && child->IsFormattingCell() )
+ child = child->GetNext();
+
+ return child;
+}
+
+} // anonymous namespace
+
// Test that parsing invalid HTML simply fails but doesn't crash for example.
TEST_CASE("wxHtmlParser::ParseInvalid", "[html][parser][error]")
{
@@ -134,4 +149,58 @@ TEST_CASE("wxHtmlCell::Detach", "[html][cell]")
}
}
+TEST_CASE("wxHtmlParser::TableAlign", "[html][parser][table]")
+{
+ wxBitmap bmp(400, 400);
+ wxMemoryDC dc(bmp);
+
+ wxHtmlWinParser parser;
+ parser.SetDC(&dc);
+
+ std::unique_ptr const root(
+ static_cast(
+ parser.Parse(
+ ""
+ )
+ )
+ );
+ REQUIRE( root );
+
+ root->Layout(200);
+
+ const wxHtmlCell *cell = GetFirstNonFormattingChild(root.get());
+ REQUIRE( cell );
+
+ const wxHtmlContainerCell *body =
+ static_cast(cell);
+
+ cell = GetFirstNonFormattingChild(body);
+ REQUIRE( cell );
+
+ const wxHtmlContainerCell *tableWrapper =
+ static_cast(cell);
+
+ cell = GetFirstNonFormattingChild(tableWrapper);
+ REQUIRE( cell );
+
+ const wxHtmlContainerCell *table =
+ static_cast(cell);
+
+ CHECK( table->GetPosX() > 0 );
+
+ cell = GetFirstNonFormattingChild(table);
+ REQUIRE( cell );
+
+ const wxHtmlContainerCell *td =
+ static_cast(cell);
+
+ cell = GetFirstNonFormattingChild(td);
+ REQUIRE( cell );
+
+ const wxHtmlContainerCell *tdContent =
+ static_cast(cell);
+
+ CHECK( tdContent->GetAlignHor() == wxHTML_ALIGN_LEFT );
+}
+
#endif //wxUSE_HTML