2 * texteditor_insertfilter.c
4 * Copyright (c) 2014 project bchan
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.
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:
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.
19 * 2. Altered source versions must be plainly marked as such, and must not be
20 * misrepresented as being the original software.
22 * 3. This notice may not be removed or altered from any source
27 #include "texteditor_insertfilter.h"
32 #include <tad/taditerator.h>
33 #include <tad/tadstack.h>
35 #include "texteditor_stackfilter.h"
37 #ifdef BCHAN_CONFIG_DEBUG
38 # define DP(arg) printf arg
39 # define DP_ER(msg, err) printf("%s (%d/%x)\n", msg, err>>16, err)
42 # define DP_ER(msg, err) /**/
46 #define DP_STATE(s) printf("%s\n", s)
48 #define DP_STATE(s) /**/
53 LOCAL Bool texteditor_insertfilter_w_ratio_isZenkaku(RATIO w_ratio)
69 LOCAL Bool texteditor_insertfilter_w_ratio_isSystemScript(tadlangcode *lang)
71 return tadlangcodecmpTC((TC[]){0xFE21}, 1, lang);
76 LOCAL TC textediter_insertfilter_zenkakufusen[] = { 0xFFA2, 0x0006, 0x0300, 0x0101, 0x0101 };
77 LOCAL TC textediter_insertfilter_hankakufusen[] = { 0xFFA2, 0x0006, 0x0300, 0x0101, 0x0102 };
78 #define TEXTEDITOR_INSERTFILTER_FUSEN_LENGTH 5
80 LOCAL VOID texteditor_insertfilter_pushback_segment(texteditor_insertfilter_t *filter, tadsegment *segment)
82 assert(filter->result_buffer.used < TEXTEDITOR_INSERTFILTER_RESULT_BUFFER_LEN);
83 filter->result_buffer.segs[filter->result_buffer.used] = *segment;
84 filter->result_buffer.used++;
87 LOCAL VOID texteditor_insertfilter_pushback_zenkakufusen(texteditor_insertfilter_t *filter)
90 segment.type = TADSEGMENT_TYPE_VARIABLE;
91 segment.value.variable.raw = (UB*)textediter_insertfilter_zenkakufusen;
92 segment.value.variable.rawlen = TEXTEDITOR_INSERTFILTER_FUSEN_LENGTH * sizeof(TC);
93 texteditor_insertfilter_pushback_segment(filter, &segment);
96 LOCAL VOID texteditor_insertfilter_pushback_hankakufusen(texteditor_insertfilter_t *filter)
99 segment.type = TADSEGMENT_TYPE_VARIABLE;
100 segment.value.variable.raw = (UB*)textediter_insertfilter_hankakufusen;
101 segment.value.variable.rawlen = TEXTEDITOR_INSERTFILTER_FUSEN_LENGTH * sizeof(TC);
102 texteditor_insertfilter_pushback_segment(filter, &segment);
105 LOCAL VOID texteditor_insertfilter_pushback_systemlangcode(texteditor_insertfilter_t *filter)
108 segment.type = TADSEGMENT_TYPE_LANGCODE;
109 segment.value.lang = (tadlangcode){0, 0x21};
110 texteditor_insertfilter_pushback_segment(filter, &segment);
113 LOCAL VOID texteditor_insertfilter_pushback_firstlangcode(texteditor_insertfilter_t *filter)
116 segment.type = TADSEGMENT_TYPE_LANGCODE;
117 segment.value.lang = filter->first.lang;
118 texteditor_insertfilter_pushback_segment(filter, &segment);
121 LOCAL W texteditor_insertfilter_put_filtering(texteditor_insertfilter_t *filter, tadsegment *segment)
126 UB segid, subid, *segdata;
128 texteditor_stackfilterresult_t *stack_result;
130 ret = texteditor_stackfilter_put(&filter->stack, segment, &stack_result);
131 if (ret == TEXTEDITOR_STACKFILTER_PUT_RESULT_FORMAT_ERROR) {
132 return TEXTEDITOR_INSERTFILTER_PUT_RESULT_FORMAT_ERROR;
135 cont = texteditor_stackfilterresult_next(stack_result, &result);
140 if (result->type == TADSEGMENT_TYPE_VARIABLE) {
141 tadsegment_getvariable(result, &segid, &seglen, &segdata);
142 if (segid != TS_TFONT) {
148 subid = *(UH*)segdata >> 8;
153 filter->current.w_ratio = *((UH*)segdata + 5);
154 } else if (result->type == TADSEGMENT_TYPE_LANGCODE) {
155 filter->current.lang = result->value.lang;
158 texteditor_insertfilter_pushback_segment(filter, result);
161 return TEXTEDITOR_INSERTFILTER_PUT_RESULT_OK;
164 LOCAL W texteditor_insertfilter_put_state_start(texteditor_insertfilter_t *filter, tadsegment *segment, texteditor_insertfilterresult_t **result)
168 ok = texteditor_insertfilter_w_ratio_isZenkaku(filter->first.w_ratio);
170 texteditor_insertfilter_pushback_zenkakufusen(filter);
172 ok = texteditor_insertfilter_w_ratio_isSystemScript(&filter->first.lang);
174 texteditor_insertfilter_pushback_systemlangcode(filter);
177 *result = &filter->result;
179 filter->state = TEXTEDITOR_INSERTFILTER_STATE_RUNNING;
181 return texteditor_insertfilter_put_filtering(filter, segment);
184 LOCAL W texteditor_insertfilter_put_state_running(texteditor_insertfilter_t *filter, tadsegment *segment, texteditor_insertfilterresult_t **result)
186 filter->result_buffer.used = 0;
187 filter->result_buffer.consumed = 0;
189 *result = &filter->result;
191 return texteditor_insertfilter_put_filtering(filter, segment);
194 EXPORT W texteditor_insertfilter_put(texteditor_insertfilter_t *filter, tadsegment *segment, texteditor_insertfilterresult_t **result)
196 switch (filter->state) {
197 case TEXTEDITOR_INSERTFILTER_STATE_START:
198 DP_STATE("put:STATE_START");
199 return texteditor_insertfilter_put_state_start(filter, segment, result);
200 case TEXTEDITOR_INSERTFILTER_STATE_RUNNING:
201 DP_STATE("put:STATE_RUNNING");
202 return texteditor_insertfilter_put_state_running(filter, segment, result);
203 case TEXTEDITOR_INSERTFILTER_STATE_END:
204 DP_STATE("put:STATE_END");
205 return TEXTEDITOR_INSERTFILTER_PUT_RESULT_FORMAT_ERROR;
207 return TEXTEDITOR_INSERTFILTER_PUT_RESULT_FORMAT_ERROR;
210 EXPORT VOID texteditor_insertfilter_endinput(texteditor_insertfilter_t *filter, texteditor_insertfilterresult_t **result)
214 filter->result_buffer.used = 0;
215 filter->result_buffer.consumed = 0;
216 *result = &filter->result;
218 switch (filter->state) {
219 case TEXTEDITOR_INSERTFILTER_STATE_START:
220 DP_STATE("end:STATE_START");
222 case TEXTEDITOR_INSERTFILTER_STATE_RUNNING:
223 DP_STATE("end:STATE_RUNNING");
224 if (filter->first.w_ratio != filter->current.w_ratio) {
225 zen = texteditor_insertfilter_w_ratio_isZenkaku(filter->first.w_ratio);
227 texteditor_insertfilter_pushback_hankakufusen(filter);
229 texteditor_insertfilter_pushback_zenkakufusen(filter);
232 ok = tadlangcodecmp(&filter->first.lang, &filter->current.lang);
234 texteditor_insertfilter_pushback_firstlangcode(filter);
237 case TEXTEDITOR_INSERTFILTER_STATE_END:
238 DP_STATE("end:STATE_END");
243 EXPORT Bool texteditor_insertfilterresult_next(texteditor_insertfilterresult_t *result, tadsegment **segment)
245 texteditor_insertfilter_t *filter = result->filter;
247 if (filter->result_buffer.consumed >= filter->result_buffer.used) {
251 *segment = filter->result_buffer.segs + filter->result_buffer.consumed;
252 filter->result_buffer.consumed++;
254 if (filter->result_buffer.consumed >= filter->result_buffer.used) {
255 filter->result_buffer.used = 0;
256 filter->result_buffer.consumed = 0;
262 EXPORT VOID texteditor_insertfilter_initialize(texteditor_insertfilter_t *filter, tadlangcode *lang, RATIO w_ratio)
264 texteditor_stackfilter_initialize(&filter->stack);
265 filter->state = TEXTEDITOR_INSERTFILTER_STATE_START;
266 filter->first.lang = *lang;
267 filter->first.w_ratio = w_ratio;
268 filter->current.lang = (tadlangcode){0, 0x21};
269 filter->current.w_ratio = 0x0101;
270 filter->result_buffer.used = 0;
271 filter->result_buffer.consumed = 0;
272 filter->result.filter = filter;
275 EXPORT VOID texteditor_insertfilter_finalize(texteditor_insertfilter_t *filter)
277 texteditor_stackfilter_finalize(&filter->stack);