1 #include "table_chunks.h"
2
3 int td_fill_spaces(GString** cells_buff, glong* cells_table, size_t cells_count, glong* max_height);
4 int td_word_wrap(GString** cells_buff, glong* cells_table, size_t cells_count);
5
fb2_parse_tr(APP * app,xmlNode * parent_node,GtkTextIter * text_buff_end,GString ** cells_buff,glong * cells_table,size_t cells_count)6 int fb2_parse_tr(APP* app, xmlNode* parent_node, GtkTextIter* text_buff_end, GString** cells_buff, glong* cells_table, size_t cells_count)
7 {
8 GtkTextBuffer* text_buff = app->text_buff;
9 xmlNode* node = parent_node->children;
10 size_t cell_index = 0;
11
12 while(node != NULL)
13 {
14 if(node->type == XML_ELEMENT_NODE)
15 {
16 if(strcmp((char*)node->name, "td") == 0)
17 parse_fb2_p_get_text(node, cells_buff[cell_index++]);
18 else if (strcmp((char*)node->name, "th") == 0)
19 parse_fb2_p_get_text(node, cells_buff[cell_index++]);
20 }
21
22 node = node->next;
23 }
24
25 glong max_height = 0;
26 td_word_wrap(cells_buff, cells_table, cells_count);
27 td_fill_spaces(cells_buff, cells_table, cells_count, &max_height);
28
29 for(size_t i=0; i<=max_height; i++)
30 {
31 gtk_text_buffer_insert(text_buff, text_buff_end, "│", -1);
32
33 for(size_t j=0; j<cells_count; j++)
34 {
35 glong cell_size = cells_table[j];
36
37 char* pos_l = g_utf8_offset_to_pointer(cells_buff[j]->str, i*cell_size);
38 char* pos_r = g_utf8_offset_to_pointer(cells_buff[j]->str, (i+1)*cell_size);
39
40 glong cell_string_size = (ptrdiff_t)(pos_r - pos_l);
41
42 gtk_text_buffer_insert(text_buff, text_buff_end, pos_l, cell_string_size);
43 gtk_text_buffer_insert(text_buff, text_buff_end, "│", -1);
44 }
45 gtk_text_buffer_insert(text_buff, text_buff_end, "\n", -1);
46 }
47
48 for(size_t i=0; i<cells_count; i++)
49 g_string_set_size(cells_buff[i], 0);
50
51 return EXIT_SUCCESS;
52 }
53
54
td_word_wrap(GString ** cells_buff,glong * cells_table,size_t cells_count)55 int td_word_wrap(GString** cells_buff, glong* cells_table, size_t cells_count) // TODO aligned
56 {
57 g_return_val_if_fail(cells_buff != NULL, EXIT_FAILURE);
58 g_return_val_if_fail(cells_table != NULL, EXIT_FAILURE);
59
60 char spaces[MAX_CELL_LENGTH];
61 memset(spaces, ' ', sizeof(spaces));
62
63 for(size_t i=0; i<cells_count; i++)
64 {
65 glong str_len = g_utf8_strlen(cells_buff[i]->str, (gssize)cells_buff[i]->len);
66 glong cell_len = cells_table[i];
67 for(glong j=0; j<str_len; j+=cell_len)
68 {
69 char* l_pos = g_utf8_offset_to_pointer(cells_buff[i]->str, j);
70 char* r_pos = g_utf8_offset_to_pointer(cells_buff[i]->str, (j+cell_len>str_len)? str_len: j+cell_len);
71 if(*r_pos != 0)
72 {
73 char* space = g_utf8_strrchr(l_pos, (ptrdiff_t)(r_pos - l_pos), ' ');
74
75 if(space != NULL)
76 {
77 glong space_pos = g_utf8_pointer_to_offset(cells_buff[i]->str, space);
78 if(space_pos != 0)
79 {
80 glong need_space = cell_len - (space_pos % cell_len)-1;
81
82 str_len = str_len + need_space;
83 ptrdiff_t insert_pos = (ptrdiff_t)(space - cells_buff[i]->str);
84
85 if(need_space > 0)
86 g_string_insert_len(cells_buff[i], insert_pos, spaces, need_space);
87 }
88 }
89 }
90 }
91
92 }
93
94 return EXIT_SUCCESS;
95 }
96
97
td_fill_spaces(GString ** cells_buff,glong * cells_table,size_t cells_count,glong * max_height)98 int td_fill_spaces(GString** cells_buff, glong* cells_table, size_t cells_count, glong* max_height) // добиваем каждую ячейку до размера максимальной ячейки
99 {
100 g_return_val_if_fail(cells_buff != NULL, EXIT_FAILURE);
101 g_return_val_if_fail(cells_table != NULL, EXIT_FAILURE);
102
103 char spaces[MAX_CELL_LENGTH];
104 memset(spaces, ' ', sizeof(spaces));
105
106
107 *max_height = 0;
108 for(size_t i=0; i<cells_count; i++) // вычисляем максимальную высоту в строках
109 {
110 glong cur_height = g_utf8_strlen(cells_buff[i]->str, cells_buff[i]->len);
111 if(cells_table[i] != 0)
112 {
113 glong height = cur_height/cells_table[i];
114 *max_height = MAX(*max_height, height);
115 }
116 }
117
118 for(size_t i=0; i<cells_count; i++) // проходимся по всем ячейкам
119 {
120 if(cells_table[i] != 0)
121 {
122 glong need_space = (*max_height+1) * cells_table[i];
123 glong tail = need_space % MAX_CELL_LENGTH;
124
125 g_string_append_len(cells_buff[i], spaces, tail);
126
127 for(glong j=0; j<need_space; j+=MAX_CELL_LENGTH)
128 g_string_append_len(cells_buff[i], spaces, MAX_CELL_LENGTH);
129 }
130 }
131
132 return EXIT_SUCCESS;
133 }
134