implement text data model.
@@ -0,0 +1,331 @@ | ||
1 | +/* | |
2 | + * bchank_lines.c | |
3 | + * | |
4 | + * Copyright (c) 2013 project bchan | |
5 | + * | |
6 | + * This software is provided 'as-is', without any express or implied | |
7 | + * warranty. In no event will the authors be held liable for any damages | |
8 | + * arising from the use of this software. | |
9 | + * | |
10 | + * Permission is granted to anyone to use this software for any purpose, | |
11 | + * including commercial applications, and to alter it and redistribute it | |
12 | + * freely, subject to the following restrictions: | |
13 | + * | |
14 | + * 1. The origin of this software must not be misrepresented; you must not | |
15 | + * claim that you wrote the original software. If you use this software | |
16 | + * in a product, an acknowledgment in the product documentation would be | |
17 | + * appreciated but is not required. | |
18 | + * | |
19 | + * 2. Altered source versions must be plainly marked as such, and must not be | |
20 | + * misrepresented as being the original software. | |
21 | + * | |
22 | + * 3. This notice may not be removed or altered from any source | |
23 | + * distribution. | |
24 | + * | |
25 | + */ | |
26 | + | |
27 | +#include "bchank_lines.h" | |
28 | + | |
29 | +#include <basic.h> | |
30 | +#include <bstdlib.h> | |
31 | +#include <bstdio.h> | |
32 | +#include <btron/hmi.h> | |
33 | +#include <bsys/queue.h> | |
34 | + | |
35 | +#include <tad/taditerator.h> | |
36 | +#include <tad/tadfragment.h> | |
37 | + | |
38 | +struct bchank_line_t_ { | |
39 | + QUEUE que; | |
40 | + tadfragment_t fragment; | |
41 | + W *pos; | |
42 | + W pos_len; | |
43 | +}; | |
44 | + | |
45 | +LOCAL VOID bchank_line_insert(bchank_line_t *line, bchank_line_t *next) | |
46 | +{ | |
47 | + QueInsert(&line->que, &next->que); | |
48 | +} | |
49 | + | |
50 | +LOCAL bchank_line_t* bchank_line_getnext(bchank_line_t *line) | |
51 | +{ | |
52 | + return (bchank_line_t*)line->que.next; | |
53 | +} | |
54 | + | |
55 | +EXPORT W bchank_line_appendtext(bchank_line_t *line, TC *str, W len) | |
56 | +{ | |
57 | + return tadfragment_pushback(&line->fragment, (UB*)str, len*sizeof(TC)); | |
58 | +} | |
59 | + | |
60 | +/* tmp */ | |
61 | +typedef enum { | |
62 | + BCHANK_SEGCHECK_RESULT_HANKAKU, | |
63 | + BCHANK_SEGCHECK_RESULT_ZENKAKU, | |
64 | + BCHANK_SEGCHECK_RESULT_OTHER | |
65 | +} BCHANK_SEGCHECK_RESULT; | |
66 | + | |
67 | +LOCAL BCHANK_SEGCHECK_RESULT check_segment(TC segment, W size, UB *data) | |
68 | +{ | |
69 | + UB segid = segment & 0xFF; | |
70 | + UB subid = *(UH*)data >> 8; | |
71 | + //UB attr = *(UH*)data & 0xff; | |
72 | + RATIO w_ratio,h_ratio; | |
73 | + W ratio_a, ratio_b; | |
74 | + | |
75 | + if (segid == TS_TFONT) { | |
76 | + switch (subid) { | |
77 | + case 3: | |
78 | + w_ratio = *(RATIO*)(data + 4); | |
79 | + h_ratio = *(RATIO*)(data + 2); | |
80 | + ratio_a = w_ratio >> 8; | |
81 | + ratio_b = w_ratio & 0xFF; | |
82 | + if ((ratio_a * 2 > ratio_b)||(ratio_b == 0)) { | |
83 | + return BCHANK_SEGCHECK_RESULT_ZENKAKU; | |
84 | + } else { | |
85 | + return BCHANK_SEGCHECK_RESULT_HANKAKU; | |
86 | + } | |
87 | + break; | |
88 | + default: | |
89 | + break; | |
90 | + } | |
91 | + } | |
92 | + return BCHANK_SEGCHECK_RESULT_OTHER; | |
93 | +} | |
94 | + | |
95 | +/* pos is charactor index ignoring variable segment. */ | |
96 | +EXPORT W bchank_line_inserttext(bchank_line_t *line, W pos, TC *str, W len) | |
97 | +{ | |
98 | +} | |
99 | + | |
100 | +EXPORT W bchank_line_removetext(bchank_line_t *line, W pos, W len) | |
101 | +{ | |
102 | +} | |
103 | + | |
104 | +LOCAL bchank_line_t* bchank_line_new() | |
105 | +{ | |
106 | + bchank_line_t *line; | |
107 | + | |
108 | + line = (bchank_line_t*)malloc(sizeof(bchank_line_t)); | |
109 | + if (line == NULL) { | |
110 | + return NULL; | |
111 | + } | |
112 | + QueInit(&line->que); | |
113 | + tadfragment_initialize(&line->fragment); | |
114 | + line->pos = NULL; | |
115 | + line->pos_len = 0; | |
116 | + | |
117 | + return line; | |
118 | +} | |
119 | + | |
120 | +LOCAL VOID bchank_line_delete(bchank_line_t *line) | |
121 | +{ | |
122 | + QueRemove(&line->que); | |
123 | + tadfragment_finalize(&line->fragment); | |
124 | + if (line->pos != NULL) { | |
125 | + free(line->pos); | |
126 | + } | |
127 | + free(line); | |
128 | +} | |
129 | + | |
130 | +struct bchank_linelist_t_ { | |
131 | + QUEUE sentinel; | |
132 | + W len; | |
133 | + bchank_genv_t *config; | |
134 | +}; | |
135 | + | |
136 | +LOCAL bchank_line_t* bchank_linelist_getsentinel(bchank_linelist_t *list) | |
137 | +{ | |
138 | + return (bchank_line_t*)&list->sentinel; | |
139 | +} | |
140 | + | |
141 | +EXPORT bchank_line_t* bchank_linelist_get(bchank_linelist_t *list, W at) | |
142 | +{ | |
143 | + bchank_line_t *sentinel, *node; | |
144 | + W i; | |
145 | + | |
146 | + if (list->len == 0) { | |
147 | + return NULL; | |
148 | + } | |
149 | + if (list->len <= at) { | |
150 | + return NULL; | |
151 | + } | |
152 | + | |
153 | + sentinel = bchank_linelist_getsentinel(list); | |
154 | + node = bchank_line_getnext(sentinel); | |
155 | + for (i = 0; i < at; i++) { | |
156 | + node = bchank_line_getnext(node); | |
157 | + } | |
158 | + | |
159 | + return node; | |
160 | +} | |
161 | + | |
162 | +EXPORT bchank_line_t* bchank_linelist_insert(bchank_linelist_t *list, W at) | |
163 | +{ | |
164 | + bchank_line_t *line, *line_new; | |
165 | + | |
166 | + if (at != list->len) { | |
167 | + line = bchank_linelist_get(list, at); | |
168 | + if (line == NULL) { | |
169 | + return NULL; | |
170 | + } | |
171 | + } else { | |
172 | + line = bchank_linelist_getsentinel(list); | |
173 | + } | |
174 | + | |
175 | + line_new = bchank_line_new(); | |
176 | + if (line_new == NULL) { | |
177 | + return NULL; | |
178 | + } | |
179 | + | |
180 | + bchank_line_insert(line_new, line); | |
181 | + list->len++; | |
182 | + | |
183 | + return line_new; | |
184 | +} | |
185 | + | |
186 | +EXPORT bchank_line_t* bchank_linelist_append(bchank_linelist_t *list) | |
187 | +{ | |
188 | + return bchank_linelist_insert(list, list->len); | |
189 | +} | |
190 | + | |
191 | +EXPORT W bchank_linelist_length(bchank_linelist_t *list) | |
192 | +{ | |
193 | + return list->len; | |
194 | +} | |
195 | + | |
196 | +EXPORT W bchank_linelist_calclinewidth(bchank_linelist_t *list, bchank_line_t *line, GID target) | |
197 | +{ | |
198 | + taditerator_t iterator; | |
199 | + taditerator_result result; | |
200 | + TC *start = NULL; | |
201 | + W len = 0, w = 0, bin_len; | |
202 | + TC *bin; | |
203 | + BCHANK_SEGCHECK_RESULT segcheck; | |
204 | + | |
205 | + bchank_genv_resetfont(list->config, target, NULL); | |
206 | + | |
207 | + bin = (TC*)tadfragment_getbuffer(&line->fragment); | |
208 | + bin_len = tadfragment_getbufferlength(&line->fragment) / sizeof(TC); | |
209 | + | |
210 | + taditerator_initialize(&iterator, bin, bin_len); | |
211 | + for (;;) { | |
212 | + taditerator_next2(&iterator, &result); | |
213 | + if (result.type == TADITERATOR_RESULTTYPE_END) { | |
214 | + if (start != NULL) { | |
215 | + w += gget_stw(target, start, len, NULL, NULL); | |
216 | + start = NULL; | |
217 | + len = 0; | |
218 | + } | |
219 | + break; | |
220 | + } else if (result.type == TADITERATOR_RESULTTYPE_CHARCTOR) { | |
221 | + if (start == NULL) { | |
222 | + start = result.pos; | |
223 | + } | |
224 | + len++; | |
225 | + } else if (result.type == TADITERATOR_RESULTTYPE_SEGMENT) { | |
226 | + if (start != NULL) { | |
227 | + w += gget_stw(target, start, len, NULL, NULL); | |
228 | + start = NULL; | |
229 | + len = 0; | |
230 | + } | |
231 | + | |
232 | + segcheck = check_segment(result.segment, result.segsize, result.data); | |
233 | + if (segcheck == BCHANK_SEGCHECK_RESULT_HANKAKU) { | |
234 | + bchank_genv_sethankaku(list->config, target); | |
235 | + } else if (segcheck == BCHANK_SEGCHECK_RESULT_ZENKAKU) { | |
236 | + bchank_genv_setzenkaku(list->config, target); | |
237 | + } | |
238 | + } | |
239 | + } | |
240 | + taditerator_finalize(&iterator); | |
241 | + | |
242 | + return w; | |
243 | +} | |
244 | + | |
245 | +EXPORT W bchank_linelist_drawline(bchank_linelist_t *list, bchank_line_t *line, GID target) | |
246 | +{ | |
247 | + taditerator_t iterator; | |
248 | + taditerator_result result; | |
249 | + TC *start = NULL; | |
250 | + W len = 0, bin_len; | |
251 | + TC *bin; | |
252 | + BCHANK_SEGCHECK_RESULT segcheck; | |
253 | + | |
254 | + bchank_genv_resetfont(list->config, target, NULL); | |
255 | + | |
256 | + bin = (TC*)tadfragment_getbuffer(&line->fragment); | |
257 | + bin_len = tadfragment_getbufferlength(&line->fragment) / sizeof(TC); | |
258 | + | |
259 | + taditerator_initialize(&iterator, bin, bin_len); | |
260 | + for (;;) { | |
261 | + taditerator_next2(&iterator, &result); | |
262 | + if (result.type == TADITERATOR_RESULTTYPE_END) { | |
263 | + if (start != NULL) { | |
264 | + gdra_str (target, start, len, G_STORE); | |
265 | + start = NULL; | |
266 | + len = 0; | |
267 | + } | |
268 | + break; | |
269 | + } else if (result.type == TADITERATOR_RESULTTYPE_CHARCTOR) { | |
270 | + if (start == NULL) { | |
271 | + start = result.pos; | |
272 | + } | |
273 | + len++; | |
274 | + } else if (result.type == TADITERATOR_RESULTTYPE_SEGMENT) { | |
275 | + if (start != NULL) { | |
276 | + gdra_str (target, start, len, G_STORE); | |
277 | + start = NULL; | |
278 | + len = 0; | |
279 | + } | |
280 | + | |
281 | + segcheck = check_segment(result.segment, result.segsize, result.data); | |
282 | + if (segcheck == BCHANK_SEGCHECK_RESULT_HANKAKU) { | |
283 | + bchank_genv_sethankaku(list->config, target); | |
284 | + } else if (segcheck == BCHANK_SEGCHECK_RESULT_ZENKAKU) { | |
285 | + bchank_genv_setzenkaku(list->config, target); | |
286 | + } | |
287 | + } | |
288 | + } | |
289 | + taditerator_finalize(&iterator); | |
290 | + | |
291 | + return 0; | |
292 | +} | |
293 | + | |
294 | +LOCAL VOID bchank_linelist_initialize(bchank_linelist_t *list, bchank_genv_t *genv) | |
295 | +{ | |
296 | + QueInit(&list->sentinel); | |
297 | + list->len = 0; | |
298 | + list->config = genv; | |
299 | +} | |
300 | + | |
301 | +LOCAL VOID bchank_linelist_finalize(bchank_linelist_t *list) | |
302 | +{ | |
303 | + bchank_line_t *sentinel, *node; | |
304 | + sentinel = bchank_linelist_getsentinel(list); | |
305 | + for (;;) { | |
306 | + node = bchank_line_getnext(sentinel); | |
307 | + if (node == sentinel) { | |
308 | + break; | |
309 | + } | |
310 | + bchank_line_delete(node); | |
311 | + } | |
312 | +} | |
313 | + | |
314 | +EXPORT bchank_linelist_t* bchank_linelist_new(bchank_genv_t *genv) | |
315 | +{ | |
316 | + bchank_linelist_t *list; | |
317 | + | |
318 | + list = (bchank_linelist_t*)malloc(sizeof(bchank_linelist_t)); | |
319 | + if (list == NULL) { | |
320 | + return NULL; | |
321 | + } | |
322 | + bchank_linelist_initialize(list, genv); | |
323 | + | |
324 | + return list; | |
325 | +} | |
326 | + | |
327 | +EXPORT VOID bchank_linelist_delete(bchank_linelist_t *list) | |
328 | +{ | |
329 | + bchank_linelist_finalize(list); | |
330 | + free(list); | |
331 | +} |
@@ -0,0 +1,50 @@ | ||
1 | +/* | |
2 | + * bchank_lines.h | |
3 | + * | |
4 | + * Copyright (c) 2013 project bchan | |
5 | + * | |
6 | + * This software is provided 'as-is', without any express or implied | |
7 | + * warranty. In no event will the authors be held liable for any damages | |
8 | + * arising from the use of this software. | |
9 | + * | |
10 | + * Permission is granted to anyone to use this software for any purpose, | |
11 | + * including commercial applications, and to alter it and redistribute it | |
12 | + * freely, subject to the following restrictions: | |
13 | + * | |
14 | + * 1. The origin of this software must not be misrepresented; you must not | |
15 | + * claim that you wrote the original software. If you use this software | |
16 | + * in a product, an acknowledgment in the product documentation would be | |
17 | + * appreciated but is not required. | |
18 | + * | |
19 | + * 2. Altered source versions must be plainly marked as such, and must not be | |
20 | + * misrepresented as being the original software. | |
21 | + * | |
22 | + * 3. This notice may not be removed or altered from any source | |
23 | + * distribution. | |
24 | + * | |
25 | + */ | |
26 | + | |
27 | +#include <basic.h> | |
28 | +#include <btron/hmi.h> | |
29 | + | |
30 | +#include "bchank_genv.h" | |
31 | + | |
32 | +#ifndef __BCHANK_LINES_H__ | |
33 | +#define __BCHANK_LINES_H__ | |
34 | + | |
35 | +typedef struct bchank_line_t_ bchank_line_t; | |
36 | + | |
37 | +IMPORT W bchank_line_appendtext(bchank_line_t *line, TC *str, W len); | |
38 | +IMPORT W bchank_line_inserttext(bchank_line_t *line, W pos, TC *str, W len); | |
39 | +IMPORT W bchank_line_removetext(bchank_line_t *line, W pos, W len); | |
40 | + | |
41 | +typedef struct bchank_linelist_t_ bchank_linelist_t; | |
42 | + | |
43 | +IMPORT bchank_linelist_t* bchank_linelist_new(bchank_genv_t *genv); | |
44 | +IMPORT VOID bchank_linelist_delete(bchank_linelist_t *list); | |
45 | +IMPORT bchank_line_t* bchank_linelist_get(bchank_linelist_t *list, W at); | |
46 | +IMPORT bchank_line_t* bchank_linelist_append(bchank_linelist_t *list); | |
47 | +IMPORT W bchank_linelist_calclinewidth(bchank_linelist_t *list, bchank_line_t *line, GID target); | |
48 | +IMPORT W bchank_linelist_drawline(bchank_linelist_t *list, bchank_line_t *line, GID target); | |
49 | + | |
50 | +#endif |