From 3cc961f958de042ef577c229aca63a739be1fd35 Mon Sep 17 00:00:00 2001 From: seleznevae Date: Mon, 3 Feb 2020 21:41:11 +0300 Subject: [PATCH 1/6] [F] Fix incorrect cell width evaluation in case of invisible symbols --- lib/fort.c | 17 +++++ src/table.c | 17 +++++ tests/bb_tests/test_table_basic.c | 108 ++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+) diff --git a/lib/fort.c b/lib/fort.c index ef4b00d..1a11fb3 100644 --- a/lib/fort.c +++ b/lib/fort.c @@ -7001,6 +7001,7 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table, return FT_ERROR; } + size_t column_visible_width = 0; size_t cols = 0; size_t rows = 0; int status = get_table_sizes(table, &rows, &cols); @@ -7022,6 +7023,17 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table, for (col = 0; col < cols; ++col) { col_width_arr[col] = 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) { const f_row_t *row_p = get_row_c(table, row); const f_cell_t *cell = get_cell_c(row_p, col); @@ -7049,6 +7061,11 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table, } } } + + if (geom == INTERN_REPR_GEOMETRY && + col_width_arr[col] > column_visible_width) { + col_width_arr[col] += column_visible_width; + } } if (combined_cells_found) { diff --git a/src/table.c b/src/table.c index 7874d22..20b9747 100644 --- a/src/table.c +++ b/src/table.c @@ -143,6 +143,7 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table, return FT_ERROR; } + size_t column_visible_width = 0; size_t cols = 0; size_t rows = 0; int status = get_table_sizes(table, &rows, &cols); @@ -164,6 +165,17 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table, for (col = 0; col < cols; ++col) { col_width_arr[col] = 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) { const f_row_t *row_p = get_row_c(table, row); const f_cell_t *cell = get_cell_c(row_p, col); @@ -191,6 +203,11 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table, } } } + + if (geom == INTERN_REPR_GEOMETRY && + col_width_arr[col] > column_visible_width) { + col_width_arr[col] += column_visible_width; + } } if (combined_cells_found) { diff --git a/tests/bb_tests/test_table_basic.c b/tests/bb_tests/test_table_basic.c index 191b4a9..8988693 100644 --- a/tests/bb_tests/test_table_basic.c +++ b/tests/bb_tests/test_table_basic.c @@ -188,6 +188,114 @@ void test_bug_fixes(void) ft_destroy_table(table); } #endif /* FT_HAVE_UTF8 */ + + SCENARIO("Issue 37 - https://github.com/seleznevae/libfort/issues/37") { + ft_table_t *table = ft_create_table(); + ft_set_border_style(table, FT_BASIC_STYLE); + ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER); + ft_write_ln(table, "xxx"); + ft_write_ln(table, + "1\n2\n3\n4\n5\n6\n7\n8\n9\n0\n1\n2\n3\n4\n5\n6\n7\n8"); + ft_set_cell_prop(table, 1, 0, FT_CPROP_CONT_FG_COLOR, FT_COLOR_RED); + + const char *table_str = ft_to_string(table); + assert_true(table_str != NULL); + const char *table_str_etalon = + "+-----+\n" + "| xxx |\n" + "+-----+\n" + "| \033[31m1\033[0m |\n" + "| \033[31m2\033[0m |\n" + "| \033[31m3\033[0m |\n" + "| \033[31m4\033[0m |\n" + "| \033[31m5\033[0m |\n" + "| \033[31m6\033[0m |\n" + "| \033[31m7\033[0m |\n" + "| \033[31m8\033[0m |\n" + "| \033[31m9\033[0m |\n" + "| \033[31m0\033[0m |\n" + "| \033[31m1\033[0m |\n" + "| \033[31m2\033[0m |\n" + "| \033[31m3\033[0m |\n" + "| \033[31m4\033[0m |\n" + "| \033[31m5\033[0m |\n" + "| \033[31m6\033[0m |\n" + "| \033[31m7\033[0m |\n" + "| \033[31m8\033[0m |\n" + "+-----+\n"; + assert_str_equal(table_str, table_str_etalon); + + ft_destroy_table(table); + } + + SCENARIO("Issue 37 - https://github.com/seleznevae/libfort/issues/37") { + ft_table_t *table = ft_create_table(); + ft_set_border_style(table, FT_BASIC_STYLE); + ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER); + + ft_write_ln(table, "hdr1", "hdr2", "xxx"); + ft_write_ln(table, "3", "", + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||"); + + ft_set_cell_prop(table, 1, FT_ANY_COLUMN, FT_CPROP_CONT_FG_COLOR, FT_COLOR_RED); + const char *table_str = ft_to_string(table); + assert_true(table_str != NULL); + + const char *table_str_etalon = + "+------+------+--------------------------------+\n" + "| hdr1 | hdr2 | xxx |\n" + "+------+------+--------------------------------+\n" + "| \033[31m3\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||\033[0m |\n" + "+------+------+--------------------------------+\n"; + assert_str_equal(table_str, table_str_etalon); + ft_destroy_table(table); + } } void test_table_basic(void) From c596d156d378977642c39b52e47231544924736c Mon Sep 17 00:00:00 2001 From: seleznevae Date: Tue, 4 Feb 2020 22:18:37 +0300 Subject: [PATCH 2/6] [A] Add changelog entry --- ChangeLog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index 0a48b47..992046d 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -8,6 +8,10 @@ - Add new table property `adding_strategy` (2 strategies available - replace(default) and insert). - Add function `ft_row_count` (`row_count` in C++ API) to get number of rows in the table. +### Bug fixes + +- Fix incorrect cell width evaluation in case of invisible symbols + ### Internal - Refactoring of code that uses vectors. From d87f5c62156e0449e248c9313c9e40467a03ef4c Mon Sep 17 00:00:00 2001 From: seleznevae Date: Wed, 5 Feb 2020 22:00:35 +0300 Subject: [PATCH 3/6] [A] Add regression test for c++ API --- tests/bb_tests_cpp/test_table_basic.cpp | 71 +++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/tests/bb_tests_cpp/test_table_basic.cpp b/tests/bb_tests_cpp/test_table_basic.cpp index 6f839a5..4e52738 100644 --- a/tests/bb_tests_cpp/test_table_basic.cpp +++ b/tests/bb_tests_cpp/test_table_basic.cpp @@ -26,6 +26,77 @@ void test_cpp_bug_fixes(void) " 3 4 \n"; assert_string_equal(table_str, table_str_etalon); } + + SCENARIO("Issue 37 - https://github.com/seleznevae/libfort/issues/37") { + fort::char_table table; + table.set_border_style(FT_BASIC_STYLE); + table.set_cell_bottom_padding(0); + table.set_cell_top_padding(0); + table.set_cell_left_padding(1); + table.set_cell_right_padding(1); + table.set_cell_text_align(fort::text_align::left); + + table << fort::header + << "hdr1" << "hdr2" << "xxx" << fort::endr + << "3" << "" << + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||||||||||||||||||||||||||\n" + "||||||"; + table.row(1).set_cell_content_fg_color(fort::color::red); + + std::string table_str = table.to_string(); + std::string table_str_etalon = + "+------+------+--------------------------------+\n" + "| hdr1 | hdr2 | xxx |\n" + "+------+------+--------------------------------+\n" + "| \033[31m3\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||||||||||||||||||||||||||\033[0m |\n" + "|\033[31m\033[0m |\033[31m\033[0m | \033[31m||||||\033[0m |\n" + "+------+------+--------------------------------+\n"; + assert_string_equal(table_str, table_str_etalon); + } } void test_cpp_table_basic(void) From 3dff45bd731ac07509e8de762537ea24858736b8 Mon Sep 17 00:00:00 2001 From: seleznevae Date: Wed, 5 Feb 2020 23:04:21 +0300 Subject: [PATCH 4/6] [F] Fix evaluation of max buffer width for column of the table --- lib/fort.c | 8 ++++++-- src/table.c | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/fort.c b/lib/fort.c index 1a11fb3..91333a7 100644 --- a/lib/fort.c +++ b/lib/fort.c @@ -7062,8 +7062,12 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table, } } - if (geom == INTERN_REPR_GEOMETRY && - col_width_arr[col] > column_visible_width) { + // 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) { col_width_arr[col] += column_visible_width; } } diff --git a/src/table.c b/src/table.c index 20b9747..6c30808 100644 --- a/src/table.c +++ b/src/table.c @@ -204,8 +204,12 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table, } } - if (geom == INTERN_REPR_GEOMETRY && - col_width_arr[col] > column_visible_width) { + // 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) { col_width_arr[col] += column_visible_width; } } From 0b671b1f93b038702ec610d0540b53d0041c5bfc Mon Sep 17 00:00:00 2001 From: seleznevae Date: Fri, 7 Feb 2020 20:01:50 +0300 Subject: [PATCH 5/6] [F] Fix cell width evalutation --- lib/fort.c | 85 ++++++++++++++++++++++++++++++----------------------- src/cell.c | 42 ++++++++++++++++---------- src/cell.h | 5 +++- src/table.c | 38 ++++++++++++------------ 4 files changed, 96 insertions(+), 74 deletions(-) diff --git a/lib/fort.c b/lib/fort.c index 91333a7..0c69c9e 100644 --- a/lib/fort.c +++ b/lib/fort.c @@ -2091,7 +2091,10 @@ FT_INTERNAL f_cell_t *copy_cell(f_cell_t *cell); 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 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 -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: * At the moment min width includes paddings. Maybe it is better that min width weren't include @@ -2374,25 +2377,35 @@ 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 = MAX(result, (size_t)get_cell_property_hierarchically(properties, row, column, FT_CPROP_MIN_WIDTH)); + return result; +} - if (geom == INTERN_REPR_GEOMETRY) { - 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); - result += strlen(cell_style_tag); +FT_INTERNAL +size_t invis_codepoints_width_cell(const f_cell_t *cell, const f_context_t *context) +{ + assert(cell); + assert(context); - char reset_cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE]; - get_reset_style_tag_for_cell(properties, row, column, reset_cell_style_tag, TEXT_STYLE_TAG_MAX_SIZE); - result += strlen(reset_cell_style_tag); + f_table_properties_t *properties = context->table_properties; + size_t row = context->row; + size_t column = context->column; - char content_style_tag[TEXT_STYLE_TAG_MAX_SIZE]; - get_style_tag_for_content(properties, row, column, content_style_tag, TEXT_STYLE_TAG_MAX_SIZE); - result += strlen(content_style_tag); + size_t result = 0; + 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); + result += strlen(cell_style_tag); - 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); - result += strlen(reset_content_style_tag); - } + char reset_cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE]; + get_reset_style_tag_for_cell(properties, row, column, reset_cell_style_tag, TEXT_STYLE_TAG_MAX_SIZE); + result += strlen(reset_cell_style_tag); + char content_style_tag[TEXT_STYLE_TAG_MAX_SIZE]; + get_style_tag_for_content(properties, row, column, content_style_tag, TEXT_STYLE_TAG_MAX_SIZE); + result += strlen(content_style_tag); + + 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); + result += strlen(reset_content_style_tag); 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; 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; } @@ -7001,7 +7014,7 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table, return FT_ERROR; } - size_t column_visible_width = 0; + size_t max_invis_codepoints = 0; size_t cols = 0; size_t rows = 0; 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) { col_width_arr[col] = 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) { const f_row_t *row_p = get_row_c(table, row); 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) { switch (get_cell_type(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; case GROUP_MASTER_CELL: 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) { - 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; if (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 cur_adj_col = col; size_t group_width = col_width_arr[col]; diff --git a/src/cell.c b/src/cell.c index 522199a..2ff816e 100644 --- a/src/cell.c +++ b/src/cell.c @@ -65,7 +65,7 @@ enum f_cell_type get_cell_type(const f_cell_t *cell) } 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: * At the moment min width includes paddings. Maybe it is better that min width weren't include @@ -86,25 +86,35 @@ 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 = MAX(result, (size_t)get_cell_property_hierarchically(properties, row, column, FT_CPROP_MIN_WIDTH)); + return result; +} - if (geom == INTERN_REPR_GEOMETRY) { - 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); - result += strlen(cell_style_tag); +FT_INTERNAL +size_t invis_codepoints_width_cell(const f_cell_t *cell, const f_context_t *context) +{ + assert(cell); + assert(context); - char reset_cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE]; - get_reset_style_tag_for_cell(properties, row, column, reset_cell_style_tag, TEXT_STYLE_TAG_MAX_SIZE); - result += strlen(reset_cell_style_tag); + f_table_properties_t *properties = context->table_properties; + size_t row = context->row; + size_t column = context->column; - char content_style_tag[TEXT_STYLE_TAG_MAX_SIZE]; - get_style_tag_for_content(properties, row, column, content_style_tag, TEXT_STYLE_TAG_MAX_SIZE); - result += strlen(content_style_tag); + size_t result = 0; + 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); + result += strlen(cell_style_tag); - 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); - result += strlen(reset_content_style_tag); - } + char reset_cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE]; + get_reset_style_tag_for_cell(properties, row, column, reset_cell_style_tag, TEXT_STYLE_TAG_MAX_SIZE); + result += strlen(reset_cell_style_tag); + char content_style_tag[TEXT_STYLE_TAG_MAX_SIZE]; + get_style_tag_for_content(properties, row, column, content_style_tag, TEXT_STYLE_TAG_MAX_SIZE); + result += strlen(content_style_tag); + + 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); + result += strlen(reset_content_style_tag); 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; 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; } diff --git a/src/cell.h b/src/cell.h index f5095d3..cc8a9dc 100644 --- a/src/cell.h +++ b/src/cell.h @@ -13,7 +13,10 @@ FT_INTERNAL f_cell_t *copy_cell(f_cell_t *cell); 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 size_t hint_height_cell(const f_cell_t *cell, const f_context_t *context); diff --git a/src/table.c b/src/table.c index 6c30808..121b164 100644 --- a/src/table.c +++ b/src/table.c @@ -143,7 +143,7 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table, return FT_ERROR; } - size_t column_visible_width = 0; + size_t max_invis_codepoints = 0; size_t cols = 0; size_t rows = 0; 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) { col_width_arr[col] = 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) { const f_row_t *row_p = get_row_c(table, row); 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) { switch (get_cell_type(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; case GROUP_MASTER_CELL: 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) { - 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; if (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 cur_adj_col = col; size_t group_width = col_width_arr[col]; From caea5d4280022d1ce59ee3bdcd695dba0103bc6b Mon Sep 17 00:00:00 2001 From: seleznevae Date: Fri, 7 Feb 2020 20:18:04 +0300 Subject: [PATCH 6/6] [C] Renamed internal functions --- lib/fort.c | 18 +++++++++--------- src/cell.c | 6 +++--- src/cell.h | 4 ++-- src/table.c | 8 ++++---- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/lib/fort.c b/lib/fort.c index 0c69c9e..654bc17 100644 --- a/lib/fort.c +++ b/lib/fort.c @@ -2091,10 +2091,10 @@ FT_INTERNAL f_cell_t *copy_cell(f_cell_t *cell); FT_INTERNAL -size_t hint_vis_width_cell(const f_cell_t *cell, const f_context_t *context); +size_t cell_vis_width(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); +size_t cell_invis_codes_width(const f_cell_t *cell, const f_context_t *context); FT_INTERNAL size_t hint_height_cell(const f_cell_t *cell, const f_context_t *context); @@ -2356,7 +2356,7 @@ enum f_cell_type get_cell_type(const f_cell_t *cell) } FT_INTERNAL -size_t hint_vis_width_cell(const f_cell_t *cell, const f_context_t *context) +size_t cell_vis_width(const f_cell_t *cell, const f_context_t *context) { /* todo: * At the moment min width includes paddings. Maybe it is better that min width weren't include @@ -2381,7 +2381,7 @@ 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) +size_t cell_invis_codes_width(const f_cell_t *cell, const f_context_t *context) { assert(cell); assert(context); @@ -2437,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; size_t buf_len = vis_width; - if (cell == NULL || (vis_width < hint_vis_width_cell(cell, context))) { + if (cell == NULL || (vis_width < cell_vis_width(cell, context))) { return -1; } @@ -7044,7 +7044,7 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table, if (cell) { switch (get_cell_type(cell)) { case COMMON_CELL: - col_width_arr[col] = MAX(col_width_arr[col], hint_vis_width_cell(cell, &context)); + col_width_arr[col] = MAX(col_width_arr[col], cell_vis_width(cell, &context)); break; case GROUP_MASTER_CELL: combined_cells_found = 1; @@ -7073,7 +7073,7 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table, continue; context.column = col; context.row = row; - size_t inv_codepoints = invis_codepoints_width_cell(cell, &context); + size_t inv_codepoints = cell_invis_codes_width(cell, &context); max_invis_codepoints = MAX(max_invis_codepoints, inv_codepoints); } col_width_arr[col] += max_invis_codepoints; @@ -7090,9 +7090,9 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table, context.row = row; if (cell) { if (get_cell_type(cell) == GROUP_MASTER_CELL) { - size_t hint_width = hint_vis_width_cell(cell, &context); + size_t hint_width = cell_vis_width(cell, &context); if (geom == INTERN_REPR_GEOMETRY) { - hint_width += invis_codepoints_width_cell(cell, &context); + hint_width += cell_invis_codes_width(cell, &context); } size_t slave_col = col + group_cell_number(row_p, col); size_t cur_adj_col = col; diff --git a/src/cell.c b/src/cell.c index 2ff816e..cab0ab1 100644 --- a/src/cell.c +++ b/src/cell.c @@ -65,7 +65,7 @@ enum f_cell_type get_cell_type(const f_cell_t *cell) } FT_INTERNAL -size_t hint_vis_width_cell(const f_cell_t *cell, const f_context_t *context) +size_t cell_vis_width(const f_cell_t *cell, const f_context_t *context) { /* todo: * At the moment min width includes paddings. Maybe it is better that min width weren't include @@ -90,7 +90,7 @@ 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) +size_t cell_invis_codes_width(const f_cell_t *cell, const f_context_t *context) { assert(cell); assert(context); @@ -146,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; size_t buf_len = vis_width; - if (cell == NULL || (vis_width < hint_vis_width_cell(cell, context))) { + if (cell == NULL || (vis_width < cell_vis_width(cell, context))) { return -1; } diff --git a/src/cell.h b/src/cell.h index cc8a9dc..92f8c06 100644 --- a/src/cell.h +++ b/src/cell.h @@ -13,10 +13,10 @@ FT_INTERNAL f_cell_t *copy_cell(f_cell_t *cell); FT_INTERNAL -size_t hint_vis_width_cell(const f_cell_t *cell, const f_context_t *context); +size_t cell_vis_width(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); +size_t cell_invis_codes_width(const f_cell_t *cell, const f_context_t *context); FT_INTERNAL size_t hint_height_cell(const f_cell_t *cell, const f_context_t *context); diff --git a/src/table.c b/src/table.c index 121b164..01613c9 100644 --- a/src/table.c +++ b/src/table.c @@ -173,7 +173,7 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table, if (cell) { switch (get_cell_type(cell)) { case COMMON_CELL: - col_width_arr[col] = MAX(col_width_arr[col], hint_vis_width_cell(cell, &context)); + col_width_arr[col] = MAX(col_width_arr[col], cell_vis_width(cell, &context)); break; case GROUP_MASTER_CELL: combined_cells_found = 1; @@ -202,7 +202,7 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table, continue; context.column = col; context.row = row; - size_t inv_codepoints = invis_codepoints_width_cell(cell, &context); + size_t inv_codepoints = cell_invis_codes_width(cell, &context); max_invis_codepoints = MAX(max_invis_codepoints, inv_codepoints); } col_width_arr[col] += max_invis_codepoints; @@ -219,9 +219,9 @@ f_status table_rows_and_cols_geometry(const ft_table_t *table, context.row = row; if (cell) { if (get_cell_type(cell) == GROUP_MASTER_CELL) { - size_t hint_width = hint_vis_width_cell(cell, &context); + size_t hint_width = cell_vis_width(cell, &context); if (geom == INTERN_REPR_GEOMETRY) { - hint_width += invis_codepoints_width_cell(cell, &context); + hint_width += cell_invis_codes_width(cell, &context); } size_t slave_col = col + group_cell_number(row_p, col); size_t cur_adj_col = col;