[F] Fix cell width evalutation

This commit is contained in:
seleznevae 2020-02-07 20:01:50 +03:00
parent 3dff45bd73
commit 0b671b1f93
4 changed files with 96 additions and 74 deletions

View File

@ -2091,7 +2091,10 @@ FT_INTERNAL
f_cell_t *copy_cell(f_cell_t *cell); f_cell_t *copy_cell(f_cell_t *cell);
FT_INTERNAL FT_INTERNAL
size_t hint_width_cell(const f_cell_t *cell, const f_context_t *context, enum f_geometry_type geom); size_t hint_vis_width_cell(const f_cell_t *cell, const f_context_t *context);
FT_INTERNAL
size_t invis_codepoints_width_cell(const f_cell_t *cell, const f_context_t *context);
FT_INTERNAL FT_INTERNAL
size_t hint_height_cell(const f_cell_t *cell, const f_context_t *context); size_t hint_height_cell(const f_cell_t *cell, const f_context_t *context);
@ -2353,7 +2356,7 @@ enum f_cell_type get_cell_type(const f_cell_t *cell)
} }
FT_INTERNAL FT_INTERNAL
size_t hint_width_cell(const f_cell_t *cell, const f_context_t *context, enum f_geometry_type geom) size_t hint_vis_width_cell(const f_cell_t *cell, const f_context_t *context)
{ {
/* todo: /* todo:
* At the moment min width includes paddings. Maybe it is better that min width weren't include * At the moment min width includes paddings. Maybe it is better that min width weren't include
@ -2374,8 +2377,20 @@ size_t hint_width_cell(const f_cell_t *cell, const f_context_t *context, enum f_
result += buffer_text_visible_width(cell->str_buffer); result += buffer_text_visible_width(cell->str_buffer);
} }
result = MAX(result, (size_t)get_cell_property_hierarchically(properties, row, column, FT_CPROP_MIN_WIDTH)); result = MAX(result, (size_t)get_cell_property_hierarchically(properties, row, column, FT_CPROP_MIN_WIDTH));
return result;
}
if (geom == INTERN_REPR_GEOMETRY) { FT_INTERNAL
size_t invis_codepoints_width_cell(const f_cell_t *cell, const f_context_t *context)
{
assert(cell);
assert(context);
f_table_properties_t *properties = context->table_properties;
size_t row = context->row;
size_t column = context->column;
size_t result = 0;
char cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE]; char cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_style_tag_for_cell(properties, row, column, cell_style_tag, TEXT_STYLE_TAG_MAX_SIZE); get_style_tag_for_cell(properties, row, column, cell_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
result += strlen(cell_style_tag); result += strlen(cell_style_tag);
@ -2391,8 +2406,6 @@ size_t hint_width_cell(const f_cell_t *cell, const f_context_t *context, enum f_
char reset_content_style_tag[TEXT_STYLE_TAG_MAX_SIZE]; char reset_content_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_reset_style_tag_for_content(properties, row, column, reset_content_style_tag, TEXT_STYLE_TAG_MAX_SIZE); get_reset_style_tag_for_content(properties, row, column, reset_content_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
result += strlen(reset_content_style_tag); result += strlen(reset_content_style_tag);
}
return result; return result;
} }
@ -2424,7 +2437,7 @@ int cell_printf(f_cell_t *cell, size_t row, f_conv_context_t *cntx, size_t vis_w
const f_context_t *context = cntx->cntx; const f_context_t *context = cntx->cntx;
size_t buf_len = vis_width; size_t buf_len = vis_width;
if (cell == NULL || (vis_width < hint_width_cell(cell, context, VISIBLE_GEOMETRY))) { if (cell == NULL || (vis_width < hint_vis_width_cell(cell, context))) {
return -1; return -1;
} }
@ -7001,7 +7014,7 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table,
return FT_ERROR; return FT_ERROR;
} }
size_t column_visible_width = 0; size_t max_invis_codepoints = 0;
size_t cols = 0; size_t cols = 0;
size_t rows = 0; size_t rows = 0;
int status = get_table_sizes(table, &rows, &cols); int status = get_table_sizes(table, &rows, &cols);
@ -7023,17 +7036,6 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table,
for (col = 0; col < cols; ++col) { for (col = 0; col < cols; ++col) {
col_width_arr[col] = 0; col_width_arr[col] = 0;
size_t row = 0; size_t row = 0;
if (geom == INTERN_REPR_GEOMETRY) {
column_visible_width = 0;
for (row = 0; row < rows; ++row) {
const f_row_t *row_p = get_row_c(table, row);
const f_cell_t *cell = get_cell_c(row_p, col);
if (!cell)
continue;
size_t cell_vis_width = hint_width_cell(cell, &context, VISIBLE_GEOMETRY);
column_visible_width = MAX(column_visible_width, cell_vis_width);
}
}
for (row = 0; row < rows; ++row) { for (row = 0; row < rows; ++row) {
const f_row_t *row_p = get_row_c(table, row); const f_row_t *row_p = get_row_c(table, row);
const f_cell_t *cell = get_cell_c(row_p, col); const f_cell_t *cell = get_cell_c(row_p, col);
@ -7042,7 +7044,7 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table,
if (cell) { if (cell) {
switch (get_cell_type(cell)) { switch (get_cell_type(cell)) {
case COMMON_CELL: case COMMON_CELL:
col_width_arr[col] = MAX(col_width_arr[col], hint_width_cell(cell, &context, geom)); col_width_arr[col] = MAX(col_width_arr[col], hint_vis_width_cell(cell, &context));
break; break;
case GROUP_MASTER_CELL: case GROUP_MASTER_CELL:
combined_cells_found = 1; combined_cells_found = 1;
@ -7062,13 +7064,19 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table,
} }
} }
// In theory it is possible that cell with max intern. representation
// just consists of invisible symobls and therefore in future a lot of
// paddings will be added to it during conversion to string. So to be
// sure we add max visible width in the column.
// TODO: Try to reduce this addition.
if (geom == INTERN_REPR_GEOMETRY) { if (geom == INTERN_REPR_GEOMETRY) {
col_width_arr[col] += column_visible_width; max_invis_codepoints = 0;
for (row = 0; row < rows; ++row) {
const f_row_t *row_p = get_row_c(table, row);
const f_cell_t *cell = get_cell_c(row_p, col);
if (!cell)
continue;
context.column = col;
context.row = row;
size_t inv_codepoints = invis_codepoints_width_cell(cell, &context);
max_invis_codepoints = MAX(max_invis_codepoints, inv_codepoints);
}
col_width_arr[col] += max_invis_codepoints;
} }
} }
@ -7082,7 +7090,10 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table,
context.row = row; context.row = row;
if (cell) { if (cell) {
if (get_cell_type(cell) == GROUP_MASTER_CELL) { if (get_cell_type(cell) == GROUP_MASTER_CELL) {
size_t hint_width = hint_width_cell(cell, &context, geom); size_t hint_width = hint_vis_width_cell(cell, &context);
if (geom == INTERN_REPR_GEOMETRY) {
hint_width += invis_codepoints_width_cell(cell, &context);
}
size_t slave_col = col + group_cell_number(row_p, col); size_t slave_col = col + group_cell_number(row_p, col);
size_t cur_adj_col = col; size_t cur_adj_col = col;
size_t group_width = col_width_arr[col]; size_t group_width = col_width_arr[col];

View File

@ -65,7 +65,7 @@ enum f_cell_type get_cell_type(const f_cell_t *cell)
} }
FT_INTERNAL FT_INTERNAL
size_t hint_width_cell(const f_cell_t *cell, const f_context_t *context, enum f_geometry_type geom) size_t hint_vis_width_cell(const f_cell_t *cell, const f_context_t *context)
{ {
/* todo: /* todo:
* At the moment min width includes paddings. Maybe it is better that min width weren't include * At the moment min width includes paddings. Maybe it is better that min width weren't include
@ -86,8 +86,20 @@ size_t hint_width_cell(const f_cell_t *cell, const f_context_t *context, enum f_
result += buffer_text_visible_width(cell->str_buffer); result += buffer_text_visible_width(cell->str_buffer);
} }
result = MAX(result, (size_t)get_cell_property_hierarchically(properties, row, column, FT_CPROP_MIN_WIDTH)); result = MAX(result, (size_t)get_cell_property_hierarchically(properties, row, column, FT_CPROP_MIN_WIDTH));
return result;
}
if (geom == INTERN_REPR_GEOMETRY) { FT_INTERNAL
size_t invis_codepoints_width_cell(const f_cell_t *cell, const f_context_t *context)
{
assert(cell);
assert(context);
f_table_properties_t *properties = context->table_properties;
size_t row = context->row;
size_t column = context->column;
size_t result = 0;
char cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE]; char cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_style_tag_for_cell(properties, row, column, cell_style_tag, TEXT_STYLE_TAG_MAX_SIZE); get_style_tag_for_cell(properties, row, column, cell_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
result += strlen(cell_style_tag); result += strlen(cell_style_tag);
@ -103,8 +115,6 @@ size_t hint_width_cell(const f_cell_t *cell, const f_context_t *context, enum f_
char reset_content_style_tag[TEXT_STYLE_TAG_MAX_SIZE]; char reset_content_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_reset_style_tag_for_content(properties, row, column, reset_content_style_tag, TEXT_STYLE_TAG_MAX_SIZE); get_reset_style_tag_for_content(properties, row, column, reset_content_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
result += strlen(reset_content_style_tag); result += strlen(reset_content_style_tag);
}
return result; return result;
} }
@ -136,7 +146,7 @@ int cell_printf(f_cell_t *cell, size_t row, f_conv_context_t *cntx, size_t vis_w
const f_context_t *context = cntx->cntx; const f_context_t *context = cntx->cntx;
size_t buf_len = vis_width; size_t buf_len = vis_width;
if (cell == NULL || (vis_width < hint_width_cell(cell, context, VISIBLE_GEOMETRY))) { if (cell == NULL || (vis_width < hint_vis_width_cell(cell, context))) {
return -1; return -1;
} }

View File

@ -13,7 +13,10 @@ FT_INTERNAL
f_cell_t *copy_cell(f_cell_t *cell); f_cell_t *copy_cell(f_cell_t *cell);
FT_INTERNAL FT_INTERNAL
size_t hint_width_cell(const f_cell_t *cell, const f_context_t *context, enum f_geometry_type geom); size_t hint_vis_width_cell(const f_cell_t *cell, const f_context_t *context);
FT_INTERNAL
size_t invis_codepoints_width_cell(const f_cell_t *cell, const f_context_t *context);
FT_INTERNAL FT_INTERNAL
size_t hint_height_cell(const f_cell_t *cell, const f_context_t *context); size_t hint_height_cell(const f_cell_t *cell, const f_context_t *context);

View File

@ -143,7 +143,7 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table,
return FT_ERROR; return FT_ERROR;
} }
size_t column_visible_width = 0; size_t max_invis_codepoints = 0;
size_t cols = 0; size_t cols = 0;
size_t rows = 0; size_t rows = 0;
int status = get_table_sizes(table, &rows, &cols); int status = get_table_sizes(table, &rows, &cols);
@ -165,17 +165,6 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table,
for (col = 0; col < cols; ++col) { for (col = 0; col < cols; ++col) {
col_width_arr[col] = 0; col_width_arr[col] = 0;
size_t row = 0; size_t row = 0;
if (geom == INTERN_REPR_GEOMETRY) {
column_visible_width = 0;
for (row = 0; row < rows; ++row) {
const f_row_t *row_p = get_row_c(table, row);
const f_cell_t *cell = get_cell_c(row_p, col);
if (!cell)
continue;
size_t cell_vis_width = hint_width_cell(cell, &context, VISIBLE_GEOMETRY);
column_visible_width = MAX(column_visible_width, cell_vis_width);
}
}
for (row = 0; row < rows; ++row) { for (row = 0; row < rows; ++row) {
const f_row_t *row_p = get_row_c(table, row); const f_row_t *row_p = get_row_c(table, row);
const f_cell_t *cell = get_cell_c(row_p, col); const f_cell_t *cell = get_cell_c(row_p, col);
@ -184,7 +173,7 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table,
if (cell) { if (cell) {
switch (get_cell_type(cell)) { switch (get_cell_type(cell)) {
case COMMON_CELL: case COMMON_CELL:
col_width_arr[col] = MAX(col_width_arr[col], hint_width_cell(cell, &context, geom)); col_width_arr[col] = MAX(col_width_arr[col], hint_vis_width_cell(cell, &context));
break; break;
case GROUP_MASTER_CELL: case GROUP_MASTER_CELL:
combined_cells_found = 1; combined_cells_found = 1;
@ -204,13 +193,19 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table,
} }
} }
// In theory it is possible that cell with max intern. representation
// just consists of invisible symobls and therefore in future a lot of
// paddings will be added to it during conversion to string. So to be
// sure we add max visible width in the column.
// TODO: Try to reduce this addition.
if (geom == INTERN_REPR_GEOMETRY) { if (geom == INTERN_REPR_GEOMETRY) {
col_width_arr[col] += column_visible_width; max_invis_codepoints = 0;
for (row = 0; row < rows; ++row) {
const f_row_t *row_p = get_row_c(table, row);
const f_cell_t *cell = get_cell_c(row_p, col);
if (!cell)
continue;
context.column = col;
context.row = row;
size_t inv_codepoints = invis_codepoints_width_cell(cell, &context);
max_invis_codepoints = MAX(max_invis_codepoints, inv_codepoints);
}
col_width_arr[col] += max_invis_codepoints;
} }
} }
@ -224,7 +219,10 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table,
context.row = row; context.row = row;
if (cell) { if (cell) {
if (get_cell_type(cell) == GROUP_MASTER_CELL) { if (get_cell_type(cell) == GROUP_MASTER_CELL) {
size_t hint_width = hint_width_cell(cell, &context, geom); size_t hint_width = hint_vis_width_cell(cell, &context);
if (geom == INTERN_REPR_GEOMETRY) {
hint_width += invis_codepoints_width_cell(cell, &context);
}
size_t slave_col = col + group_cell_number(row_p, col); size_t slave_col = col + group_cell_number(row_p, col);
size_t cur_adj_col = col; size_t cur_adj_col = col;
size_t group_width = col_width_arr[col]; size_t group_width = col_width_arr[col];