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