implement chekc each character's state for text insert.
@@ -0,0 +1,240 @@ | ||
1 | +/* | |
2 | + * test_texteditor_characterstate.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 "test_control.h" | |
28 | + | |
29 | +#include "texteditor_characterstate.h" | |
30 | + | |
31 | +#include <basic.h> | |
32 | +#include <bstdio.h> | |
33 | +#include <bstdlib.h> | |
34 | +#include <bstring.h> | |
35 | +#include <tstring.h> | |
36 | + | |
37 | +#include <unittest_driver.h> | |
38 | + | |
39 | +typedef struct { | |
40 | + tadfragment_cursor_segment input; | |
41 | + struct { | |
42 | + TC *lang; | |
43 | + W lang_len; | |
44 | + Bool is_hankaku; | |
45 | + } expected; | |
46 | +} test_texteditor_characterstate_t; | |
47 | + | |
48 | +LOCAL UNITTEST_RESULT test_texteditor_characterstate_common(test_texteditor_characterstate_t *testdata, W len) | |
49 | +{ | |
50 | + texteditor_characterstate_t state; | |
51 | + W i, err; | |
52 | + Bool is_hankaku, ok; | |
53 | + TC *lang, lang_len; | |
54 | + UNITTEST_RESULT result = UNITTEST_RESULT_PASS; | |
55 | + | |
56 | + texteditor_characterstate_initialize(&state); | |
57 | + | |
58 | + for (i = 0; i < len; i++) { | |
59 | + err = texteditor_charactorstate_input(&state, &(testdata[i].input)); | |
60 | + if (err < 0) { | |
61 | + printf("[%d] texteditor_charactorstate_input error\n", i); | |
62 | + result = UNITTEST_RESULT_FAIL; | |
63 | + break; | |
64 | + } | |
65 | + is_hankaku = texteditor_characterstate_ishankaku(&state); | |
66 | + if (is_hankaku != False) { | |
67 | + if (testdata[i].expected.is_hankaku == False) { | |
68 | + printf("[%d] ishankaku error\n", i); | |
69 | + result = UNITTEST_RESULT_FAIL; | |
70 | + } | |
71 | + } else { | |
72 | + if (testdata[i].expected.is_hankaku != False) { | |
73 | + printf("[%d] ishankaku error\n", i); | |
74 | + result = UNITTEST_RESULT_FAIL; | |
75 | + } | |
76 | + } | |
77 | + | |
78 | + ok = texteditor_characterstate_islang(&state, testdata[i].expected.lang, testdata[i].expected.lang_len); | |
79 | + if (ok == False) { | |
80 | + printf("[%d] islang error\n", i); | |
81 | + result = UNITTEST_RESULT_FAIL; | |
82 | + } | |
83 | + | |
84 | + lang_len = texteditor_characterstate_getlang(&state, NULL, -1); | |
85 | + if (lang_len != testdata[i].expected.lang_len) { | |
86 | + printf("[%d] getlang length 1 error. expected = %d, result = %d\n", i, testdata[i].expected.lang_len, lang_len); | |
87 | + result = UNITTEST_RESULT_FAIL; | |
88 | + } | |
89 | + | |
90 | + lang = malloc(sizeof(TC)*testdata[i].expected.lang_len); | |
91 | + lang_len = texteditor_characterstate_getlang(&state, lang, testdata[i].expected.lang_len); | |
92 | + if (lang_len != testdata[i].expected.lang_len) { | |
93 | + printf("[%d] getlang length 2 error. expected = %d, result = %d\n", i, testdata[i].expected.lang_len, lang_len); | |
94 | + result = UNITTEST_RESULT_FAIL; | |
95 | + } else { | |
96 | + if (tc_strncmp(lang, testdata[i].expected.lang, lang_len) != 0) { | |
97 | + printf("[%d] getlang code error\n", i); | |
98 | + result = UNITTEST_RESULT_FAIL; | |
99 | + } | |
100 | + } | |
101 | + free(lang); | |
102 | + } | |
103 | + | |
104 | + texteditor_characterstate_finalize(&state); | |
105 | + | |
106 | + return result; | |
107 | +} | |
108 | + | |
109 | +LOCAL UNITTEST_RESULT test_texteditor_characterstate_1() | |
110 | +{ | |
111 | + test_texteditor_characterstate_t testdata[] = { | |
112 | + { | |
113 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_LANGCODE, (UB[]){0x21, 0xFE}, 2}, | |
114 | + {(TC[]){0xFE21}, 1, False} | |
115 | + }, | |
116 | + { | |
117 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_LANGCODE, (UB[]){0x22, 0xFE}, 2}, | |
118 | + {(TC[]){0xFE22}, 1, False} | |
119 | + }, | |
120 | + { | |
121 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_LANGCODE, (UB[]){0xFE, 0xFE, 0x21, 0xFE}, 4}, | |
122 | + {(TC[]){0xFEFE, 0xFE21}, 2, False} | |
123 | + }, | |
124 | + { | |
125 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_LANGCODE, (UB[]){0xFE, 0xFE, 0x21, 0x00}, 4}, | |
126 | + {(TC[]){0xFEFE, 0x0021}, 2, False} | |
127 | + }, | |
128 | + { | |
129 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_LANGCODE, (UB[]){0xFE, 0xFE, 0xFE, 0xFE, 0x21, 0xFE}, 6}, | |
130 | + {(TC[]){0xFEFE, 0xFEFE, 0xFE21}, 3, False} | |
131 | + }, | |
132 | + { | |
133 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_LANGCODE, (UB[]){0xFE, 0xFE, 0xFE, 0xFE, 0x21, 0x00}, 6}, | |
134 | + {(TC[]){0xFEFE, 0xFEFE, 0x0021}, 3, False} | |
135 | + } | |
136 | + }; | |
137 | + return test_texteditor_characterstate_common(testdata, 6); | |
138 | +} | |
139 | + | |
140 | +LOCAL UNITTEST_RESULT test_texteditor_characterstate_2() | |
141 | +{ | |
142 | + test_texteditor_characterstate_t testdata[] = { | |
143 | + { | |
144 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_CHAR, (UB[]){0x21, 0x21}, 2}, | |
145 | + {(TC[]){0xFE21}, 1, False} | |
146 | + }, | |
147 | + { | |
148 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_LANGCODE, (UB[]){0x22, 0xFE}, 2}, | |
149 | + {(TC[]){0xFE22}, 1, False} | |
150 | + }, | |
151 | + { | |
152 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_CHAR, (UB[]){0x21, 0x21}, 2}, | |
153 | + {(TC[]){0xFE22}, 1, False} | |
154 | + }, | |
155 | + { | |
156 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_LANGCODE, (UB[]){0x21, 0xFE}, 2}, | |
157 | + {(TC[]){0xFE21}, 1, False} | |
158 | + }, | |
159 | + { | |
160 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_CHAR, (UB[]){0x21, 0x21}, 2}, | |
161 | + {(TC[]){0xFE21}, 1, False} | |
162 | + }, | |
163 | + }; | |
164 | + return test_texteditor_characterstate_common(testdata, 5); | |
165 | +} | |
166 | + | |
167 | +LOCAL UNITTEST_RESULT test_texteditor_characterstate_3() | |
168 | +{ | |
169 | + test_texteditor_characterstate_t testdata[] = { | |
170 | + { | |
171 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_VARIABLE, (UB[]){0xA2, 0xFF, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00}, 10}, | |
172 | + {(TC[]){0xFE21}, 1, False} | |
173 | + }, | |
174 | + { | |
175 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_VARIABLE, (UB[]){0xA2, 0xFF, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x01}, 10}, | |
176 | + {(TC[]){0xFE21}, 1, True} | |
177 | + }, | |
178 | + { | |
179 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_VARIABLE, (UB[]){0xA2, 0xFF, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00}, 10}, | |
180 | + {(TC[]){0xFE21}, 1, False} | |
181 | + }, | |
182 | + { | |
183 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_VARIABLE, (UB[]){0xA2, 0xFF, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x01}, 10}, | |
184 | + {(TC[]){0xFE21}, 1, True} | |
185 | + }, | |
186 | + { | |
187 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_VARIABLE, (UB[]){0xA2, 0xFF, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x01}, 10}, | |
188 | + {(TC[]){0xFE21}, 1, False} | |
189 | + }, | |
190 | + }; | |
191 | + return test_texteditor_characterstate_common(testdata, 5); | |
192 | +} | |
193 | + | |
194 | + | |
195 | +LOCAL UNITTEST_RESULT test_texteditor_characterstate_4() | |
196 | +{ | |
197 | + test_texteditor_characterstate_t testdata[] = { | |
198 | + { | |
199 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_VARIABLE, (UB[]){0xA2, 0xFF, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x01}, 10}, | |
200 | + {(TC[]){0xFE21}, 1, True} | |
201 | + }, | |
202 | + { | |
203 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_CHAR, (UB[]){0x21, 0x21}, 2}, | |
204 | + {(TC[]){0xFE21}, 1, True} | |
205 | + }, | |
206 | + { | |
207 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_LANGCODE, (UB[]){0x22, 0xFE}, 2}, | |
208 | + {(TC[]){0xFE22}, 1, True} | |
209 | + }, | |
210 | + { | |
211 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_CHAR, (UB[]){0x21, 0x21}, 2}, | |
212 | + {(TC[]){0xFE22}, 1, True} | |
213 | + }, | |
214 | + { | |
215 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_VARIABLE, (UB[]){0xA2, 0xFF, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00}, 10}, | |
216 | + {(TC[]){0xFE22}, 1, False} | |
217 | + }, | |
218 | + { | |
219 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_CHAR, (UB[]){0x21, 0x21}, 2}, | |
220 | + {(TC[]){0xFE22}, 1, False} | |
221 | + }, | |
222 | + { | |
223 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_LANGCODE, (UB[]){0x21, 0xFE}, 2}, | |
224 | + {(TC[]){0xFE21}, 1, False} | |
225 | + }, | |
226 | + { | |
227 | + {TADFRAGMENT_CURSOR_SEGMENTTYPE_CHAR, (UB[]){0x21, 0x21}, 2}, | |
228 | + {(TC[]){0xFE21}, 1, False} | |
229 | + }, | |
230 | + }; | |
231 | + return test_texteditor_characterstate_common(testdata, 8); | |
232 | +} | |
233 | + | |
234 | +EXPORT VOID test_texteditor_characterstate_main(unittest_driver_t *driver) | |
235 | +{ | |
236 | + UNITTEST_DRIVER_REGIST(driver, test_texteditor_characterstate_1); | |
237 | + UNITTEST_DRIVER_REGIST(driver, test_texteditor_characterstate_2); | |
238 | + UNITTEST_DRIVER_REGIST(driver, test_texteditor_characterstate_3); | |
239 | + UNITTEST_DRIVER_REGIST(driver, test_texteditor_characterstate_4); | |
240 | +} |
@@ -0,0 +1,134 @@ | ||
1 | +/* | |
2 | + * texteditor_characterstate.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 "texteditor_characterstate.h" | |
28 | + | |
29 | +#include <bstdio.h> | |
30 | + | |
31 | +#ifdef BCHAN_CONFIG_DEBUG | |
32 | +# define DP(arg) printf arg | |
33 | +# define DP_ER(msg, err) printf("%s (%d/%x)\n", msg, err>>16, err) | |
34 | +#else | |
35 | +# define DP(arg) /**/ | |
36 | +# define DP_ER(msg, err) /**/ | |
37 | +#endif | |
38 | + | |
39 | +EXPORT W texteditor_charactorstate_input(texteditor_characterstate_t *state, tadfragment_cursor_segment *segment) | |
40 | +{ | |
41 | + TC ch; | |
42 | + W iter; | |
43 | + UB segid, subid; | |
44 | + | |
45 | + if (segment->type == TADFRAGMENT_CURSOR_SEGMENTTYPE_VARIABLE) { | |
46 | + if (segment->len != 10) { | |
47 | + return 0; | |
48 | + } | |
49 | + segid = *(TC*)segment->p & 0xFF; | |
50 | + if (segid != TS_TFONT) { | |
51 | + return 0; | |
52 | + } | |
53 | + subid = *(TC*)(segment->p + 4) >> 8; | |
54 | + if (subid != 3) { | |
55 | + return 0; | |
56 | + } | |
57 | + state->w_ratio = *(RATIO*)(segment->p + 8); | |
58 | + } else if (segment->type == TADFRAGMENT_CURSOR_SEGMENTTYPE_LANGCODE) { | |
59 | + ch = *(TC*)(segment->p + segment->len - 2); | |
60 | + iter = segment->len - 2; | |
61 | + if ((ch & 0xFE00) == 0xFE00) { | |
62 | + iter++; | |
63 | + } | |
64 | + state->lang.iter = iter - 1; | |
65 | + state->lang.code = 0x00FF & ch; | |
66 | + } | |
67 | + return 0; | |
68 | +} | |
69 | + | |
70 | +EXPORT Bool texteditor_characterstate_ishankaku(texteditor_characterstate_t *state) | |
71 | +{ | |
72 | + W ratio_a, ratio_b; | |
73 | + | |
74 | + ratio_a = state->w_ratio >> 8; | |
75 | + ratio_b = state->w_ratio & 0xFF; | |
76 | + if ((ratio_a * 2 > ratio_b)||(ratio_b == 0)) { | |
77 | + return False; | |
78 | + } else { | |
79 | + return True; | |
80 | + } | |
81 | +} | |
82 | + | |
83 | +EXPORT W texteditor_characterstate_getlang(texteditor_characterstate_t *state, TC *str, W len) | |
84 | +{ | |
85 | + W i, req_len; | |
86 | + | |
87 | + req_len = 2 + (state->lang.iter+1)/2*2; | |
88 | + | |
89 | + if (str == NULL || len < 0) { | |
90 | + return req_len / sizeof(TC); | |
91 | + } | |
92 | + | |
93 | + for (i = 0; i < (state->lang.iter + 1) / 2; i++) { | |
94 | + str[i] = 0xFEFE; | |
95 | + } | |
96 | + if (state->lang.iter % 2 == 1) { | |
97 | + str[i] = state->lang.code; | |
98 | + } else { | |
99 | + str[i] = 0xFE00 | state->lang.code; | |
100 | + } | |
101 | + | |
102 | + return req_len / sizeof(TC); | |
103 | +} | |
104 | + | |
105 | +EXPORT Bool texteditor_characterstate_islang(texteditor_characterstate_t *state, TC *str, W len) | |
106 | +{ | |
107 | + TC ch; | |
108 | + W iter; | |
109 | + UH code; | |
110 | + | |
111 | + ch = str[len - 1]; | |
112 | + iter = (len - 1) * 2; | |
113 | + if ((ch & 0xFE00) == 0xFE00) { | |
114 | + iter++; | |
115 | + } | |
116 | + iter--; | |
117 | + code = 0x00FF & ch; | |
118 | + | |
119 | + if ((state->lang.iter == iter)&&(state->lang.code == code)) { | |
120 | + return True; | |
121 | + } | |
122 | + return False; | |
123 | +} | |
124 | + | |
125 | +EXPORT VOID texteditor_characterstate_initialize(texteditor_characterstate_t *state) | |
126 | +{ | |
127 | + state->w_ratio = 0x0101; | |
128 | + state->lang.iter = 0; | |
129 | + state->lang.code = 0x21; // system script | |
130 | +} | |
131 | + | |
132 | +EXPORT VOID texteditor_characterstate_finalize(texteditor_characterstate_t *state) | |
133 | +{ | |
134 | +} |
@@ -0,0 +1,52 @@ | ||
1 | +/* | |
2 | + * texteditor_characterstate.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 | + | |
29 | +#include <tad/tadfragment.h> | |
30 | + | |
31 | +#ifndef __TEXTEDITOR_CHARACTERSTATE_H__ | |
32 | +#define __TEXTEDITOR_CHARACTERSTATE_H__ | |
33 | + | |
34 | +/* Functionality name: texteditor */ | |
35 | +/* Detail name: characterstate */ | |
36 | +struct texteditor_characterstate_t_ { | |
37 | + RATIO w_ratio; | |
38 | + struct { | |
39 | + UW iter; | |
40 | + UB code; | |
41 | + } lang; | |
42 | +}; | |
43 | +typedef struct texteditor_characterstate_t_ texteditor_characterstate_t; | |
44 | + | |
45 | +IMPORT VOID texteditor_characterstate_initialize(texteditor_characterstate_t *state); | |
46 | +IMPORT VOID texteditor_characterstate_finalize(texteditor_characterstate_t *state); | |
47 | +IMPORT W texteditor_charactorstate_input(texteditor_characterstate_t *state, tadfragment_cursor_segment *segment); | |
48 | +IMPORT Bool texteditor_characterstate_ishankaku(texteditor_characterstate_t *state); | |
49 | +IMPORT W texteditor_characterstate_getlang(texteditor_characterstate_t *state, TC *str, W len); | |
50 | +IMPORT Bool texteditor_characterstate_islang(texteditor_characterstate_t *state, TC *str, W len); | |
51 | + | |
52 | +#endif |