diff --git a/include/litehtml/table.h b/include/litehtml/table.h index 53ef837..1c7b0b7 100644 --- a/include/litehtml/table.h +++ b/include/litehtml/table.h @@ -210,12 +210,15 @@ namespace litehtml rows m_cells; table_column::vector m_columns; table_row::vector m_rows; + elements_vector m_captions; + int m_captions_height; public: table_grid() { m_rows_count = 0; m_cols_count = 0; + m_captions_height = 0; } void clear(); @@ -226,9 +229,13 @@ namespace litehtml table_cell* cell(int t_col, int t_row); table_column& column(int c) { return m_columns[c]; } table_row& row(int r) { return m_rows[r]; } + elements_vector& captions() { return m_captions; } - int rows_count() { return m_rows_count; } - int cols_count() { return m_cols_count; } + int rows_count() const { return m_rows_count; } + int cols_count() const { return m_cols_count; } + + void captions_height(int height) { m_captions_height = height; } + int captions_height() const { return m_captions_height; } void distribute_max_width(int width, int start, int end); void distribute_min_width(int width, int start, int end); diff --git a/src/document.cpp b/src/document.cpp index f67623d..8da0d9c 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -904,11 +904,14 @@ void litehtml::document::fix_table_children(element::ptr& el_ptr, style_display { if (!(*cur_iter)->is_white_space() || ((*cur_iter)->is_white_space() && !tmp.empty())) { - if (tmp.empty()) + if (disp != display_table_row_group || (*cur_iter)->get_display() != display_table_caption) { - first_iter = cur_iter; + if (tmp.empty()) + { + first_iter = cur_iter; + } + tmp.push_back((*cur_iter)); } - tmp.push_back((*cur_iter)); } cur_iter++; } diff --git a/src/el_table.cpp b/src/el_table.cpp index 06d77be..7a45671 100644 --- a/src/el_table.cpp +++ b/src/el_table.cpp @@ -21,7 +21,10 @@ litehtml::el_table::~el_table() bool litehtml::el_table::appendChild(const litehtml::element::ptr& el) { if(!el) return false; - if(!t_strcmp(el->get_tagName(), _t("tbody")) || !t_strcmp(el->get_tagName(), _t("thead")) || !t_strcmp(el->get_tagName(), _t("tfoot"))) + if( !t_strcmp(el->get_tagName(), _t("tbody")) || + !t_strcmp(el->get_tagName(), _t("thead")) || + !t_strcmp(el->get_tagName(), _t("tfoot")) || + !t_strcmp(el->get_tagName(), _t("caption"))) { return html_tag::appendChild(el); } diff --git a/src/html_tag.cpp b/src/html_tag.cpp index bf20371..4d1be32 100644 --- a/src/html_tag.cpp +++ b/src/html_tag.cpp @@ -583,6 +583,14 @@ void litehtml::html_tag::init() row = row_iter.next(false); } + for (auto& el : m_children) + { + if (el->get_display() == display_table_caption) + { + m_grid->captions().push_back(el); + } + } + m_grid->finish(); } @@ -2045,6 +2053,13 @@ void litehtml::html_tag::draw_background( uint_ptr hdc, int x, int y, const posi { if(el_pos.does_intersect(clip)) { + if (m_grid) + { + int captions_height = m_grid->captions_height(); + pos.y += captions_height; + pos.height -= captions_height; + } + const background* bg = get_background(); if(bg) { @@ -4610,13 +4625,46 @@ int litehtml::html_tag::render_table(int x, int y, int max_width, bool /*second_ m_pos.width = table_width; + // Render table captions + // Table border doesn't round the caption so we have to start caption in the border position + int captions_height = -border_top(); + + for (auto& caption : m_grid->captions()) + { + caption->render(-border_left(), captions_height, table_width + border_left() + border_right()); + captions_height += caption->height(); + } + + if (captions_height) + { + // Add border height to get the top of cells + captions_height += border_top(); + + // Save caption height for draw_background + m_grid->captions_height(captions_height); + + // Move table cells to the bottom side + for (int row = 0; row < m_grid->rows_count(); row++) + { + m_grid->row(row).el_row->m_pos.y += captions_height; + for (int col = 0; col < m_grid->cols_count(); col++) + { + table_cell* cell = m_grid->cell(col, row); + if (cell->el) + { + cell->el->m_pos.y += captions_height; + } + } + } + } + calc_auto_margins(parent_width); m_pos.move_to(x, y); m_pos.x += content_margins_left(); m_pos.y += content_margins_top(); m_pos.width = table_width; - m_pos.height = table_height; + m_pos.height = table_height + captions_height; return max_table_width; } @@ -4734,6 +4782,11 @@ void litehtml::html_tag::draw_children_table(uint_ptr hdc, int x, int y, const p position pos = m_pos; pos.x += x; pos.y += y; + for (auto& caption : m_grid->captions()) + { + caption->draw(hdc, pos.x, pos.y, clip); + caption->draw_children(hdc, pos.x, pos.y, clip, flag, zindex); + } for (int row = 0; row < m_grid->rows_count(); row++) { if (flag == draw_block)