2#pragma warning(disable: 4100)
3#elif defined(__clang__)
4#pragma clang diagnostic ignored "-Wunused-parameter"
10void litehtml::table_grid::add_cell(element::ptr& el)
14 cell.colspan = t_atoi(el->get_attr(_t(
"colspan"), _t(
"1")));
15 cell.rowspan = t_atoi(el->get_attr(_t(
"rowspan"), _t(
"1")));
16 cell.borders = el->get_borders();
18 while( is_rowspanned( (
int) m_cells.size() - 1, (
int) m_cells.back().size() ) )
20 m_cells.back().push_back(table_cell());
23 m_cells.back().push_back(cell);
24 for(
int i = 1; i < cell.colspan; i++)
26 table_cell empty_cell;
27 m_cells.back().push_back(empty_cell);
32void litehtml::table_grid::begin_row(element::ptr& row)
34 std::vector<table_cell> r;
37 m_rows.push_back(table_row(0, row));
42bool litehtml::table_grid::is_rowspanned(
int r,
int c )
44 for(
int row = r - 1; row >= 0; row--)
46 if(c < (
int) m_cells[row].size())
48 if(m_cells[row][c].rowspan > 1)
50 if(m_cells[row][c].rowspan >= r - row + 1)
60void litehtml::table_grid::finish()
62 m_rows_count = (int) m_cells.size();
64 for(
int i = 0; i < (int) m_cells.size(); i++)
66 m_cols_count = std::max(m_cols_count, (
int) m_cells[i].size());
68 for(
int i = 0; i < (int) m_cells.size(); i++)
70 for(
int j = (
int) m_cells[i].size(); j < m_cols_count; j++)
72 table_cell empty_cell;
73 m_cells[i].push_back(empty_cell);
78 for(
int i = 0; i < m_cols_count; i++)
80 m_columns.push_back(table_column(0, 0));
83 for(
int col = 0; col < m_cols_count; col++)
85 for(
int row = 0; row < m_rows_count; row++)
87 if(cell(col, row)->el)
90 if(m_columns[col].border_left)
92 m_columns[col].border_left = std::min(m_columns[col].border_left, cell(col, row)->borders.left);
95 m_columns[col].border_left = cell(col, row)->borders.left;
98 if(m_columns[col].border_right)
100 m_columns[col].border_right = std::min(m_columns[col].border_right, cell(col, row)->borders.right);
103 m_columns[col].border_right = cell(col, row)->borders.right;
106 if(m_rows[row].border_top)
108 m_rows[row].border_top = std::min(m_rows[row].border_top, cell(col, row)->borders.top);
111 m_rows[row].border_top = cell(col, row)->borders.top;
114 if(m_rows[row].border_bottom)
116 m_rows[row].border_bottom = std::min(m_rows[row].border_bottom, cell(col, row)->borders.bottom);
119 m_rows[row].border_bottom = cell(col, row)->borders.bottom;
123 if(cell(col, row)->el && cell(col, row)->colspan <= 1)
125 if (!cell(col, row)->el->get_css_width().is_predefined() && m_columns[col].css_width.is_predefined())
127 m_columns[col].css_width = cell(col, row)->el->get_css_width();
133 for(
int col = 0; col < m_cols_count; col++)
135 for(
int row = 0; row < m_rows_count; row++)
137 if(cell(col, row)->el)
139 cell(col, row)->el->set_css_width(m_columns[col].css_width);
147 if(t_col >= 0 && t_col < m_cols_count && t_row >= 0 && t_row < m_rows_count)
149 return &m_cells[t_row][t_col];
154void litehtml::table_grid::distribute_max_width(
int width,
int start,
int end )
156 table_column_accessor_max_width selector;
157 distribute_width(width, start, end, &selector);
160void litehtml::table_grid::distribute_min_width(
int width,
int start,
int end )
162 table_column_accessor_min_width selector;
163 distribute_width(width, start, end, &selector);
166void litehtml::table_grid::distribute_width(
int width,
int start,
int end, table_column_accessor* acc )
168 if(!(start >= 0 && start < m_cols_count && end >= 0 && end < m_cols_count))
174 for(
int col = start; col <= end; col++)
176 cols_width += m_columns[col].max_width;
179 int add = width / (end - start + 1);
181 for(
int col = start; col <= end; col++)
185 add = round_f( (
float) width * ((
float) m_columns[col].max_width / (
float) cols_width) );
188 acc->get(m_columns[col]) += add;
190 if(added_width < width)
192 acc->get(m_columns[start]) += width - added_width;
196void litehtml::table_grid::distribute_width(
int width,
int start,
int end )
198 if(!(start >= 0 && start < m_cols_count && end >= 0 && end < m_cols_count))
203 std::vector<table_column*> distribute_columns;
205 for(
int step = 0; step < 3; step++)
207 distribute_columns.clear();
214 for(
int col = start; col <= end; col++)
216 if(m_columns[col].css_width.is_predefined())
218 distribute_columns.push_back(&m_columns[col]);
226 for(
int col = start; col <= end; col++)
228 if(!m_columns[col].css_width.is_predefined() && m_columns[col].css_width.units() == css_units_percentage)
230 distribute_columns.push_back(&m_columns[col]);
238 for(
int col = start; col <= end; col++)
240 distribute_columns.push_back(&m_columns[col]);
248 if(!distribute_columns.empty() || step == 2)
251 for(std::vector<table_column*>::iterator col = distribute_columns.begin(); col != distribute_columns.end(); col++)
253 cols_width += (*col)->max_width - (*col)->min_width;
258 int add = width / (int) distribute_columns.size();
259 for(std::vector<table_column*>::iterator col = distribute_columns.begin(); col != distribute_columns.end(); col++)
261 add = round_f( (
float) width * ((
float) ((*col)->max_width - (*col)->min_width) / (
float) cols_width) );
262 if((*col)->width + add >= (*col)->min_width)
264 (*col)->width += add;
268 added_width += ((*col)->width - (*col)->min_width) * (add / abs(add));
269 (*col)->width = (*col)->min_width;
272 if(added_width < width && step)
274 distribute_columns.front()->width += width - added_width;
279 distribute_columns.back()->width += width;
284 if(added_width == width)
289 width -= added_width;
294int litehtml::table_grid::calc_table_width(
int block_width,
bool is_auto,
int& min_table_width,
int& max_table_width)
305 for(
int col = 0; col < m_cols_count; col++)
307 min_table_width += m_columns[col].min_width;
308 max_table_width += m_columns[col].max_width;
310 if(!m_columns[col].css_width.is_predefined())
312 m_columns[col].width = m_columns[col].css_width.calc_percent(block_width);
313 m_columns[col].width = std::max(m_columns[col].width, m_columns[col].min_width);
316 m_columns[col].width = m_columns[col].min_width;
317 max_w += m_columns[col].max_width;
318 min_w += m_columns[col].min_width;
321 cur_width += m_columns[col].width;
324 if(cur_width == block_width)
329 if(cur_width < block_width)
331 if(cur_width - min_w + max_w <= block_width)
334 for(
int col = 0; col < m_cols_count; col++)
336 if(m_columns[col].css_width.is_predefined())
338 m_columns[col].width = m_columns[col].max_width;
340 cur_width += m_columns[col].width;
342 if(cur_width == block_width || is_auto)
347 distribute_width(block_width - cur_width, 0, m_cols_count - 1);
349 for(
int col = 0; col < m_cols_count; col++)
351 cur_width += m_columns[col].width;
357 for(
int col = 0; col < m_cols_count; col++)
359 if(!m_columns[col].css_width.is_predefined() && m_columns[col].css_width.units() == css_units_percentage)
361 percent += m_columns[col].css_width.val();
364 fixed_width += m_columns[col].width;
367 float scale = (float) (100.0 / percent);
369 for(
int col = 0; col < m_cols_count; col++)
371 if(!m_columns[col].css_width.is_predefined() && m_columns[col].css_width.units() == css_units_percentage)
374 w.set_value(m_columns[col].css_width.val() * scale, css_units_percentage);
375 m_columns[col].width = w.calc_percent(block_width - fixed_width);
376 if(m_columns[col].width < m_columns[col].min_width)
378 m_columns[col].width = m_columns[col].min_width;
381 cur_width += m_columns[col].width;
387void litehtml::table_grid::clear()
396void litehtml::table_grid::calc_horizontal_positions( margins& table_borders, border_collapse bc,
int bdr_space_x)
398 if(bc == border_collapse_separate)
400 int left = bdr_space_x;
401 for(
int i = 0; i < m_cols_count; i++)
403 m_columns[i].left = left;
404 m_columns[i].right = m_columns[i].left + m_columns[i].width;
405 left = m_columns[i].right + bdr_space_x;
412 left -= std::min(table_borders.left, m_columns[0].border_left);
414 for(
int i = 0; i < m_cols_count; i++)
418 left -= std::min(m_columns[i - 1].border_right, m_columns[i].border_left);
421 m_columns[i].left = left;
422 m_columns[i].right = m_columns[i].left + m_columns[i].width;
423 left = m_columns[i].right;
428void litehtml::table_grid::calc_vertical_positions( margins& table_borders, border_collapse bc,
int bdr_space_y )
430 if(bc == border_collapse_separate)
432 int top = bdr_space_y;
433 for(
int i = 0; i < m_rows_count; i++)
436 m_rows[i].bottom = m_rows[i].top + m_rows[i].height;
437 top = m_rows[i].bottom + bdr_space_y;
444 top -= std::min(table_borders.top, m_rows[0].border_top);
446 for(
int i = 0; i < m_rows_count; i++)
450 top -= std::min(m_rows[i - 1].border_bottom, m_rows[i].border_top);
454 m_rows[i].bottom = m_rows[i].top + m_rows[i].height;
455 top = m_rows[i].bottom;
460void litehtml::table_grid::calc_rows_height(
int blockHeight,
int borderSpacingY)
462 int min_table_height = 0;
465 for (
auto& row : m_rows)
467 if (!row.css_height.is_predefined())
469 if (row.css_height.units() != css_units_percentage)
471 if (row.height < (
int)row.css_height.val())
473 row.height = (int)row.css_height.val();
477 row.min_height = row.height;
478 min_table_height += row.height;
483 if (blockHeight > min_table_height)
485 int extra_height = blockHeight - min_table_height;
487 for (
auto& row : m_rows)
489 if (!row.css_height.is_predefined() && row.css_height.units() == css_units_percentage)
491 row.height = row.css_height.calc_percent(blockHeight);
492 if (row.height < row.min_height)
494 row.height = row.min_height;
497 extra_height -= row.height - row.min_height;
499 if (extra_height <= 0)
break;
501 else if (row.css_height.is_predefined())
506 if (extra_height > 0)
511 int extra_row_height = (int)(extra_height / auto_count);
512 for (
auto& row : m_rows)
514 if (row.css_height.is_predefined())
516 row.height += extra_row_height;
525 int extra_row_height = (int)(extra_height / m_rows.size());
526 for (
auto& row : m_rows)
528 row.height += extra_row_height;
533 else if (extra_height < 0)
535 extra_height = -extra_height;
536 for (
auto row = m_rows.rbegin(); row < m_rows.rend() && extra_height > 0; row++)
538 if (row->height > row->min_height)
540 if (row->height - extra_height >= row->min_height)
542 row->height -= extra_height;
547 extra_height -= row->height - row->min_height;
548 row->height = row->min_height;
558int& litehtml::table_column_accessor_max_width::get( table_column& col )
560 return col.max_width;
563int& litehtml::table_column_accessor_min_width::get( table_column& col )
565 return col.min_width;
568int& litehtml::table_column_accessor_width::get( table_column& col )