[A] Added text styles

This commit is contained in:
seleznevae 2018-11-10 09:58:21 +03:00
parent 018ecbd383
commit c2c887f6c6
16 changed files with 1648 additions and 149 deletions

View File

@ -142,15 +142,16 @@ typedef struct fort_row fort_row_t;
/*typedef struct ft_table ft_table_t;*/
typedef struct separator separator_t;
enum CellType {
CommonCell,
GroupMasterCell,
GroupSlaveCell
};
enum request_geom_type {
VISIBLE_GEOMETRY,
INTERN_REPR_GEOMETRY
};
/*****************************************************************************
* LIBFORT helpers
@ -182,6 +183,15 @@ int wsnprint_n_string(wchar_t *buf, size_t length, size_t n, const char *str);
written += tmp; \
} while(0)
#define CHCK_RSLT_ADD_TO_INVISIBLE_WRITTEN(statement) \
do { \
tmp = statement; \
if (tmp < 0) {\
goto clear; \
} \
invisible_written += tmp; \
} while(0)
#define CHECK_NOT_NEGATIVE(x) \
do { if (x < 0) goto fort_fail; } while (0)
@ -339,11 +349,13 @@ FT_INTERNAL
size_t buffer_text_width(string_buffer_t *buffer);
FT_INTERNAL
int buffer_printf(string_buffer_t *buffer, size_t buffer_row, char *buf, size_t buf_len, const context_t *context);
int buffer_printf(string_buffer_t *buffer, size_t buffer_row, char *buf, size_t total_buf_len,
const context_t *context, const char *content_style_tag, const char *reset_content_style_tag);
#ifdef FT_HAVE_WCHAR
FT_INTERNAL
int buffer_wprintf(string_buffer_t *buffer, size_t buffer_row, wchar_t *buf, size_t buf_len, const context_t *context);
int buffer_wprintf(string_buffer_t *buffer, size_t buffer_row, wchar_t *buf, size_t total_buf_len,
const context_t *context, const char *content_style_tag, const char *reset_content_style_tag);
#endif /* FT_HAVE_WCHAR */
#endif /* STRING_BUFFER_H */
@ -368,6 +380,19 @@ int buffer_wprintf(string_buffer_t *buffer, size_t buffer_row, wchar_t *buf, siz
#define PROP_SET(ft_props, property) ((ft_props) |=(property))
#define PROP_UNSET(ft_props, property) ((ft_props) &= ~((uint32_t)property))
#define TEXT_STYLE_TAG_MAX_SIZE 64
void get_style_tag_for_cell(const fort_table_properties_t *props,
size_t row, size_t col, char *style_tag, size_t sz);
void get_reset_style_tag_for_cell(const fort_table_properties_t *props,
size_t row, size_t col, char *style_tag, size_t sz);
void get_style_tag_for_content(const fort_table_properties_t *props,
size_t row, size_t col, char *style_tag, size_t sz);
void get_reset_style_tag_for_content(const fort_table_properties_t *props,
size_t row, size_t col, char *style_tag, size_t sz);
struct fort_cell_props {
size_t cell_row;
size_t cell_col;
@ -380,6 +405,11 @@ struct fort_cell_props {
unsigned int cell_padding_right;
unsigned int cell_empty_string_height;
enum ft_row_type row_type;
unsigned int content_fg_color_number;
unsigned int content_bg_color_number;
unsigned int cell_bg_color_number;
unsigned int cell_text_style;
unsigned int content_text_style;
};
typedef struct fort_cell_props fort_cell_props_t;
@ -561,7 +591,7 @@ FT_INTERNAL
fort_cell_t *copy_cell(fort_cell_t *cell);
FT_INTERNAL
size_t hint_width_cell(const fort_cell_t *cell, const context_t *context);
size_t hint_width_cell(const fort_cell_t *cell, const context_t *context, enum request_geom_type geom);
FT_INTERNAL
size_t hint_height_cell(const fort_cell_t *cell, const context_t *context);
@ -730,10 +760,12 @@ fort_row_t *get_row_and_create_if_not_exists(ft_table_t *table, size_t row);
FT_INTERNAL
string_buffer_t *get_cur_str_buffer_and_create_if_not_exists(ft_table_t *table);
FT_INTERNAL
fort_status_t table_rows_and_cols_geometry(const ft_table_t *table,
size_t **col_width_arr_p, size_t *col_width_arr_sz,
size_t **row_height_arr_p, size_t *row_height_arr_sz);
size_t **row_height_arr_p, size_t *row_height_arr_sz,
enum request_geom_type geom);
FT_INTERNAL
fort_status_t table_geometry(const ft_table_t *table, size_t *height, size_t *width);
@ -749,11 +781,258 @@ fort_status_t table_geometry(const ft_table_t *table, size_t *height, size_t *wi
Begin of file "properties.c"
********************************************************/
/* #include "fort_utils.h" */ /* Commented by amalgamation script */
#include <assert.h>
/* #include "properties.h" */ /* Commented by amalgamation script */
/* #include "fort_utils.h" */ /* Commented by amalgamation script */
/* #include "vector.h" */ /* Commented by amalgamation script */
#define FT_RESET_COLOR "\033[0m"
const char *fg_colors[] = {
"",
"\033[30m",
"\033[31m",
"\033[32m",
"\033[33m",
"\033[34m",
"\033[35m",
"\033[36m",
"\033[37m",
"\033[90m",
"\033[91m",
"\033[92m",
"\033[93m",
"\033[94m",
"\033[95m",
"\033[96m",
"\033[97m",
};
const char *reset_fg_colors[] = {
"",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
};
const char *bg_colors[] = {
"",
"\033[40m",
"\033[41m",
"\033[42m",
"\033[43m",
"\033[44m",
"\033[45m",
"\033[46m",
"\033[47m",
"\033[100m",
"\033[101m",
"\033[102m",
"\033[103m",
"\033[104m",
"\033[105m",
"\033[106m",
"\033[107m",
};
const char *reset_bg_colors[] = {
"",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
};
const char *text_styles[] = {
"",
"\033[1m",
"\033[2m",
"\033[4m",
"\033[5m",
"\033[7m",
"\033[8m",
};
const char *reset_text_styles[] = {
"",
"\033[21m",
"\033[22m",
"\033[24m",
"\033[25m",
"\033[27m",
"\033[28m",
};
static const size_t n_fg_colors = sizeof(fg_colors) / sizeof(fg_colors[0]);
static const size_t n_bg_colors = sizeof(bg_colors) / sizeof(bg_colors[0]);
static const size_t n_styles = sizeof(text_styles) / sizeof(text_styles[0]);
void get_style_tag_for_cell(const fort_table_properties_t *props,
size_t row, size_t col, char *style_tag, size_t sz)
{
(void)sz;
unsigned bg_color_number = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CELL_BG_COLOR);
unsigned text_style = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CELL_TEXT_STYLE);
style_tag[0] = '\0';
if (text_style < n_styles) {
strcat(style_tag, text_styles[text_style]);
} else {
goto error;
}
if (bg_color_number < n_bg_colors) {
strcat(style_tag, bg_colors[bg_color_number]);
} else {
goto error;
}
return;
error:
// shouldn't be here
assert(0);
style_tag[0] = '\0';
return;
}
void get_reset_style_tag_for_cell(const fort_table_properties_t *props,
size_t row, size_t col, char *reset_style_tag, size_t sz)
{
(void)sz;
unsigned bg_color_number = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CELL_BG_COLOR);
unsigned text_style = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CELL_TEXT_STYLE);
reset_style_tag[0] = '\0';
if (text_style < n_styles) {
strcat(reset_style_tag, reset_text_styles[text_style]);
} else {
goto error;
}
if (bg_color_number < n_bg_colors) {
strcat(reset_style_tag, reset_bg_colors[bg_color_number]);
} else {
goto error;
}
return;
error:
// shouldn't be here
assert(0);
reset_style_tag[0] = '\0';
return;
}
void get_style_tag_for_content(const fort_table_properties_t *props,
size_t row, size_t col, char *style_tag, size_t sz)
{
(void)sz;
unsigned text_style = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CONT_TEXT_STYLE);
unsigned fg_color_number = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CONT_FG_COLOR);
unsigned bg_color_number = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CONT_BG_COLOR);
style_tag[0] = '\0';
if (text_style < n_styles) {
strcat(style_tag, text_styles[text_style]);
} else {
goto error;
}
if (fg_color_number < n_fg_colors) {
strcat(style_tag, fg_colors[fg_color_number]);
} else {
goto error;
}
if (bg_color_number < n_bg_colors) {
strcat(style_tag, bg_colors[bg_color_number]);
} else {
goto error;
}
return;
error:
// shouldn't be here
assert(0);
style_tag[0] = '\0';
return;
}
void get_reset_style_tag_for_content(const fort_table_properties_t *props,
size_t row, size_t col, char *reset_style_tag, size_t sz)
{
(void)sz;
unsigned text_style = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CONT_TEXT_STYLE);
unsigned fg_color_number = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CONT_FG_COLOR);
unsigned bg_color_number = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CONT_BG_COLOR);
reset_style_tag[0] = '\0';
if (text_style < n_styles) {
strcat(reset_style_tag, reset_text_styles[text_style]);
} else {
goto error;
}
if (fg_color_number < n_fg_colors) {
strcat(reset_style_tag, reset_fg_colors[fg_color_number]);
} else {
goto error;
}
if (bg_color_number < n_bg_colors) {
strcat(reset_style_tag, reset_bg_colors[bg_color_number]);
} else {
goto error;
}
return;
error:
// shouldn't be here
assert(0);
reset_style_tag[0] = '\0';
return;
}
/*****************************************************************************
* COLUMN PROPERTIES
* ***************************************************************************/
@ -765,7 +1044,8 @@ struct fort_cell_props g_default_cell_properties = {
/* properties */
FT_CPROP_MIN_WIDTH | FT_CPROP_TEXT_ALIGN | FT_CPROP_TOP_PADDING
| FT_CPROP_BOTTOM_PADDING | FT_CPROP_LEFT_PADDING | FT_CPROP_RIGHT_PADDING
| FT_CPROP_EMPTY_STR_HEIGHT,
| FT_CPROP_EMPTY_STR_HEIGHT | FT_CPROP_CONT_FG_COLOR | FT_CPROP_CELL_BG_COLOR
| FT_CPROP_CONT_BG_COLOR | FT_CPROP_CELL_TEXT_STYLE | FT_CPROP_CONT_TEXT_STYLE,
0, /* col_min_width */
FT_ALIGNED_LEFT, /* align */
@ -776,6 +1056,11 @@ struct fort_cell_props g_default_cell_properties = {
1, /* cell_empty_string_height */
FT_ROW_COMMON, /* row_type */
FT_COLOR_DEFAULT, /* content_fg_color_number */
FT_COLOR_DEFAULT, /* content_bg_color_number */
FT_COLOR_DEFAULT, /* cell_bg_color_number */
FT_TSTYLE_DEFAULT, /* cell_text_style */
FT_TSTYLE_DEFAULT, /* content_text_style */
};
static int get_prop_value_if_exists_otherwise_default(const struct fort_cell_props *cell_opts, uint32_t property)
@ -801,6 +1086,16 @@ static int get_prop_value_if_exists_otherwise_default(const struct fort_cell_pro
return cell_opts->cell_empty_string_height;
case FT_CPROP_ROW_TYPE:
return cell_opts->row_type;
case FT_CPROP_CONT_FG_COLOR:
return cell_opts->content_fg_color_number;
case FT_CPROP_CONT_BG_COLOR:
return cell_opts->content_bg_color_number;
case FT_CPROP_CELL_BG_COLOR:
return cell_opts->cell_bg_color_number;
case FT_CPROP_CELL_TEXT_STYLE:
return cell_opts->cell_text_style;
case FT_CPROP_CONT_TEXT_STYLE:
return cell_opts->content_text_style;
default:
/* todo: implement later */
exit(333);
@ -871,6 +1166,7 @@ FT_INTERNAL
int get_cell_property_value_hierarcial(const fort_table_properties_t *propertiess, size_t row, size_t column, uint32_t property)
{
assert(propertiess);
size_t row_origin = row;
const fort_cell_props_t *opt = NULL;
if (propertiess->cell_properties != NULL) {
@ -878,15 +1174,29 @@ int get_cell_property_value_hierarcial(const fort_table_properties_t *properties
opt = cget_cell_prop(propertiess->cell_properties, row, column);
if (opt != NULL && PROP_IS_SET(opt->properties, property))
break;
if (row != FT_ANY_ROW) {
if (row != FT_ANY_ROW && column != FT_ANY_COLUMN) {
row = FT_ANY_ROW;
continue;
}
if (column != FT_ANY_COLUMN) {
} else if (row == FT_ANY_ROW && column != FT_ANY_COLUMN) {
row = row_origin;
column = FT_ANY_COLUMN;
continue;
} else if (row != FT_ANY_ROW && column == FT_ANY_COLUMN) {
row = FT_ANY_ROW;
column = FT_ANY_COLUMN;
continue;
}
// if (row != FT_ANY_ROW) {
// row = FT_ANY_ROW;
// continue;
// }
// if (column != FT_ANY_COLUMN) {
// column = FT_ANY_COLUMN;
// continue;
// }
opt = NULL;
break;
}
@ -923,6 +1233,16 @@ static fort_status_t set_cell_property_impl(fort_cell_props_t *opt, uint32_t pro
opt->cell_empty_string_height = value;
} else if (PROP_IS_SET(property, FT_CPROP_ROW_TYPE)) {
opt->row_type = (enum ft_row_type)value;
} else if (PROP_IS_SET(property, FT_CPROP_CONT_FG_COLOR)) {
opt->content_fg_color_number = value;
} else if (PROP_IS_SET(property, FT_CPROP_CONT_BG_COLOR)) {
opt->content_bg_color_number = value;
} else if (PROP_IS_SET(property, FT_CPROP_CELL_BG_COLOR)) {
opt->cell_bg_color_number = value;
} else if (PROP_IS_SET(property, FT_CPROP_CELL_TEXT_STYLE)) {
opt->cell_text_style = value;
} else if (PROP_IS_SET(property, FT_CPROP_CONT_TEXT_STYLE)) {
opt->content_text_style = value;
}
return FT_SUCCESS;
@ -1569,7 +1889,8 @@ fort_status_t get_table_sizes(const ft_table_t *table, size_t *rows, size_t *col
FT_INTERNAL
fort_status_t table_rows_and_cols_geometry(const ft_table_t *table,
size_t **col_width_arr_p, size_t *col_width_arr_sz,
size_t **row_height_arr_p, size_t *row_height_arr_sz)
size_t **row_height_arr_p, size_t *row_height_arr_sz,
enum request_geom_type geom)
{
if (table == NULL) {
return FT_ERROR;
@ -1606,7 +1927,7 @@ fort_status_t table_rows_and_cols_geometry(const ft_table_t *table,
if (cell) {
switch (get_cell_type(cell)) {
case CommonCell:
col_width_arr[col] = MAX(col_width_arr[col], hint_width_cell(cell, &context));
col_width_arr[col] = MAX(col_width_arr[col], hint_width_cell(cell, &context, geom));
break;
case GroupMasterCell:
combined_cells_found = 1;
@ -1631,7 +1952,7 @@ fort_status_t table_rows_and_cols_geometry(const ft_table_t *table,
context.row = row;
if (cell) {
if (get_cell_type(cell) == GroupMasterCell) {
size_t hint_width = hint_width_cell(cell, &context);
size_t hint_width = hint_width_cell(cell, &context, geom);
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];
@ -1690,7 +2011,7 @@ fort_status_t table_geometry(const ft_table_t *table, size_t *height, size_t *wi
size_t *col_width_arr = NULL;
size_t *row_height_arr = NULL;
int status = table_rows_and_cols_geometry(table, &col_width_arr, &cols, &row_height_arr, &rows);
int status = table_rows_and_cols_geometry(table, &col_width_arr, &cols, &row_height_arr, &rows, INTERN_REPR_GEOMETRY);
if (FT_IS_ERROR(status))
return status;
@ -2347,7 +2668,7 @@ const char *ft_to_string(const ft_table_t *table)
size_t rows = 0;
size_t *col_width_arr = NULL;
size_t *row_height_arr = NULL;
status = table_rows_and_cols_geometry(table, &col_width_arr, &cols, &row_height_arr, &rows);
status = table_rows_and_cols_geometry(table, &col_width_arr, &cols, &row_height_arr, &rows, VISIBLE_GEOMETRY);
if (FT_IS_ERROR(status))
return NULL;
@ -2451,7 +2772,7 @@ const wchar_t *ft_to_wstring(const ft_table_t *table)
size_t rows = 0;
size_t *col_width_arr = NULL;
size_t *row_height_arr = NULL;
status = table_rows_and_cols_geometry(table, &col_width_arr, &cols, &row_height_arr, &rows);
status = table_rows_and_cols_geometry(table, &col_width_arr, &cols, &row_height_arr, &rows, VISIBLE_GEOMETRY);
if (rows == 0)
return EMPTY_STRING;
@ -3353,7 +3674,8 @@ size_t buffer_text_width(string_buffer_t *buffer)
FT_INTERNAL
int buffer_printf(string_buffer_t *buffer, size_t buffer_row, char *buf, size_t buf_len, const context_t *context)
int buffer_printf(string_buffer_t *buffer, size_t buffer_row, char *buf, size_t total_buf_len,
const context_t *context, const char *content_style_tag, const char *reset_content_style_tag)
{
#define CHAR_TYPE char
#define NULL_CHAR '\0'
@ -3367,6 +3689,8 @@ int buffer_printf(string_buffer_t *buffer, size_t buffer_row, char *buf, size_t
#define STR_N_SUBSTRING str_n_substring
#define STR_ITER_WIDTH str_iter_width
size_t buf_len = total_buf_len - strlen(content_style_tag) - strlen(reset_content_style_tag);
if (buffer == NULL || buffer->str.data == NULL
|| buffer_row >= buffer_text_height(buffer) || buf_len == 0) {
return -1;
@ -3404,7 +3728,7 @@ int buffer_printf(string_buffer_t *buffer, size_t buffer_row, char *buf, size_t
const CHAR_TYPE *end = NULL;
CHAR_TYPE old_value;
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, buf_len - written, left, SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, left, SPACE_CHAR));
STR_N_SUBSTRING(buffer->BUFFER_STR, NEWLINE_CHAR, buffer_row, &beg, &end);
if (beg == NULL || end == NULL)
@ -3416,10 +3740,13 @@ int buffer_printf(string_buffer_t *buffer, size_t buffer_row, char *buf, size_t
if (str_it_width < 0 || content_width < (size_t)str_it_width)
return - 1;
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINTF(buf + written, buf_len - written, SNPRINTF_FMT_STR, (int)(end - beg), beg));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, 1, content_style_tag));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINTF(buf + written, total_buf_len - written, SNPRINTF_FMT_STR, (int)(end - beg), beg));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, 1, reset_content_style_tag));
*(CHAR_TYPE *)end = old_value;
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, buf_len - written, (content_width - (size_t)str_it_width), SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, buf_len - written, right, SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, (content_width - (size_t)str_it_width), SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, right, SPACE_CHAR));
return written;
clear:
@ -3441,7 +3768,8 @@ clear:
#ifdef FT_HAVE_WCHAR
FT_INTERNAL
int buffer_wprintf(string_buffer_t *buffer, size_t buffer_row, wchar_t *buf, size_t buf_len, const context_t *context)
int buffer_wprintf(string_buffer_t *buffer, size_t buffer_row, wchar_t *buf, size_t total_buf_len,
const context_t *context, const char *content_style_tag, const char *reset_content_style_tag)
{
#define CHAR_TYPE wchar_t
#define NULL_CHAR L'\0'
@ -3455,6 +3783,8 @@ int buffer_wprintf(string_buffer_t *buffer, size_t buffer_row, wchar_t *buf, siz
#define STR_N_SUBSTRING wstr_n_substring
#define STR_ITER_WIDTH wcs_iter_width
size_t buf_len = total_buf_len - strlen(content_style_tag) - strlen(reset_content_style_tag);
if (buffer == NULL || buffer->str.data == NULL
|| buffer_row >= buffer_text_height(buffer) || buf_len == 0) {
return -1;
@ -3492,7 +3822,7 @@ int buffer_wprintf(string_buffer_t *buffer, size_t buffer_row, wchar_t *buf, siz
const CHAR_TYPE *end = NULL;
CHAR_TYPE old_value;
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, buf_len - written, left, SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, left, SPACE_CHAR));
STR_N_SUBSTRING(buffer->BUFFER_STR, NEWLINE_CHAR, buffer_row, &beg, &end);
if (beg == NULL || end == NULL)
@ -3504,10 +3834,13 @@ int buffer_wprintf(string_buffer_t *buffer, size_t buffer_row, wchar_t *buf, siz
if (str_it_width < 0 || content_width < (size_t)str_it_width)
return - 1;
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINTF(buf + written, buf_len - written, SNPRINTF_FMT_STR, (int)(end - beg), beg));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, 1, content_style_tag));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINTF(buf + written, total_buf_len - written, SNPRINTF_FMT_STR, (int)(end - beg), beg));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, 1, reset_content_style_tag));
*(CHAR_TYPE *)end = old_value;
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, buf_len - written, (content_width - (size_t)str_it_width), SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, buf_len - written, right, SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, (content_width - (size_t)str_it_width), SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, right, SPACE_CHAR));
return written;
clear:
@ -3752,6 +4085,9 @@ int snprint_n_strings(char *buf, size_t length, size_t n, const char *str)
if (n * str_len > INT_MAX)
return -1;
if (str_len == 0)
return 0;
int status = snprintf(buf, length, "%0*d", (int)(n * str_len), 0);
if (status < 0)
return status;
@ -3797,8 +4133,36 @@ int wsnprint_n_string(wchar_t *buf, size_t length, size_t n, const char *str)
/* This function doesn't work properly with multibyte characters
* so it is better return an error in this case
*/
if (str_len > 1)
return -1;
if (str_len > 1) {
const unsigned char *p = (const unsigned char *)str;
while (*p) {
if (*p <= 127)
p++;
else {
const int SIZE = 64;
wchar_t wcs[SIZE];
const char *ptr = str;
int length;
length = mbsrtowcs(wcs, (const char **)&ptr, SIZE, NULL);
wcs[length] = L'\0';
if (length > 1) {
return -1;
} else {
swprintf(buf, length, L"%0*d", (int)(n * str_len), 0);
int k = n;
while (k) {
*buf = *wcs;
++buf;
--k;
}
buf[n] = L'\0';
return n;
}
// return -1;
}
}
}
if (length <= n * str_len)
return -1;
@ -3806,12 +4170,13 @@ int wsnprint_n_string(wchar_t *buf, size_t length, size_t n, const char *str)
if (n == 0)
return 0;
/* To ensure valid return value it is safely not print such big strings */
if (n * str_len > INT_MAX)
return -1;
if (str_len == 0)
return 0;
int status = swprintf(buf, length, L"%0*d", (int)(n * str_len), 0);
if (status < 0)
return status;
@ -5245,9 +5610,8 @@ enum CellType get_cell_type(const fort_cell_t *cell)
return cell->cell_type;
}
FT_INTERNAL
size_t hint_width_cell(const fort_cell_t *cell, const context_t *context)
size_t hint_width_cell(const fort_cell_t *cell, const context_t *context, enum request_geom_type geom)
{
/* todo:
* At the moment min width includes paddings. Maybe it is better that min width weren't include
@ -5263,6 +5627,25 @@ size_t hint_width_cell(const fort_cell_t *cell, const context_t *context)
result += buffer_text_width(cell->str_buffer);
}
result = MAX(result, (size_t)get_cell_property_value_hierarcial(context->table_properties, context->row, context->column, FT_CPROP_MIN_WIDTH));
if (geom == INTERN_REPR_GEOMETRY) {
char cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_style_tag_for_cell(context->table_properties, context->row, context->column, cell_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
result += strlen(cell_style_tag);
char reset_cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_reset_style_tag_for_cell(context->table_properties, context->row, context->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(context->table_properties, context->row, context->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(context->table_properties, context->row, context->column, reset_content_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
result += strlen(reset_content_style_tag);
}
return result;
}
@ -5287,14 +5670,12 @@ FT_INTERNAL
int cell_printf(fort_cell_t *cell, size_t row, char *buf, size_t buf_len, const context_t *context)
{
const char *space_char = " ";
int (*buffer_printf_)(string_buffer_t *, size_t, char *, size_t, const context_t *) = buffer_printf;
int (*buffer_printf_)(string_buffer_t *, size_t, char *, size_t, const context_t *, const char *, const char *) = buffer_printf;
// int (*snprint_n_chars_)(char *, size_t, size_t, char) = snprint_n_chars;
int (*snprint_n_strings_)(char *, size_t, size_t, const char *) = snprint_n_strings;
if (cell == NULL || buf_len == 0
|| (buf_len <= hint_width_cell(cell, context))) {
|| (buf_len <= hint_width_cell(cell, context, VISIBLE_GEOMETRY))) {
return -1;
}
@ -5302,30 +5683,83 @@ int cell_printf(fort_cell_t *cell, size_t row, char *buf, size_t buf_len, const
unsigned int cell_padding_left = get_cell_property_value_hierarcial(context->table_properties, context->row, context->column, FT_CPROP_LEFT_PADDING);
unsigned int cell_padding_right = get_cell_property_value_hierarcial(context->table_properties, context->row, context->column, FT_CPROP_RIGHT_PADDING);
int written = 0;
int invisible_written = 0;
int tmp = 0;
// int left = cell_padding_left;
// int right = cell_padding_right;
/* todo: Dirty hack with changing buf_len! need refactoring. */
/* Also maybe it is better to move all struff with colors to buffers? */
char cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_style_tag_for_cell(context->table_properties, context->row, context->column, cell_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
buf_len += strlen(cell_style_tag);
char reset_cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_reset_style_tag_for_cell(context->table_properties, context->row, context->column, reset_cell_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
buf_len += strlen(reset_cell_style_tag);
char content_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_style_tag_for_content(context->table_properties, context->row, context->column, content_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
buf_len += strlen(content_style_tag);
char reset_content_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_reset_style_tag_for_content(context->table_properties, context->row, context->column, reset_content_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
buf_len += strlen(reset_content_style_tag);
/* CELL_STYLE_T LEFT_PADDING CONTENT_STYLE_T CONTENT RESET_CONTENT_STYLE_T RIGHT_PADDING RESET_CELL_STYLE_T
* | | | | | | | |
* L1 R1
* L2 R2
* L3 R3
*/
size_t L2 = cell_padding_left;
size_t R2 = cell_padding_right;
size_t R3 = strlen(reset_cell_style_tag);
#define TOTAL_WRITTEN (written + invisible_written)
#define RIGHT (cell_padding_right + extra_right)
#define WRITE_CELL_STYLE_TAG CHCK_RSLT_ADD_TO_INVISIBLE_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, 1, cell_style_tag))
#define WRITE_RESET_CELL_STYLE_TAG CHCK_RSLT_ADD_TO_INVISIBLE_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, 1, reset_cell_style_tag))
#define WRITE_CONTENT_STYLE_TAG CHCK_RSLT_ADD_TO_INVISIBLE_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, 1, content_style_tag))
#define WRITE_RESET_CONTENT_STYLE_TAG CHCK_RSLT_ADD_TO_INVISIBLE_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, 1, reset_content_style_tag))
if (row >= hint_height_cell(cell, context)
|| row < cell_padding_top
|| row >= (cell_padding_top + buffer_text_height(cell->str_buffer))) {
return snprint_n_strings_(buf, buf_len, buf_len - 1, space_char);
WRITE_CELL_STYLE_TAG;
WRITE_CONTENT_STYLE_TAG;
WRITE_RESET_CONTENT_STYLE_TAG;
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len, buf_len - 1 - TOTAL_WRITTEN - R3, space_char));
WRITE_RESET_CELL_STYLE_TAG;
return TOTAL_WRITTEN;
}
WRITE_CELL_STYLE_TAG;
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, L2, space_char));
if (cell->str_buffer) {
CHCK_RSLT_ADD_TO_WRITTEN(buffer_printf_(cell->str_buffer, row - cell_padding_top, buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN - R2 - R3, context, content_style_tag, reset_content_style_tag));
} else {
WRITE_CONTENT_STYLE_TAG;
WRITE_RESET_CONTENT_STYLE_TAG;
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN - R2 - R3, space_char));
}
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, R2, space_char));
WRITE_RESET_CELL_STYLE_TAG;
int written = 0;
int tmp = 0;
int left = cell_padding_left;
int right = cell_padding_right;
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + written, buf_len - written, left, space_char));
if (cell->str_buffer)
CHCK_RSLT_ADD_TO_WRITTEN(buffer_printf_(cell->str_buffer, row - cell_padding_top, buf + written, buf_len - written - right, context));
else
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + written, buf_len - written, buf_len - written - right, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + written, buf_len - written, right, space_char));
return written;
return TOTAL_WRITTEN;
clear:
return -1;
#undef WRITE_CELL_STYLE_TAG
#undef WRITE_RESET_CELL_STYLE_TAG
#undef WRITE_CONTENT_STYLE_TAG
#undef WRITE_RESET_CONTENT_STYLE_TAG
#undef TOTAL_WRITTEN
#undef RIGHT
}
#ifdef FT_HAVE_WCHAR
@ -5333,14 +5767,12 @@ FT_INTERNAL
int cell_wprintf(fort_cell_t *cell, size_t row, wchar_t *buf, size_t buf_len, const context_t *context)
{
const char *space_char = " ";
int (*buffer_printf_)(string_buffer_t *, size_t, wchar_t *, size_t, const context_t *) = buffer_wprintf;
int (*buffer_printf_)(string_buffer_t *, size_t, wchar_t *, size_t, const context_t *, const char *, const char *) = buffer_wprintf;
// int (*snprint_n_chars_)(wchar_t *, size_t, size_t, wchar_t) = wsnprint_n_chars;
int (*snprint_n_strings_)(wchar_t *, size_t, size_t, const char *) = wsnprint_n_string;
if (cell == NULL || buf_len == 0
|| (buf_len <= hint_width_cell(cell, context))) {
|| (buf_len <= hint_width_cell(cell, context, VISIBLE_GEOMETRY))) {
return -1;
}
@ -5348,29 +5780,81 @@ int cell_wprintf(fort_cell_t *cell, size_t row, wchar_t *buf, size_t buf_len, co
unsigned int cell_padding_left = get_cell_property_value_hierarcial(context->table_properties, context->row, context->column, FT_CPROP_LEFT_PADDING);
unsigned int cell_padding_right = get_cell_property_value_hierarcial(context->table_properties, context->row, context->column, FT_CPROP_RIGHT_PADDING);
int written = 0;
int invisible_written = 0;
int tmp = 0;
/* todo: Dirty hack with changing buf_len! need refactoring. */
/* Also maybe it is better to move all struff with colors to buffers? */
char cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_style_tag_for_cell(context->table_properties, context->row, context->column, cell_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
buf_len += strlen(cell_style_tag);
char reset_cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_reset_style_tag_for_cell(context->table_properties, context->row, context->column, reset_cell_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
buf_len += strlen(reset_cell_style_tag);
char content_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_style_tag_for_content(context->table_properties, context->row, context->column, content_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
buf_len += strlen(content_style_tag);
char reset_content_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_reset_style_tag_for_content(context->table_properties, context->row, context->column, reset_content_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
buf_len += strlen(reset_content_style_tag);
/* CELL_STYLE_T LEFT_PADDING CONTENT_STYLE_T CONTENT RESET_CONTENT_STYLE_T RIGHT_PADDING RESET_CELL_STYLE_T
* | | | | | | | |
* L1 R1
* L2 R2
* L3 R3
*/
size_t L2 = cell_padding_left;
size_t R2 = cell_padding_right;
size_t R3 = strlen(reset_cell_style_tag);
#define TOTAL_WRITTEN (written + invisible_written)
#define RIGHT (right + extra_right)
#define WRITE_CELL_STYLE_TAG CHCK_RSLT_ADD_TO_INVISIBLE_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, 1, cell_style_tag))
#define WRITE_RESET_CELL_STYLE_TAG CHCK_RSLT_ADD_TO_INVISIBLE_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, 1, reset_cell_style_tag))
#define WRITE_CONTENT_STYLE_TAG CHCK_RSLT_ADD_TO_INVISIBLE_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, 1, content_style_tag))
#define WRITE_RESET_CONTENT_STYLE_TAG CHCK_RSLT_ADD_TO_INVISIBLE_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, 1, reset_content_style_tag))
if (row >= hint_height_cell(cell, context)
|| row < cell_padding_top
|| row >= (cell_padding_top + buffer_text_height(cell->str_buffer))) {
return snprint_n_strings_(buf, buf_len, buf_len - 1, space_char);
WRITE_CELL_STYLE_TAG;
WRITE_CONTENT_STYLE_TAG;
WRITE_RESET_CONTENT_STYLE_TAG;
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len, buf_len - 1 - TOTAL_WRITTEN - R3, space_char));
WRITE_RESET_CELL_STYLE_TAG;
return TOTAL_WRITTEN;
}
int written = 0;
int tmp = 0;
int left = cell_padding_left;
int right = cell_padding_right;
WRITE_CELL_STYLE_TAG;
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, L2, space_char));
if (cell->str_buffer) {
CHCK_RSLT_ADD_TO_WRITTEN(buffer_printf_(cell->str_buffer, row - cell_padding_top, buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN - R2 - R3, context, content_style_tag, reset_content_style_tag));
} else {
WRITE_CONTENT_STYLE_TAG;
WRITE_RESET_CONTENT_STYLE_TAG;
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN - R2 - R3, space_char));
}
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, R2, space_char));
WRITE_RESET_CELL_STYLE_TAG;
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + written, buf_len - written, left, space_char));
if (cell->str_buffer)
CHCK_RSLT_ADD_TO_WRITTEN(buffer_printf_(cell->str_buffer, row - cell_padding_top, buf + written, buf_len - written - right, context));
else
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + written, buf_len - written, buf_len - written - right, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + written, buf_len - written, right, space_char));
return written;
return TOTAL_WRITTEN;
clear:
return -1;
#undef WRITE_CELL_STYLE_TAG
#undef WRITE_RESET_CELL_STYLE_TAG
#undef WRITE_CONTENT_STYLE_TAG
#undef WRITE_RESET_CONTENT_STYLE_TAG
#undef TOTAL_WRITTEN
#undef RIGHT
}
#endif

View File

@ -683,9 +683,50 @@ int ft_set_border_style(ft_table_t *table, const struct ft_border_style *style);
#define FT_CPROP_RIGHT_PADDING (0x01U << 5) /**< Right padding for cell content */
#define FT_CPROP_EMPTY_STR_HEIGHT (0x01U << 6) /**< Height of empty cell */
#define FT_CPROP_ROW_TYPE (0x01U << 7) /**< Row type */
#define FT_CPROP_CONT_FG_COLOR (0x01U << 8) /**< Cell content foreground text color */
#define FT_CPROP_CELL_BG_COLOR (0x01U << 9) /**< Cell background color */
#define FT_CPROP_CONT_BG_COLOR (0x01U << 10) /**< Cell content background color */
#define FT_CPROP_CELL_TEXT_STYLE (0x01U << 11) /**< Cell text style */
#define FT_CPROP_CONT_TEXT_STYLE (0x01U << 12) /**< Cell content text style */
/** @} */
/**
* @name Colors.
* @{
*/
#define FT_COLOR_DEFAULT 0
#define FT_COLOR_BLACK 1
#define FT_COLOR_RED 2
#define FT_COLOR_GREEN 3
#define FT_COLOR_YELLOW 4
#define FT_COLOR_BLUE 5
#define FT_COLOR_MAGENTA 6
#define FT_COLOR_CYAN 7
#define FT_COLOR_LIGHT_GRAY 8
#define FT_COLOR_DARK_GRAY 9
#define FT_COLOR_LIGHT_RED 10
#define FT_COLOR_LIGHT_GREEN 11
#define FT_COLOR_LIGHT_YELLOW 12
#define FT_COLOR_LIGHT_BLUE 13
#define FT_COLOR_LIGHT_MAGENTA 15
#define FT_COLOR_LIGHT_CYAN 16
#define FT_COLOR_LIGHT_WHYTE 17
/** @} */
/**
* @name Text styles.
* @{
*/
#define FT_TSTYLE_DEFAULT 0
#define FT_TSTYLE_BOLD 1
#define FT_TSTYLE_DIM 2
#define FT_TSTYLE_UNDERLINED 3
#define FT_TSTYLE_BLINK 4
#define FT_TSTYLE_INVERTED 5
#define FT_TSTYLE_HIDDEN 6
/** @} */
/**
* Alignment of cell content.

View File

@ -62,9 +62,8 @@ enum CellType get_cell_type(const fort_cell_t *cell)
return cell->cell_type;
}
FT_INTERNAL
size_t hint_width_cell(const fort_cell_t *cell, const context_t *context)
size_t hint_width_cell(const fort_cell_t *cell, const context_t *context, enum request_geom_type geom)
{
/* todo:
* At the moment min width includes paddings. Maybe it is better that min width weren't include
@ -80,6 +79,25 @@ size_t hint_width_cell(const fort_cell_t *cell, const context_t *context)
result += buffer_text_width(cell->str_buffer);
}
result = MAX(result, (size_t)get_cell_property_value_hierarcial(context->table_properties, context->row, context->column, FT_CPROP_MIN_WIDTH));
if (geom == INTERN_REPR_GEOMETRY) {
char cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_style_tag_for_cell(context->table_properties, context->row, context->column, cell_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
result += strlen(cell_style_tag);
char reset_cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_reset_style_tag_for_cell(context->table_properties, context->row, context->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(context->table_properties, context->row, context->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(context->table_properties, context->row, context->column, reset_content_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
result += strlen(reset_content_style_tag);
}
return result;
}
@ -104,14 +122,12 @@ FT_INTERNAL
int cell_printf(fort_cell_t *cell, size_t row, char *buf, size_t buf_len, const context_t *context)
{
const char *space_char = " ";
int (*buffer_printf_)(string_buffer_t *, size_t, char *, size_t, const context_t *) = buffer_printf;
int (*buffer_printf_)(string_buffer_t *, size_t, char *, size_t, const context_t *, const char *, const char *) = buffer_printf;
// int (*snprint_n_chars_)(char *, size_t, size_t, char) = snprint_n_chars;
int (*snprint_n_strings_)(char *, size_t, size_t, const char *) = snprint_n_strings;
if (cell == NULL || buf_len == 0
|| (buf_len <= hint_width_cell(cell, context))) {
|| (buf_len <= hint_width_cell(cell, context, VISIBLE_GEOMETRY))) {
return -1;
}
@ -119,30 +135,83 @@ int cell_printf(fort_cell_t *cell, size_t row, char *buf, size_t buf_len, const
unsigned int cell_padding_left = get_cell_property_value_hierarcial(context->table_properties, context->row, context->column, FT_CPROP_LEFT_PADDING);
unsigned int cell_padding_right = get_cell_property_value_hierarcial(context->table_properties, context->row, context->column, FT_CPROP_RIGHT_PADDING);
int written = 0;
int invisible_written = 0;
int tmp = 0;
// int left = cell_padding_left;
// int right = cell_padding_right;
/* todo: Dirty hack with changing buf_len! need refactoring. */
/* Also maybe it is better to move all struff with colors to buffers? */
char cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_style_tag_for_cell(context->table_properties, context->row, context->column, cell_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
buf_len += strlen(cell_style_tag);
char reset_cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_reset_style_tag_for_cell(context->table_properties, context->row, context->column, reset_cell_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
buf_len += strlen(reset_cell_style_tag);
char content_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_style_tag_for_content(context->table_properties, context->row, context->column, content_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
buf_len += strlen(content_style_tag);
char reset_content_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_reset_style_tag_for_content(context->table_properties, context->row, context->column, reset_content_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
buf_len += strlen(reset_content_style_tag);
/* CELL_STYLE_T LEFT_PADDING CONTENT_STYLE_T CONTENT RESET_CONTENT_STYLE_T RIGHT_PADDING RESET_CELL_STYLE_T
* | | | | | | | |
* L1 R1
* L2 R2
* L3 R3
*/
size_t L2 = cell_padding_left;
size_t R2 = cell_padding_right;
size_t R3 = strlen(reset_cell_style_tag);
#define TOTAL_WRITTEN (written + invisible_written)
#define RIGHT (cell_padding_right + extra_right)
#define WRITE_CELL_STYLE_TAG CHCK_RSLT_ADD_TO_INVISIBLE_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, 1, cell_style_tag))
#define WRITE_RESET_CELL_STYLE_TAG CHCK_RSLT_ADD_TO_INVISIBLE_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, 1, reset_cell_style_tag))
#define WRITE_CONTENT_STYLE_TAG CHCK_RSLT_ADD_TO_INVISIBLE_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, 1, content_style_tag))
#define WRITE_RESET_CONTENT_STYLE_TAG CHCK_RSLT_ADD_TO_INVISIBLE_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, 1, reset_content_style_tag))
if (row >= hint_height_cell(cell, context)
|| row < cell_padding_top
|| row >= (cell_padding_top + buffer_text_height(cell->str_buffer))) {
return snprint_n_strings_(buf, buf_len, buf_len - 1, space_char);
WRITE_CELL_STYLE_TAG;
WRITE_CONTENT_STYLE_TAG;
WRITE_RESET_CONTENT_STYLE_TAG;
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len, buf_len - 1 - TOTAL_WRITTEN - R3, space_char));
WRITE_RESET_CELL_STYLE_TAG;
return TOTAL_WRITTEN;
}
WRITE_CELL_STYLE_TAG;
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, L2, space_char));
if (cell->str_buffer) {
CHCK_RSLT_ADD_TO_WRITTEN(buffer_printf_(cell->str_buffer, row - cell_padding_top, buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN - R2 - R3, context, content_style_tag, reset_content_style_tag));
} else {
WRITE_CONTENT_STYLE_TAG;
WRITE_RESET_CONTENT_STYLE_TAG;
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN - R2 - R3, space_char));
}
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, R2, space_char));
WRITE_RESET_CELL_STYLE_TAG;
int written = 0;
int tmp = 0;
int left = cell_padding_left;
int right = cell_padding_right;
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + written, buf_len - written, left, space_char));
if (cell->str_buffer)
CHCK_RSLT_ADD_TO_WRITTEN(buffer_printf_(cell->str_buffer, row - cell_padding_top, buf + written, buf_len - written - right, context));
else
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + written, buf_len - written, buf_len - written - right, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + written, buf_len - written, right, space_char));
return written;
return TOTAL_WRITTEN;
clear:
return -1;
#undef WRITE_CELL_STYLE_TAG
#undef WRITE_RESET_CELL_STYLE_TAG
#undef WRITE_CONTENT_STYLE_TAG
#undef WRITE_RESET_CONTENT_STYLE_TAG
#undef TOTAL_WRITTEN
#undef RIGHT
}
#ifdef FT_HAVE_WCHAR
@ -150,14 +219,12 @@ FT_INTERNAL
int cell_wprintf(fort_cell_t *cell, size_t row, wchar_t *buf, size_t buf_len, const context_t *context)
{
const char *space_char = " ";
int (*buffer_printf_)(string_buffer_t *, size_t, wchar_t *, size_t, const context_t *) = buffer_wprintf;
int (*buffer_printf_)(string_buffer_t *, size_t, wchar_t *, size_t, const context_t *, const char *, const char *) = buffer_wprintf;
// int (*snprint_n_chars_)(wchar_t *, size_t, size_t, wchar_t) = wsnprint_n_chars;
int (*snprint_n_strings_)(wchar_t *, size_t, size_t, const char *) = wsnprint_n_string;
if (cell == NULL || buf_len == 0
|| (buf_len <= hint_width_cell(cell, context))) {
|| (buf_len <= hint_width_cell(cell, context, VISIBLE_GEOMETRY))) {
return -1;
}
@ -165,29 +232,81 @@ int cell_wprintf(fort_cell_t *cell, size_t row, wchar_t *buf, size_t buf_len, co
unsigned int cell_padding_left = get_cell_property_value_hierarcial(context->table_properties, context->row, context->column, FT_CPROP_LEFT_PADDING);
unsigned int cell_padding_right = get_cell_property_value_hierarcial(context->table_properties, context->row, context->column, FT_CPROP_RIGHT_PADDING);
int written = 0;
int invisible_written = 0;
int tmp = 0;
/* todo: Dirty hack with changing buf_len! need refactoring. */
/* Also maybe it is better to move all struff with colors to buffers? */
char cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_style_tag_for_cell(context->table_properties, context->row, context->column, cell_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
buf_len += strlen(cell_style_tag);
char reset_cell_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_reset_style_tag_for_cell(context->table_properties, context->row, context->column, reset_cell_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
buf_len += strlen(reset_cell_style_tag);
char content_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_style_tag_for_content(context->table_properties, context->row, context->column, content_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
buf_len += strlen(content_style_tag);
char reset_content_style_tag[TEXT_STYLE_TAG_MAX_SIZE];
get_reset_style_tag_for_content(context->table_properties, context->row, context->column, reset_content_style_tag, TEXT_STYLE_TAG_MAX_SIZE);
buf_len += strlen(reset_content_style_tag);
/* CELL_STYLE_T LEFT_PADDING CONTENT_STYLE_T CONTENT RESET_CONTENT_STYLE_T RIGHT_PADDING RESET_CELL_STYLE_T
* | | | | | | | |
* L1 R1
* L2 R2
* L3 R3
*/
size_t L2 = cell_padding_left;
size_t R2 = cell_padding_right;
size_t R3 = strlen(reset_cell_style_tag);
#define TOTAL_WRITTEN (written + invisible_written)
#define RIGHT (right + extra_right)
#define WRITE_CELL_STYLE_TAG CHCK_RSLT_ADD_TO_INVISIBLE_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, 1, cell_style_tag))
#define WRITE_RESET_CELL_STYLE_TAG CHCK_RSLT_ADD_TO_INVISIBLE_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, 1, reset_cell_style_tag))
#define WRITE_CONTENT_STYLE_TAG CHCK_RSLT_ADD_TO_INVISIBLE_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, 1, content_style_tag))
#define WRITE_RESET_CONTENT_STYLE_TAG CHCK_RSLT_ADD_TO_INVISIBLE_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, 1, reset_content_style_tag))
if (row >= hint_height_cell(cell, context)
|| row < cell_padding_top
|| row >= (cell_padding_top + buffer_text_height(cell->str_buffer))) {
return snprint_n_strings_(buf, buf_len, buf_len - 1, space_char);
WRITE_CELL_STYLE_TAG;
WRITE_CONTENT_STYLE_TAG;
WRITE_RESET_CONTENT_STYLE_TAG;
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len, buf_len - 1 - TOTAL_WRITTEN - R3, space_char));
WRITE_RESET_CELL_STYLE_TAG;
return TOTAL_WRITTEN;
}
int written = 0;
int tmp = 0;
int left = cell_padding_left;
int right = cell_padding_right;
WRITE_CELL_STYLE_TAG;
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, L2, space_char));
if (cell->str_buffer) {
CHCK_RSLT_ADD_TO_WRITTEN(buffer_printf_(cell->str_buffer, row - cell_padding_top, buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN - R2 - R3, context, content_style_tag, reset_content_style_tag));
} else {
WRITE_CONTENT_STYLE_TAG;
WRITE_RESET_CONTENT_STYLE_TAG;
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN - R2 - R3, space_char));
}
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + TOTAL_WRITTEN, buf_len - TOTAL_WRITTEN, R2, space_char));
WRITE_RESET_CELL_STYLE_TAG;
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + written, buf_len - written, left, space_char));
if (cell->str_buffer)
CHCK_RSLT_ADD_TO_WRITTEN(buffer_printf_(cell->str_buffer, row - cell_padding_top, buf + written, buf_len - written - right, context));
else
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + written, buf_len - written, buf_len - written - right, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + written, buf_len - written, right, space_char));
return written;
return TOTAL_WRITTEN;
clear:
return -1;
#undef WRITE_CELL_STYLE_TAG
#undef WRITE_RESET_CELL_STYLE_TAG
#undef WRITE_CONTENT_STYLE_TAG
#undef WRITE_RESET_CONTENT_STYLE_TAG
#undef TOTAL_WRITTEN
#undef RIGHT
}
#endif

View File

@ -13,7 +13,7 @@ FT_INTERNAL
fort_cell_t *copy_cell(fort_cell_t *cell);
FT_INTERNAL
size_t hint_width_cell(const fort_cell_t *cell, const context_t *context);
size_t hint_width_cell(const fort_cell_t *cell, const context_t *context, enum request_geom_type geom);
FT_INTERNAL
size_t hint_height_cell(const fort_cell_t *cell, const context_t *context);

View File

@ -611,7 +611,7 @@ const char *ft_to_string(const ft_table_t *table)
size_t rows = 0;
size_t *col_width_arr = NULL;
size_t *row_height_arr = NULL;
status = table_rows_and_cols_geometry(table, &col_width_arr, &cols, &row_height_arr, &rows);
status = table_rows_and_cols_geometry(table, &col_width_arr, &cols, &row_height_arr, &rows, VISIBLE_GEOMETRY);
if (FT_IS_ERROR(status))
return NULL;
@ -715,7 +715,7 @@ const wchar_t *ft_to_wstring(const ft_table_t *table)
size_t rows = 0;
size_t *col_width_arr = NULL;
size_t *row_height_arr = NULL;
status = table_rows_and_cols_geometry(table, &col_width_arr, &cols, &row_height_arr, &rows);
status = table_rows_and_cols_geometry(table, &col_width_arr, &cols, &row_height_arr, &rows, VISIBLE_GEOMETRY);
if (rows == 0)
return EMPTY_STRING;

View File

@ -195,6 +195,9 @@ int snprint_n_strings(char *buf, size_t length, size_t n, const char *str)
if (n * str_len > INT_MAX)
return -1;
if (str_len == 0)
return 0;
int status = snprintf(buf, length, "%0*d", (int)(n * str_len), 0);
if (status < 0)
return status;
@ -240,8 +243,36 @@ int wsnprint_n_string(wchar_t *buf, size_t length, size_t n, const char *str)
/* This function doesn't work properly with multibyte characters
* so it is better return an error in this case
*/
if (str_len > 1)
return -1;
if (str_len > 1) {
const unsigned char *p = (const unsigned char *)str;
while (*p) {
if (*p <= 127)
p++;
else {
const int SIZE = 64;
wchar_t wcs[SIZE];
const char *ptr = str;
int length;
length = mbsrtowcs(wcs, (const char **)&ptr, SIZE, NULL);
wcs[length] = L'\0';
if (length > 1) {
return -1;
} else {
swprintf(buf, length, L"%0*d", (int)(n * str_len), 0);
int k = n;
while (k) {
*buf = *wcs;
++buf;
--k;
}
buf[n] = L'\0';
return n;
}
// return -1;
}
}
}
if (length <= n * str_len)
return -1;
@ -249,12 +280,13 @@ int wsnprint_n_string(wchar_t *buf, size_t length, size_t n, const char *str)
if (n == 0)
return 0;
/* To ensure valid return value it is safely not print such big strings */
if (n * str_len > INT_MAX)
return -1;
if (str_len == 0)
return 0;
int status = swprintf(buf, length, L"%0*d", (int)(n * str_len), 0);
if (status < 0)
return status;

View File

@ -105,15 +105,16 @@ typedef struct fort_row fort_row_t;
/*typedef struct ft_table ft_table_t;*/
typedef struct separator separator_t;
enum CellType {
CommonCell,
GroupMasterCell,
GroupSlaveCell
};
enum request_geom_type {
VISIBLE_GEOMETRY,
INTERN_REPR_GEOMETRY
};
/*****************************************************************************
* LIBFORT helpers
@ -145,6 +146,15 @@ int wsnprint_n_string(wchar_t *buf, size_t length, size_t n, const char *str);
written += tmp; \
} while(0)
#define CHCK_RSLT_ADD_TO_INVISIBLE_WRITTEN(statement) \
do { \
tmp = statement; \
if (tmp < 0) {\
goto clear; \
} \
invisible_written += tmp; \
} while(0)
#define CHECK_NOT_NEGATIVE(x) \
do { if (x < 0) goto fort_fail; } while (0)

View File

@ -1,8 +1,255 @@
#include "fort_utils.h"
#include <assert.h>
#include "properties.h"
#include "fort_utils.h"
#include "vector.h"
#define FT_RESET_COLOR "\033[0m"
const char *fg_colors[] = {
"",
"\033[30m",
"\033[31m",
"\033[32m",
"\033[33m",
"\033[34m",
"\033[35m",
"\033[36m",
"\033[37m",
"\033[90m",
"\033[91m",
"\033[92m",
"\033[93m",
"\033[94m",
"\033[95m",
"\033[96m",
"\033[97m",
};
const char *reset_fg_colors[] = {
"",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
"\033[39m",
};
const char *bg_colors[] = {
"",
"\033[40m",
"\033[41m",
"\033[42m",
"\033[43m",
"\033[44m",
"\033[45m",
"\033[46m",
"\033[47m",
"\033[100m",
"\033[101m",
"\033[102m",
"\033[103m",
"\033[104m",
"\033[105m",
"\033[106m",
"\033[107m",
};
const char *reset_bg_colors[] = {
"",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
"\033[49m",
};
const char *text_styles[] = {
"",
"\033[1m",
"\033[2m",
"\033[4m",
"\033[5m",
"\033[7m",
"\033[8m",
};
const char *reset_text_styles[] = {
"",
"\033[21m",
"\033[22m",
"\033[24m",
"\033[25m",
"\033[27m",
"\033[28m",
};
static const size_t n_fg_colors = sizeof(fg_colors) / sizeof(fg_colors[0]);
static const size_t n_bg_colors = sizeof(bg_colors) / sizeof(bg_colors[0]);
static const size_t n_styles = sizeof(text_styles) / sizeof(text_styles[0]);
void get_style_tag_for_cell(const fort_table_properties_t *props,
size_t row, size_t col, char *style_tag, size_t sz)
{
(void)sz;
unsigned bg_color_number = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CELL_BG_COLOR);
unsigned text_style = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CELL_TEXT_STYLE);
style_tag[0] = '\0';
if (text_style < n_styles) {
strcat(style_tag, text_styles[text_style]);
} else {
goto error;
}
if (bg_color_number < n_bg_colors) {
strcat(style_tag, bg_colors[bg_color_number]);
} else {
goto error;
}
return;
error:
// shouldn't be here
assert(0);
style_tag[0] = '\0';
return;
}
void get_reset_style_tag_for_cell(const fort_table_properties_t *props,
size_t row, size_t col, char *reset_style_tag, size_t sz)
{
(void)sz;
unsigned bg_color_number = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CELL_BG_COLOR);
unsigned text_style = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CELL_TEXT_STYLE);
reset_style_tag[0] = '\0';
if (text_style < n_styles) {
strcat(reset_style_tag, reset_text_styles[text_style]);
} else {
goto error;
}
if (bg_color_number < n_bg_colors) {
strcat(reset_style_tag, reset_bg_colors[bg_color_number]);
} else {
goto error;
}
return;
error:
// shouldn't be here
assert(0);
reset_style_tag[0] = '\0';
return;
}
void get_style_tag_for_content(const fort_table_properties_t *props,
size_t row, size_t col, char *style_tag, size_t sz)
{
(void)sz;
unsigned text_style = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CONT_TEXT_STYLE);
unsigned fg_color_number = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CONT_FG_COLOR);
unsigned bg_color_number = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CONT_BG_COLOR);
style_tag[0] = '\0';
if (text_style < n_styles) {
strcat(style_tag, text_styles[text_style]);
} else {
goto error;
}
if (fg_color_number < n_fg_colors) {
strcat(style_tag, fg_colors[fg_color_number]);
} else {
goto error;
}
if (bg_color_number < n_bg_colors) {
strcat(style_tag, bg_colors[bg_color_number]);
} else {
goto error;
}
return;
error:
// shouldn't be here
assert(0);
style_tag[0] = '\0';
return;
}
void get_reset_style_tag_for_content(const fort_table_properties_t *props,
size_t row, size_t col, char *reset_style_tag, size_t sz)
{
(void)sz;
unsigned text_style = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CONT_TEXT_STYLE);
unsigned fg_color_number = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CONT_FG_COLOR);
unsigned bg_color_number = get_cell_property_value_hierarcial(props, row, col, FT_CPROP_CONT_BG_COLOR);
reset_style_tag[0] = '\0';
if (text_style < n_styles) {
strcat(reset_style_tag, reset_text_styles[text_style]);
} else {
goto error;
}
if (fg_color_number < n_fg_colors) {
strcat(reset_style_tag, reset_fg_colors[fg_color_number]);
} else {
goto error;
}
if (bg_color_number < n_bg_colors) {
strcat(reset_style_tag, reset_bg_colors[bg_color_number]);
} else {
goto error;
}
return;
error:
// shouldn't be here
assert(0);
reset_style_tag[0] = '\0';
return;
}
/*****************************************************************************
* COLUMN PROPERTIES
* ***************************************************************************/
@ -14,7 +261,8 @@ struct fort_cell_props g_default_cell_properties = {
/* properties */
FT_CPROP_MIN_WIDTH | FT_CPROP_TEXT_ALIGN | FT_CPROP_TOP_PADDING
| FT_CPROP_BOTTOM_PADDING | FT_CPROP_LEFT_PADDING | FT_CPROP_RIGHT_PADDING
| FT_CPROP_EMPTY_STR_HEIGHT,
| FT_CPROP_EMPTY_STR_HEIGHT | FT_CPROP_CONT_FG_COLOR | FT_CPROP_CELL_BG_COLOR
| FT_CPROP_CONT_BG_COLOR | FT_CPROP_CELL_TEXT_STYLE | FT_CPROP_CONT_TEXT_STYLE,
0, /* col_min_width */
FT_ALIGNED_LEFT, /* align */
@ -25,6 +273,11 @@ struct fort_cell_props g_default_cell_properties = {
1, /* cell_empty_string_height */
FT_ROW_COMMON, /* row_type */
FT_COLOR_DEFAULT, /* content_fg_color_number */
FT_COLOR_DEFAULT, /* content_bg_color_number */
FT_COLOR_DEFAULT, /* cell_bg_color_number */
FT_TSTYLE_DEFAULT, /* cell_text_style */
FT_TSTYLE_DEFAULT, /* content_text_style */
};
static int get_prop_value_if_exists_otherwise_default(const struct fort_cell_props *cell_opts, uint32_t property)
@ -50,6 +303,16 @@ static int get_prop_value_if_exists_otherwise_default(const struct fort_cell_pro
return cell_opts->cell_empty_string_height;
case FT_CPROP_ROW_TYPE:
return cell_opts->row_type;
case FT_CPROP_CONT_FG_COLOR:
return cell_opts->content_fg_color_number;
case FT_CPROP_CONT_BG_COLOR:
return cell_opts->content_bg_color_number;
case FT_CPROP_CELL_BG_COLOR:
return cell_opts->cell_bg_color_number;
case FT_CPROP_CELL_TEXT_STYLE:
return cell_opts->cell_text_style;
case FT_CPROP_CONT_TEXT_STYLE:
return cell_opts->content_text_style;
default:
/* todo: implement later */
exit(333);
@ -120,6 +383,7 @@ FT_INTERNAL
int get_cell_property_value_hierarcial(const fort_table_properties_t *propertiess, size_t row, size_t column, uint32_t property)
{
assert(propertiess);
size_t row_origin = row;
const fort_cell_props_t *opt = NULL;
if (propertiess->cell_properties != NULL) {
@ -127,15 +391,29 @@ int get_cell_property_value_hierarcial(const fort_table_properties_t *properties
opt = cget_cell_prop(propertiess->cell_properties, row, column);
if (opt != NULL && PROP_IS_SET(opt->properties, property))
break;
if (row != FT_ANY_ROW) {
if (row != FT_ANY_ROW && column != FT_ANY_COLUMN) {
row = FT_ANY_ROW;
continue;
}
if (column != FT_ANY_COLUMN) {
} else if (row == FT_ANY_ROW && column != FT_ANY_COLUMN) {
row = row_origin;
column = FT_ANY_COLUMN;
continue;
} else if (row != FT_ANY_ROW && column == FT_ANY_COLUMN) {
row = FT_ANY_ROW;
column = FT_ANY_COLUMN;
continue;
}
// if (row != FT_ANY_ROW) {
// row = FT_ANY_ROW;
// continue;
// }
// if (column != FT_ANY_COLUMN) {
// column = FT_ANY_COLUMN;
// continue;
// }
opt = NULL;
break;
}
@ -172,6 +450,16 @@ static fort_status_t set_cell_property_impl(fort_cell_props_t *opt, uint32_t pro
opt->cell_empty_string_height = value;
} else if (PROP_IS_SET(property, FT_CPROP_ROW_TYPE)) {
opt->row_type = (enum ft_row_type)value;
} else if (PROP_IS_SET(property, FT_CPROP_CONT_FG_COLOR)) {
opt->content_fg_color_number = value;
} else if (PROP_IS_SET(property, FT_CPROP_CONT_BG_COLOR)) {
opt->content_bg_color_number = value;
} else if (PROP_IS_SET(property, FT_CPROP_CELL_BG_COLOR)) {
opt->cell_bg_color_number = value;
} else if (PROP_IS_SET(property, FT_CPROP_CELL_TEXT_STYLE)) {
opt->cell_text_style = value;
} else if (PROP_IS_SET(property, FT_CPROP_CONT_TEXT_STYLE)) {
opt->content_text_style = value;
}
return FT_SUCCESS;

View File

@ -9,6 +9,19 @@
#define PROP_SET(ft_props, property) ((ft_props) |=(property))
#define PROP_UNSET(ft_props, property) ((ft_props) &= ~((uint32_t)property))
#define TEXT_STYLE_TAG_MAX_SIZE 64
void get_style_tag_for_cell(const fort_table_properties_t *props,
size_t row, size_t col, char *style_tag, size_t sz);
void get_reset_style_tag_for_cell(const fort_table_properties_t *props,
size_t row, size_t col, char *style_tag, size_t sz);
void get_style_tag_for_content(const fort_table_properties_t *props,
size_t row, size_t col, char *style_tag, size_t sz);
void get_reset_style_tag_for_content(const fort_table_properties_t *props,
size_t row, size_t col, char *style_tag, size_t sz);
struct fort_cell_props {
size_t cell_row;
size_t cell_col;
@ -21,6 +34,11 @@ struct fort_cell_props {
unsigned int cell_padding_right;
unsigned int cell_empty_string_height;
enum ft_row_type row_type;
unsigned int content_fg_color_number;
unsigned int content_bg_color_number;
unsigned int cell_bg_color_number;
unsigned int cell_text_style;
unsigned int content_text_style;
};
typedef struct fort_cell_props fort_cell_props_t;

View File

@ -341,7 +341,8 @@ size_t buffer_text_width(string_buffer_t *buffer)
FT_INTERNAL
int buffer_printf(string_buffer_t *buffer, size_t buffer_row, char *buf, size_t buf_len, const context_t *context)
int buffer_printf(string_buffer_t *buffer, size_t buffer_row, char *buf, size_t total_buf_len,
const context_t *context, const char *content_style_tag, const char *reset_content_style_tag)
{
#define CHAR_TYPE char
#define NULL_CHAR '\0'
@ -355,6 +356,8 @@ int buffer_printf(string_buffer_t *buffer, size_t buffer_row, char *buf, size_t
#define STR_N_SUBSTRING str_n_substring
#define STR_ITER_WIDTH str_iter_width
size_t buf_len = total_buf_len - strlen(content_style_tag) - strlen(reset_content_style_tag);
if (buffer == NULL || buffer->str.data == NULL
|| buffer_row >= buffer_text_height(buffer) || buf_len == 0) {
return -1;
@ -392,7 +395,7 @@ int buffer_printf(string_buffer_t *buffer, size_t buffer_row, char *buf, size_t
const CHAR_TYPE *end = NULL;
CHAR_TYPE old_value;
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, buf_len - written, left, SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, left, SPACE_CHAR));
STR_N_SUBSTRING(buffer->BUFFER_STR, NEWLINE_CHAR, buffer_row, &beg, &end);
if (beg == NULL || end == NULL)
@ -404,10 +407,13 @@ int buffer_printf(string_buffer_t *buffer, size_t buffer_row, char *buf, size_t
if (str_it_width < 0 || content_width < (size_t)str_it_width)
return - 1;
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINTF(buf + written, buf_len - written, SNPRINTF_FMT_STR, (int)(end - beg), beg));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, 1, content_style_tag));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINTF(buf + written, total_buf_len - written, SNPRINTF_FMT_STR, (int)(end - beg), beg));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, 1, reset_content_style_tag));
*(CHAR_TYPE *)end = old_value;
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, buf_len - written, (content_width - (size_t)str_it_width), SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, buf_len - written, right, SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, (content_width - (size_t)str_it_width), SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, right, SPACE_CHAR));
return written;
clear:
@ -429,7 +435,8 @@ clear:
#ifdef FT_HAVE_WCHAR
FT_INTERNAL
int buffer_wprintf(string_buffer_t *buffer, size_t buffer_row, wchar_t *buf, size_t buf_len, const context_t *context)
int buffer_wprintf(string_buffer_t *buffer, size_t buffer_row, wchar_t *buf, size_t total_buf_len,
const context_t *context, const char *content_style_tag, const char *reset_content_style_tag)
{
#define CHAR_TYPE wchar_t
#define NULL_CHAR L'\0'
@ -443,6 +450,8 @@ int buffer_wprintf(string_buffer_t *buffer, size_t buffer_row, wchar_t *buf, siz
#define STR_N_SUBSTRING wstr_n_substring
#define STR_ITER_WIDTH wcs_iter_width
size_t buf_len = total_buf_len - strlen(content_style_tag) - strlen(reset_content_style_tag);
if (buffer == NULL || buffer->str.data == NULL
|| buffer_row >= buffer_text_height(buffer) || buf_len == 0) {
return -1;
@ -480,7 +489,7 @@ int buffer_wprintf(string_buffer_t *buffer, size_t buffer_row, wchar_t *buf, siz
const CHAR_TYPE *end = NULL;
CHAR_TYPE old_value;
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, buf_len - written, left, SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, left, SPACE_CHAR));
STR_N_SUBSTRING(buffer->BUFFER_STR, NEWLINE_CHAR, buffer_row, &beg, &end);
if (beg == NULL || end == NULL)
@ -492,10 +501,13 @@ int buffer_wprintf(string_buffer_t *buffer, size_t buffer_row, wchar_t *buf, siz
if (str_it_width < 0 || content_width < (size_t)str_it_width)
return - 1;
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINTF(buf + written, buf_len - written, SNPRINTF_FMT_STR, (int)(end - beg), beg));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, 1, content_style_tag));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINTF(buf + written, total_buf_len - written, SNPRINTF_FMT_STR, (int)(end - beg), beg));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, 1, reset_content_style_tag));
*(CHAR_TYPE *)end = old_value;
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, buf_len - written, (content_width - (size_t)str_it_width), SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, buf_len - written, right, SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, (content_width - (size_t)str_it_width), SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, total_buf_len - written, right, SPACE_CHAR));
return written;
clear:

View File

@ -57,11 +57,13 @@ FT_INTERNAL
size_t buffer_text_width(string_buffer_t *buffer);
FT_INTERNAL
int buffer_printf(string_buffer_t *buffer, size_t buffer_row, char *buf, size_t buf_len, const context_t *context);
int buffer_printf(string_buffer_t *buffer, size_t buffer_row, char *buf, size_t total_buf_len,
const context_t *context, const char *content_style_tag, const char *reset_content_style_tag);
#ifdef FT_HAVE_WCHAR
FT_INTERNAL
int buffer_wprintf(string_buffer_t *buffer, size_t buffer_row, wchar_t *buf, size_t buf_len, const context_t *context);
int buffer_wprintf(string_buffer_t *buffer, size_t buffer_row, wchar_t *buf, size_t total_buf_len,
const context_t *context, const char *content_style_tag, const char *reset_content_style_tag);
#endif /* FT_HAVE_WCHAR */
#endif /* STRING_BUFFER_H */

View File

@ -122,7 +122,8 @@ fort_status_t get_table_sizes(const ft_table_t *table, size_t *rows, size_t *col
FT_INTERNAL
fort_status_t table_rows_and_cols_geometry(const ft_table_t *table,
size_t **col_width_arr_p, size_t *col_width_arr_sz,
size_t **row_height_arr_p, size_t *row_height_arr_sz)
size_t **row_height_arr_p, size_t *row_height_arr_sz,
enum request_geom_type geom)
{
if (table == NULL) {
return FT_ERROR;
@ -159,7 +160,7 @@ fort_status_t table_rows_and_cols_geometry(const ft_table_t *table,
if (cell) {
switch (get_cell_type(cell)) {
case CommonCell:
col_width_arr[col] = MAX(col_width_arr[col], hint_width_cell(cell, &context));
col_width_arr[col] = MAX(col_width_arr[col], hint_width_cell(cell, &context, geom));
break;
case GroupMasterCell:
combined_cells_found = 1;
@ -184,7 +185,7 @@ fort_status_t table_rows_and_cols_geometry(const ft_table_t *table,
context.row = row;
if (cell) {
if (get_cell_type(cell) == GroupMasterCell) {
size_t hint_width = hint_width_cell(cell, &context);
size_t hint_width = hint_width_cell(cell, &context, geom);
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];
@ -243,7 +244,7 @@ fort_status_t table_geometry(const ft_table_t *table, size_t *height, size_t *wi
size_t *col_width_arr = NULL;
size_t *row_height_arr = NULL;
int status = table_rows_and_cols_geometry(table, &col_width_arr, &cols, &row_height_arr, &rows);
int status = table_rows_and_cols_geometry(table, &col_width_arr, &cols, &row_height_arr, &rows, INTERN_REPR_GEOMETRY);
if (FT_IS_ERROR(status))
return status;

View File

@ -36,10 +36,12 @@ fort_row_t *get_row_and_create_if_not_exists(ft_table_t *table, size_t row);
FT_INTERNAL
string_buffer_t *get_cur_str_buffer_and_create_if_not_exists(ft_table_t *table);
FT_INTERNAL
fort_status_t table_rows_and_cols_geometry(const ft_table_t *table,
size_t **col_width_arr_p, size_t *col_width_arr_sz,
size_t **row_height_arr_p, size_t *row_height_arr_sz);
size_t **row_height_arr_p, size_t *row_height_arr_sz,
enum request_geom_type geom);
FT_INTERNAL
fort_status_t table_geometry(const ft_table_t *table, size_t *height, size_t *width);

View File

@ -137,6 +137,118 @@ void test_table_cell_properties(void)
ft_table_t *table = NULL;
WHEN("Setting property for one cell") {
set_test_properties_as_default();
table = create_test_int_table(0);
ft_set_cell_prop(table, 1, 1, FT_CPROP_TOP_PADDING, 2);
const char *table_str = ft_to_string(table);
assert_true(table_str != NULL);
const char *table_str_etalon =
"+---+---+----+----+\n"
"| | | | |\n"
"| 3 | 4 | 55 | 67 |\n"
"| | | | |\n"
"+---+---+----+----+\n"
"| | | | |\n"
"| 3 | | 55 | 67 |\n"
"| | 4 | | |\n"
"| | | | |\n"
"+---+---+----+----+\n"
"| | | | |\n"
"| 3 | 4 | 55 | 67 |\n"
"| | | | |\n"
"+---+---+----+----+\n";
assert_str_equal(table_str, table_str_etalon);
ft_destroy_table(table);
}
WHEN("Setting property for the row") {
set_test_properties_as_default();
table = create_test_int_table(0);
ft_set_cell_prop(table, 1, FT_ANY_COLUMN, FT_CPROP_TOP_PADDING, 2);
const char *table_str = ft_to_string(table);
assert_true(table_str != NULL);
const char *table_str_etalon =
"+---+---+----+----+\n"
"| | | | |\n"
"| 3 | 4 | 55 | 67 |\n"
"| | | | |\n"
"+---+---+----+----+\n"
"| | | | |\n"
"| | | | |\n"
"| 3 | 4 | 55 | 67 |\n"
"| | | | |\n"
"+---+---+----+----+\n"
"| | | | |\n"
"| 3 | 4 | 55 | 67 |\n"
"| | | | |\n"
"+---+---+----+----+\n";
assert_str_equal(table_str, table_str_etalon);
ft_destroy_table(table);
}
WHEN("Setting property for the column") {
set_test_properties_as_default();
table = create_test_int_table(0);
ft_set_cell_prop(table, FT_ANY_ROW, 1, FT_CPROP_TOP_PADDING, 2);
const char *table_str = ft_to_string(table);
assert_true(table_str != NULL);
const char *table_str_etalon =
"+---+---+----+----+\n"
"| | | | |\n"
"| 3 | | 55 | 67 |\n"
"| | 4 | | |\n"
"| | | | |\n"
"+---+---+----+----+\n"
"| | | | |\n"
"| 3 | | 55 | 67 |\n"
"| | 4 | | |\n"
"| | | | |\n"
"+---+---+----+----+\n"
"| | | | |\n"
"| 3 | | 55 | 67 |\n"
"| | 4 | | |\n"
"| | | | |\n"
"+---+---+----+----+\n";
assert_str_equal(table_str, table_str_etalon);
ft_destroy_table(table);
}
WHEN("Setting property for all cells in the table") {
set_test_properties_as_default();
table = create_test_int_table(0);
ft_set_cell_prop(table, FT_ANY_ROW, FT_ANY_COLUMN, FT_CPROP_TOP_PADDING, 2);
const char *table_str = ft_to_string(table);
assert_true(table_str != NULL);
const char *table_str_etalon =
"+---+---+----+----+\n"
"| | | | |\n"
"| | | | |\n"
"| 3 | 4 | 55 | 67 |\n"
"| | | | |\n"
"+---+---+----+----+\n"
"| | | | |\n"
"| | | | |\n"
"| 3 | 4 | 55 | 67 |\n"
"| | | | |\n"
"+---+---+----+----+\n"
"| | | | |\n"
"| | | | |\n"
"| 3 | 4 | 55 | 67 |\n"
"| | | | |\n"
"+---+---+----+----+\n";
assert_str_equal(table_str, table_str_etalon);
ft_destroy_table(table);
}
WHEN("All paddings = 1") {
set_test_properties_as_default();
@ -553,3 +665,248 @@ void test_table_cell_properties(void)
ft_destroy_table(table);
}
}
void test_table_text_styles(void)
{
ft_table_t *table = NULL;
set_test_properties_as_default();
WHEN("Simple table with one cell and foreground content color") {
table = ft_create_table();
assert(table);
assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CONT_FG_COLOR, FT_COLOR_YELLOW) == FT_SUCCESS);
assert(ft_write(table, "42") == FT_SUCCESS);
const char *table_str = ft_to_string(table);
assert_true(table_str != NULL);
const char *table_str_etalon =
"+----+\n"
"|\033[33m\033[39m |\n"
"| \033[33m42\033[39m |\n"
"|\033[33m\033[39m |\n"
"+----+\n";
assert_str_equal(table_str, table_str_etalon);
ft_destroy_table(table);
}
#ifdef FT_HAVE_WCHAR
WHEN("Simple table with one cell and foreground color(wide strings case)") {
table = ft_create_table();
assert(table);
assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CONT_FG_COLOR, FT_COLOR_YELLOW) == FT_SUCCESS);
assert(ft_wwrite(table, L"42") == FT_SUCCESS);
const wchar_t *table_str = ft_to_wstring(table);
assert_true(table_str != NULL);
const wchar_t *table_str_etalon =
L"+----+\n"
L"|\033[33m\033[39m |\n"
L"| \033[33m42\033[39m |\n"
L"|\033[33m\033[39m |\n"
L"+----+\n";
assert_wcs_equal(table_str, table_str_etalon);
ft_destroy_table(table);
}
#endif
WHEN("Simple table with one cell and background content color") {
table = ft_create_table();
assert(table);
assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CONT_BG_COLOR, FT_COLOR_YELLOW) == FT_SUCCESS);
assert(ft_write(table, "42") == FT_SUCCESS);
const char *table_str = ft_to_string(table);
assert_true(table_str != NULL);
const char *table_str_etalon =
"+----+\n"
"|\033[43m\033[49m |\n"
"| \033[43m42\033[49m |\n"
"|\033[43m\033[49m |\n"
"+----+\n";
assert_str_equal(table_str, table_str_etalon);
ft_destroy_table(table);
}
#ifdef FT_HAVE_WCHAR
WHEN("Simple table with one cell and background content color(wide strings case)") {
table = ft_create_table();
assert(table);
assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CONT_BG_COLOR, FT_COLOR_YELLOW) == FT_SUCCESS);
assert(ft_wwrite(table, L"42") == FT_SUCCESS);
const wchar_t *table_str = ft_to_wstring(table);
assert_true(table_str != NULL);
const wchar_t *table_str_etalon =
L"+----+\n"
L"|\033[43m\033[49m |\n"
L"| \033[43m42\033[49m |\n"
L"|\033[43m\033[49m |\n"
L"+----+\n";
assert_wcs_equal(table_str, table_str_etalon);
ft_destroy_table(table);
}
#endif
WHEN("Simple table with one cell and background cell color") {
table = ft_create_table();
assert(table);
assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CELL_BG_COLOR, FT_COLOR_YELLOW) == FT_SUCCESS);
assert(ft_write(table, "42") == FT_SUCCESS);
const char *table_str = ft_to_string(table);
assert_true(table_str != NULL);
const char *table_str_etalon =
"+----+\n"
"|\033[43m \033[49m|\n"
"|\033[43m 42 \033[49m|\n"
"|\033[43m \033[49m|\n"
"+----+\n";
assert_str_equal(table_str, table_str_etalon);
ft_destroy_table(table);
}
#ifdef FT_HAVE_WCHAR
WHEN("Simple table with one cell and background cell color(wide strings case)") {
table = ft_create_table();
assert(table);
assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CELL_BG_COLOR, FT_COLOR_YELLOW) == FT_SUCCESS);
assert(ft_wwrite(table, L"42") == FT_SUCCESS);
const wchar_t *table_str = ft_to_wstring(table);
assert_true(table_str != NULL);
const wchar_t *table_str_etalon =
L"+----+\n"
L"|\033[43m \033[49m|\n"
L"|\033[43m 42 \033[49m|\n"
L"|\033[43m \033[49m|\n"
L"+----+\n";
assert_wcs_equal(table_str, table_str_etalon);
ft_destroy_table(table);
}
#endif
WHEN("Simple table with one cell and content style") {
table = ft_create_table();
assert(table);
assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_UNDERLINED) == FT_SUCCESS);
assert(ft_write(table, "42") == FT_SUCCESS);
const char *table_str = ft_to_string(table);
assert_true(table_str != NULL);
const char *table_str_etalon =
"+----+\n"
"|\033[4m\033[24m |\n"
"| \033[4m42\033[24m |\n"
"|\033[4m\033[24m |\n"
"+----+\n";
assert_str_equal(table_str, table_str_etalon);
ft_destroy_table(table);
}
#ifdef FT_HAVE_WCHAR
WHEN("Simple table with one cell and content style(wide strings case)") {
table = ft_create_table();
assert(table);
assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_UNDERLINED) == FT_SUCCESS);
assert(ft_wwrite(table, L"42") == FT_SUCCESS);
const wchar_t *table_str = ft_to_wstring(table);
assert_true(table_str != NULL);
const wchar_t *table_str_etalon =
L"+----+\n"
L"|\033[4m\033[24m |\n"
L"| \033[4m42\033[24m |\n"
L"|\033[4m\033[24m |\n"
L"+----+\n";
assert_wcs_equal(table_str, table_str_etalon);
ft_destroy_table(table);
}
#endif
WHEN("Simple table with one cell and cell style") {
table = ft_create_table();
assert(table);
assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CELL_TEXT_STYLE, FT_TSTYLE_UNDERLINED) == FT_SUCCESS);
assert(ft_write(table, "42") == FT_SUCCESS);
const char *table_str = ft_to_string(table);
assert_true(table_str != NULL);
const char *table_str_etalon =
"+----+\n"
"|\033[4m \033[24m|\n"
"|\033[4m 42 \033[24m|\n"
"|\033[4m \033[24m|\n"
"+----+\n";
assert_str_equal(table_str, table_str_etalon);
ft_destroy_table(table);
}
#ifdef FT_HAVE_WCHAR
WHEN("Simple table with one cell and cell style(wide strings case)") {
table = ft_create_table();
assert(table);
assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CELL_TEXT_STYLE, FT_TSTYLE_UNDERLINED) == FT_SUCCESS);
assert(ft_wwrite(table, L"42") == FT_SUCCESS);
const wchar_t *table_str = ft_to_wstring(table);
assert_true(table_str != NULL);
const wchar_t *table_str_etalon =
L"+----+\n"
L"|\033[4m \033[24m|\n"
L"|\033[4m 42 \033[24m|\n"
L"|\033[4m \033[24m|\n"
L"+----+\n";
assert_wcs_equal(table_str, table_str_etalon);
ft_destroy_table(table);
}
#endif
WHEN("Simple table with one cell background color, content foreground color and style.") {
set_test_properties_as_default();
table = ft_create_table();
assert(table);
assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CONT_FG_COLOR, FT_COLOR_YELLOW) == FT_SUCCESS);
assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CELL_BG_COLOR, FT_COLOR_RED) == FT_SUCCESS);
assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_UNDERLINED) == FT_SUCCESS);
assert(ft_write(table, "42") == FT_SUCCESS);
const char *table_str = ft_to_string(table);
assert_true(table_str != NULL);
const char *table_str_etalon =
"+----+\n"
"|\033[41m\033[4m\033[33m\033[24m\033[39m \033[49m|\n"
"|\033[41m \033[4m\033[33m42\033[24m\033[39m \033[49m|\n"
"|\033[41m\033[4m\033[33m\033[24m\033[39m \033[49m|\n"
"+----+\n";
assert_str_equal(table_str, table_str_etalon);
ft_destroy_table(table);
}
#ifdef FT_HAVE_WCHAR
WHEN("Simple table with one cell background color, content foreground color and style.") {
set_test_properties_as_default();
table = ft_create_table();
assert(table);
assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CONT_FG_COLOR, FT_COLOR_YELLOW) == FT_SUCCESS);
assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CELL_BG_COLOR, FT_COLOR_RED) == FT_SUCCESS);
assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_UNDERLINED) == FT_SUCCESS);
assert(ft_wwrite(table, L"42") == FT_SUCCESS);
const wchar_t *table_str = ft_to_wstring(table);
assert_true(table_str != NULL);
const wchar_t *table_str_etalon =
L"+----+\n"
L"|\033[41m\033[4m\033[33m\033[24m\033[39m \033[49m|\n"
L"|\033[41m \033[4m\033[33m42\033[24m\033[39m \033[49m|\n"
L"|\033[41m\033[4m\033[33m\033[24m\033[39m \033[49m|\n"
L"+----+\n";
assert_wcs_equal(table_str, table_str_etalon);
ft_destroy_table(table);
}
#endif
}

View File

@ -24,6 +24,7 @@ struct test_case bb_test_suit [] = {
{"test_table_builtin_border_styles", test_table_builtin_border_styles},
{"test_table_cell_properties", test_table_cell_properties},
{"test_table_tbl_properties", test_table_tbl_properties},
{"test_table_text_styles", test_table_text_styles},
{"test_memory_errors", test_memory_errors},
};
@ -52,15 +53,146 @@ int main(void)
* Essential for OSX, because swprintf can fail in case of real unicode
* chars.
*/
#if defined(FT_HAVE_WCHAR)
//#if defined(FT_HAVE_WCHAR)
// setlocale(LC_CTYPE, "");
//#endif
//#ifdef FORT_WB_TESTING_ENABLED
// status |= run_wb_test_suit();
// fprintf(stderr, "\n");
//#endif
// status |= run_bb_test_suit();
setlocale(LC_CTYPE, "");
#endif
#ifdef FORT_WB_TESTING_ENABLED
status |= run_wb_test_suit();
fprintf(stderr, "\n");
#endif
status |= run_bb_test_suit();
ft_table_t *table = NULL;
table = ft_create_table();
ft_set_border_style(table, FT_DOUBLE2_STYLE);
ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
ft_wwrite_ln(table, L"some", L"some3333", L"11111");
ft_wwrite_ln(table, L"s", L"some333377777", L"1111111111");
ft_wwrite_ln(table, L"some", L"some3333", L"111111");
ft_wwrite_ln(table, L"", L"", L"");
ft_set_cell_prop(table, FT_ANY_ROW, 0, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_CENTER);
ft_set_cell_prop(table, 0, 1, FT_CPROP_CELL_TEXT_STYLE, FT_TSTYLE_UNDERLINED);
ft_set_cell_prop(table, 0, 2, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_UNDERLINED);
ft_set_cell_prop(table, 2, 1, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_UNDERLINED);
ft_set_cell_prop(table, 0, 1, FT_CPROP_CONT_FG_COLOR, FT_COLOR_YELLOW);
ft_set_cell_prop(table, 0, 1, FT_CPROP_CELL_BG_COLOR, FT_COLOR_MAGENTA);
ft_set_cell_prop(table, 0, 1, FT_CPROP_CELL_TEXT_STYLE, FT_TSTYLE_UNDERLINED);
ft_set_cell_prop(table, 1, 1, FT_CPROP_CONT_BG_COLOR, FT_COLOR_RED);
ft_set_cell_prop(table, 0, 2, FT_CPROP_CONT_BG_COLOR, FT_COLOR_RED);
ft_set_cell_prop(table, 3, FT_ANY_COLUMN, FT_CPROP_CONT_FG_COLOR, FT_COLOR_GREEN);
ft_set_cell_prop(table, 3, FT_ANY_COLUMN, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_BOLD);
const wchar_t *table_wstr = ft_to_wstring(table);
if (table_wstr) {
fwprintf(stdout, L"Table:\n%ls\n ", table_wstr);
} else {
fwprintf(stdout, L"Table conversion failed !!!\n ");
}
ft_destroy_table(table);
// /////////////////////////
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);
ft_wwrite_ln(table, L"Test", L"Iterations", L"ms/op", L"Passed");
ft_wwrite_ln(table, L"n-body", L"1000", L"1.629");
ft_wwrite_ln(table, L"", L"2500", L"6.3", L"");
ft_wwrite_ln(table, L"", L"10000", L"10.5");
ft_add_separator(table);
ft_wwrite_ln(table, L"regex-redux", L"1000", L"1.629");
ft_wwrite_ln(table, L"", L"2500", L"6.3", L"");
ft_wwrite_ln(table, L"", L"10000", L"10.5");
ft_add_separator(table);
ft_wwrite_ln(table, L"mandelbrot", L"1000", L"1.629");
ft_wwrite_ln(table, L"", L"2500", L"6.3", L"");
ft_wwrite_ln(table, L"", L"10000", L"10.5");
ft_add_separator(table);
ft_set_cell_span(table, 10, 0, 3);
ft_wwrite_ln(table, L"Total result", L"", L"", L"");
ft_set_cell_prop(table, 0, 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, 1, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_RIGHT);
ft_set_cell_prop(table, FT_ANY_ROW, 3, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_CENTER);
ft_set_cell_prop(table, 10, 0, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_CENTER);
ft_set_cell_prop(table, 2, 3, FT_CPROP_CONT_FG_COLOR, FT_COLOR_GREEN);
ft_set_cell_prop(table, 5, 3, FT_CPROP_CONT_FG_COLOR, FT_COLOR_RED);
ft_set_cell_prop(table, 8, 3, FT_CPROP_CONT_FG_COLOR, FT_COLOR_GREEN);
// ft_set_cell_prop(table, FT_ANY_ROW, 0, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_CENTER);
// ft_set_cell_prop(table, 0, 1, FT_CPROP_CELL_TEXT_STYLE, FT_TSTYLE_UNDERLINED);
// ft_set_cell_prop(table, 0, 2, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_UNDERLINED);
// ft_set_cell_prop(table, 2, 1, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_UNDERLINED);
// ft_set_cell_prop(table, 0, 1, FT_CPROP_CONT_FG_COLOR, FT_COLOR_YELLOW);
// ft_set_cell_prop(table, 0, 1, FT_CPROP_CELL_BG_COLOR, FT_COLOR_MAGENTA);
// ft_set_cell_prop(table, 0, 1, FT_CPROP_CELL_TEXT_STYLE, FT_TSTYLE_UNDERLINED);
// ft_set_cell_prop(table, 1, 1, FT_CPROP_CONT_BG_COLOR, FT_COLOR_RED);
// ft_set_cell_prop(table, 0, 2, FT_CPROP_CONT_BG_COLOR, FT_COLOR_RED);
// ft_set_cell_prop(table, 3, FT_ANY_COLUMN, FT_CPROP_CONT_FG_COLOR, FT_COLOR_GREEN);
// ft_set_cell_prop(table, 3, FT_ANY_COLUMN, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_BOLD);
table_wstr = ft_to_wstring(table);
if (table_wstr) {
fwprintf(stdout, L"Table:\n%ls\n ", table_wstr);
} else {
fwprintf(stdout, L"Table conversion failed !!!\n ");
}
ft_destroy_table(table);
// printf("\n\n------ Some debug stuff delete later --------\n\n\n");
// ft_table_t *table = ft_create_table();
// ft_set_cell_prop(table, 0, 0, FT_CPROP_CONT_FG_COLOR, FT_COLOR_RED);
// ft_set_cell_prop(table, 1, 1, FT_CPROP_CONT_FG_COLOR, FT_COLOR_GREEN);
// ft_set_cell_prop(table, FT_ANY_ROW, 2, FT_CPROP_CONT_FG_COLOR, FT_COLOR_MAGENTA);
// ft_set_cell_prop(table, FT_ANY_ROW, 2, FT_CPROP_CONT_BG_COLOR, FT_COLOR_YELLOW);
// ft_set_cell_prop(table, 0, 1, FT_CPROP_CONT_FG_COLOR, FT_COLOR_YELLOW);
// ft_set_cell_prop(table, 0, 1, FT_CPROP_CELL_BG_COLOR, FT_COLOR_MAGENTA);
// ft_set_cell_prop(table, 0, 1, FT_CPROP_CELL_TEXT_STYLE, FT_TSTYLE_UNDERLINED);
// ft_set_cell_prop(table, 2, FT_ANY_COLUMN, FT_CPROP_CELL_TEXT_STYLE, FT_TSTYLE_BOLD);
// ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
// ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_CENTER);
// ft_set_cell_prop(table, FT_ANY_ROW, 0, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_CENTER);
// ft_set_cell_prop(table, 0, 1, FT_CPROP_CELL_TEXT_STYLE, FT_TSTYLE_UNDERLINED);
// ft_set_cell_prop(table, 0, 2, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_UNDERLINED);
// ft_set_cell_prop(table, 2, 1, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_UNDERLINED);
// ft_write_ln(table, "some", "some3333", "11111");
// ft_write_ln(table, "s", "some333377777", "1111111111");
// ft_write_ln(table, "some", "some3333", "111111");
// const char *str_repr = ft_to_string(table);
// printf("%s\n", str_repr ? str_repr : "NULL");
// ft_destroy_table(table);
// printf("aa \033[42m 11 \033[4m 222 \033[49m 123 \033[24m 666\n");
return status;
}

View File

@ -33,6 +33,7 @@ void test_table_write(void);
void test_table_border_style(void);
void test_table_builtin_border_styles(void);
void test_table_cell_properties(void);
void test_table_text_styles(void);
void test_table_tbl_properties(void);
void test_memory_errors(void);