diff --git a/example/main.c b/example/main.c index 441115d..dcdf15c 100644 --- a/example/main.c +++ b/example/main.c @@ -146,6 +146,65 @@ void custom_border_style_example(void) ft_destroy_table(table); } + +void colorfull_table(void) +{ + setlocale(LC_CTYPE, ""); + + ft_table_t *table = ft_create_table(); + ft_set_border_style(table, FT_DOUBLE_STYLE); + ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER); + + /* Filling table with data */ + ft_wwrite_ln(table, L"Test", L"Iterations", L"ms/op", L"Ticks", L"Passed"); + ft_wwrite_ln(table, L"n-body", L"1000", L"1.6", L"1,500,000", L"✔"); + ft_add_separator(table); + ft_wwrite_ln(table, L"regex-redux", L"1000", L"0.8", L"8,000,000"); + ft_wwrite_ln(table, L"", L"2500", L"3.9", L"27,000,000", L"✖"); + ft_wwrite_ln(table, L"", L"10000", L"12.5", L"96,800,000"); + ft_add_separator(table); + ft_wwrite_ln(table, L"mandelbrot", L"1000", L"8.1", L"89,000,000"); + ft_wwrite_ln(table, L"", L"2500", L"19.8", L"320,000,000", L"✔"); + ft_wwrite_ln(table, L"", L"10000", L"60.7", L"987,000,000"); + ft_add_separator(table); + ft_set_cell_span(table, 8, 0, 4); + ft_wwrite_ln(table, L"Total result", L"", L"", L"", L"✖"); + + + /* Setting text styles */ + ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_BOLD); + ft_set_cell_prop(table, 8, FT_ANY_COLUMN, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_BOLD); + ft_set_cell_prop(table, FT_ANY_ROW, 0, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_BOLD); + ft_set_cell_prop(table, FT_ANY_ROW, 4, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_BOLD); + ft_set_cell_prop(table, FT_ANY_ROW, FT_ANY_COLUMN, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_ITALIC); + + + /* Set alignment */ + ft_set_cell_prop(table, FT_ANY_ROW, 1, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_RIGHT); + ft_set_cell_prop(table, FT_ANY_ROW, 2, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_RIGHT); + ft_set_cell_prop(table, FT_ANY_ROW, 3, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_RIGHT); + ft_set_cell_prop(table, FT_ANY_ROW, 4, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_CENTER); + ft_set_cell_prop(table, 8, 0, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_CENTER); + + /* Set colors */ + ft_set_cell_prop(table, 1, 4, FT_CPROP_CONT_FG_COLOR, FT_COLOR_GREEN); + ft_set_cell_prop(table, 3, 4, FT_CPROP_CONT_FG_COLOR, FT_COLOR_RED); + ft_set_cell_prop(table, 6, 4, FT_CPROP_CONT_FG_COLOR, FT_COLOR_GREEN); + ft_set_cell_prop(table, 8, 4, FT_CPROP_CONT_FG_COLOR, FT_COLOR_RED); + ft_set_cell_prop(table, 3, 2, FT_CPROP_CONT_FG_COLOR, FT_COLOR_RED); + ft_set_cell_prop(table, 4, 3, FT_CPROP_CONT_BG_COLOR, FT_COLOR_LIGHT_RED); + ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_CONT_FG_COLOR, FT_COLOR_LIGHT_BLUE); + + const wchar_t *table_wstr = ft_to_wstring(table); + if (table_wstr) { + fwprintf(stderr, L"Table:\n%ls\n ", table_wstr); + } else { + fwprintf(stderr, L"Table conversion failed !!!\n "); + } + + ft_destroy_table(table); +} + int main(void) { base_example(); @@ -153,6 +212,7 @@ int main(void) fill_table_with_data_example(); complex_layout_example(); custom_border_style_example(); + colorfull_table(); int result = 0; diff --git a/lib/fort.c b/lib/fort.c index 0f09422..0d326b9 100644 --- a/lib/fort.c +++ b/lib/fort.c @@ -515,6 +515,9 @@ enum SeparatorItemPos { II_sip = 2, RH_sip = 3, + TI_sip = 4, + BI_sip = 5, + SepratorItemPosSize }; @@ -1314,6 +1317,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ "+", "-", "+", "+", \ + "+", "+", \ }, \ } @@ -1337,6 +1341,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ "+", "-", "+", "+", \ + "+", "+", \ }, \ } @@ -1360,6 +1365,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ " ", "-", " ", " ", \ + " ", " ", \ }, \ } @@ -1383,6 +1389,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ " ", "-", "-", " ", \ + "-", "-", \ }, \ } @@ -1406,6 +1413,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ ":", ".", ":", ":", \ + ":", ":", \ }, \ } @@ -1429,6 +1437,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ " ", " ", " ", " ", \ + " ", " ", \ }, \ } @@ -1453,6 +1462,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ "├", "─", "┼", "┤", \ + "┬", "┴", \ }, \ } @@ -1476,6 +1486,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ "├", "─", "┼", "┤", \ + "┬", "┴", \ }, \ } @@ -1500,6 +1511,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ "╠", "═", "╬", "╣", \ + "╦", "╩", \ }, \ } @@ -1524,6 +1536,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ "╠", "═", "╪", "╣", \ + "╤", "╧", \ }, \ } @@ -1548,6 +1561,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ "┣", "━", "╋", "┫", \ + "┳", "┻", \ }, \ } @@ -1571,6 +1585,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ "┣", "━", "┿", "┫", \ + "┯", "┷", \ }, \ } @@ -1594,6 +1609,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ "▌", "━", "╋", "▐", \ + "╋", "╋", \ }, \ } @@ -2989,6 +3005,7 @@ static void set_border_props_for_props(fort_table_properties_t *properties, cons } SEP_CHARS[LH_sip] = SEP_CHARS[RH_sip] = SEP_CHARS[II_sip] = header_border_chs->out_intersect_ch; + SEP_CHARS[TI_sip] = SEP_CHARS[BI_sip] = header_border_chs->out_intersect_ch; SEP_CHARS[IH_sip] = style->hor_separator_char; @@ -4518,9 +4535,17 @@ int print_row_separator(char *buffer, size_t buffer_sz, IV = &(context->table_properties->border_style.separator_chars[II_sip]); R = &(context->table_properties->border_style.separator_chars[RH_sip]); - IT = &(context->table_properties->border_style.separator_chars[II_sip]); - IB = &(context->table_properties->border_style.separator_chars[II_sip]); + IT = &(context->table_properties->border_style.separator_chars[TI_sip]); + IB = &(context->table_properties->border_style.separator_chars[BI_sip]); II = &(context->table_properties->border_style.separator_chars[IH_sip]); + + if (lower_row == NULL) { + L = &(*border_chars)[BL_bip]; + R = &(*border_chars)[BR_bip]; + } else if (upper_row == NULL) { + L = &(*border_chars)[TL_bip]; + R = &(*border_chars)[TR_bip]; + } } else { switch (separatorPos) { case TopSeparator: @@ -4693,9 +4718,17 @@ int wprint_row_separator(wchar_t *buffer, size_t buffer_sz, IV = &(context->table_properties->border_style.separator_chars[II_sip]); R = &(context->table_properties->border_style.separator_chars[RH_sip]); - IT = &(context->table_properties->border_style.separator_chars[II_sip]); - IB = &(context->table_properties->border_style.separator_chars[II_sip]); + IT = &(context->table_properties->border_style.separator_chars[TI_sip]); + IB = &(context->table_properties->border_style.separator_chars[BI_sip]); II = &(context->table_properties->border_style.separator_chars[IH_sip]); + + if (lower_row == NULL) { + L = &(*border_chars)[BL_bip]; + R = &(*border_chars)[BR_bip]; + } else if (upper_row == NULL) { + L = &(*border_chars)[TL_bip]; + R = &(*border_chars)[TR_bip]; + } } else { switch (separatorPos) { case TopSeparator: diff --git a/src/fort_impl.c b/src/fort_impl.c index 6893217..826e9f6 100644 --- a/src/fort_impl.c +++ b/src/fort_impl.c @@ -922,6 +922,7 @@ static void set_border_props_for_props(fort_table_properties_t *properties, cons } SEP_CHARS[LH_sip] = SEP_CHARS[RH_sip] = SEP_CHARS[II_sip] = header_border_chs->out_intersect_ch; + SEP_CHARS[TI_sip] = SEP_CHARS[BI_sip] = header_border_chs->out_intersect_ch; SEP_CHARS[IH_sip] = style->hor_separator_char; diff --git a/src/properties.c b/src/properties.c index 051ff32..1f6fa45 100644 --- a/src/properties.c +++ b/src/properties.c @@ -523,6 +523,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ "+", "-", "+", "+", \ + "+", "+", \ }, \ } @@ -546,6 +547,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ "+", "-", "+", "+", \ + "+", "+", \ }, \ } @@ -569,6 +571,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ " ", "-", " ", " ", \ + " ", " ", \ }, \ } @@ -592,6 +595,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ " ", "-", "-", " ", \ + "-", "-", \ }, \ } @@ -615,6 +619,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ ":", ".", ":", ":", \ + ":", ":", \ }, \ } @@ -638,6 +643,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ " ", " ", " ", " ", \ + " ", " ", \ }, \ } @@ -662,6 +668,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ "├", "─", "┼", "┤", \ + "┬", "┴", \ }, \ } @@ -685,6 +692,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ "├", "─", "┼", "┤", \ + "┬", "┴", \ }, \ } @@ -709,6 +717,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ "╠", "═", "╬", "╣", \ + "╦", "╩", \ }, \ } @@ -733,6 +742,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ "╠", "═", "╪", "╣", \ + "╤", "╧", \ }, \ } @@ -757,6 +767,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ "┣", "━", "╋", "┫", \ + "┳", "┻", \ }, \ } @@ -780,6 +791,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ "┣", "━", "┿", "┫", \ + "┯", "┷", \ }, \ } @@ -803,6 +815,7 @@ fort_status_t set_default_cell_property(uint32_t property, int value) /* separator_chars */ \ { \ "▌", "━", "╋", "▐", \ + "╋", "╋", \ }, \ } diff --git a/src/properties.h b/src/properties.h index 212b78c..094f999 100644 --- a/src/properties.h +++ b/src/properties.h @@ -142,6 +142,9 @@ enum SeparatorItemPos { II_sip = 2, RH_sip = 3, + TI_sip = 4, + BI_sip = 5, + SepratorItemPosSize }; diff --git a/src/row.c b/src/row.c index 5236fba..ccfa9b4 100644 --- a/src/row.c +++ b/src/row.c @@ -306,9 +306,17 @@ int print_row_separator(char *buffer, size_t buffer_sz, IV = &(context->table_properties->border_style.separator_chars[II_sip]); R = &(context->table_properties->border_style.separator_chars[RH_sip]); - IT = &(context->table_properties->border_style.separator_chars[II_sip]); - IB = &(context->table_properties->border_style.separator_chars[II_sip]); + IT = &(context->table_properties->border_style.separator_chars[TI_sip]); + IB = &(context->table_properties->border_style.separator_chars[BI_sip]); II = &(context->table_properties->border_style.separator_chars[IH_sip]); + + if (lower_row == NULL) { + L = &(*border_chars)[BL_bip]; + R = &(*border_chars)[BR_bip]; + } else if (upper_row == NULL) { + L = &(*border_chars)[TL_bip]; + R = &(*border_chars)[TR_bip]; + } } else { switch (separatorPos) { case TopSeparator: @@ -481,9 +489,17 @@ int wprint_row_separator(wchar_t *buffer, size_t buffer_sz, IV = &(context->table_properties->border_style.separator_chars[II_sip]); R = &(context->table_properties->border_style.separator_chars[RH_sip]); - IT = &(context->table_properties->border_style.separator_chars[II_sip]); - IB = &(context->table_properties->border_style.separator_chars[II_sip]); + IT = &(context->table_properties->border_style.separator_chars[TI_sip]); + IB = &(context->table_properties->border_style.separator_chars[BI_sip]); II = &(context->table_properties->border_style.separator_chars[IH_sip]); + + if (lower_row == NULL) { + L = &(*border_chars)[BL_bip]; + R = &(*border_chars)[BR_bip]; + } else if (upper_row == NULL) { + L = &(*border_chars)[TL_bip]; + R = &(*border_chars)[TR_bip]; + } } else { switch (separatorPos) { case TopSeparator: diff --git a/tests/bb_tests/test_table_border_style.c b/tests/bb_tests/test_table_border_style.c index e962ab5..ff712e5 100644 --- a/tests/bb_tests/test_table_border_style.c +++ b/tests/bb_tests/test_table_border_style.c @@ -128,6 +128,39 @@ void test_table_border_style(void) assert_str_equal(table_str, table_str_etalon); ft_destroy_table(table); } + + WHEN("Separator complex testing") { + table = ft_create_table(); + ft_set_border_style(table, FT_DOUBLE2_STYLE); + assert(table); + + ft_add_separator(table); + assert_true(ft_write_ln(table, "1", "2", "3") == FT_SUCCESS); + ft_add_separator(table); + assert_true(ft_write_ln(table, "1", "2", "3") == FT_SUCCESS); + ft_add_separator(table); + ft_set_cell_span(table, 2, 0, 2); + assert_true(ft_write_ln(table, "1", "2", "3") == FT_SUCCESS); + ft_add_separator(table); + ft_set_cell_span(table, 3, 1, 2); + assert_true(ft_write_ln(table, "1", "2", "3") == FT_SUCCESS); + ft_add_separator(table); + + const char *table_str = ft_to_string(table); + assert_true(table_str != NULL); + const char *table_str_etalon = + "╔═══╤═══╤═══╗\n" + "║ 1 │ 2 │ 3 ║\n" + "╠═══╪═══╪═══╣\n" + "║ 1 │ 2 │ 3 ║\n" + "╠═══╧═══╪═══╣\n" + "║ 1 │ 3 ║\n" + "╠═══╤═══╧═══╣\n" + "║ 1 │ 2 ║\n" + "╚═══╧═══════╝\n"; + assert_str_equal(table_str, table_str_etalon); + ft_destroy_table(table); + } }