4 * Copyright (c) 2009-2010 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 "subjectlayout.h"
28 #include "subjectparser.h"
35 #include <btron/btron.h>
39 #ifdef BCHANL_CONFIG_DEBUG
40 # define DP(arg) printf arg
41 # define DP_ER(msg, err) printf("%s (%d/%x)\n", msg, err>>16, err)
44 # define DP_ER(msg, err) /**/
47 LOCAL TC dec[] = {TK_0,TK_1,TK_2,TK_3,TK_4,TK_5,TK_6,TK_7,TK_8,TK_9};
49 LOCAL W WtoTCS(W num, TC *dest)
51 W digit,draw = 0,i = 0;
53 digit = num / 1000000000 % 10;
54 if ((digit != 0)||(draw != 0)) {
55 dest[i++] = dec[digit];
58 digit = num / 100000000 % 10;
59 if ((digit != 0)||(draw != 0)) {
60 dest[i++] = dec[digit];
63 digit = num / 10000000 % 10;
64 if ((digit != 0)||(draw != 0)) {
65 dest[i++] = dec[digit];
68 digit = num / 1000000 % 10;
69 if ((digit != 0)||(draw != 0)) {
70 dest[i++] = dec[digit];
73 digit = num / 100000 % 10;
74 if ((digit != 0)||(draw != 0)) {
75 dest[i++] = dec[digit];
78 digit = num / 10000 % 10;
79 if ((digit != 0)||(draw != 0)) {
80 dest[i++] = dec[digit];
83 digit = num / 1000 % 10;
84 if ((digit != 0)||(draw != 0)) {
85 dest[i++] = dec[digit];
88 digit = num / 100 % 10;
89 if ((digit != 0)||(draw != 0)) {
90 dest[i++] = dec[digit];
93 digit = num / 10 % 10;
94 if ((digit != 0)||(draw != 0)) {
95 dest[i++] = dec[digit];
99 if ((digit != 0)||(draw != 0)) {
100 dest[i++] = dec[digit];
108 typedef struct sbjtlayout_thread_t_ sbjtlayout_thread_t;
109 struct sbjtlayout_thread_t_ {
110 sbjtparser_thread_t *parser_thread;
112 W view_l,view_t,view_r,view_b;
119 struct sbjtlayout_t_ {
121 W draw_l,draw_t,draw_r,draw_b;
122 sbjtlayout_thread_t **layout_thread; /* should be QUEUE? */
128 LOCAL sbjtlayout_thread_t* sbjtlayout_thread_new(sbjtparser_thread_t *thread)
130 sbjtlayout_thread_t *layout_thread;
133 layout_thread = (sbjtlayout_thread_t*)malloc(sizeof(sbjtlayout_thread_t));
134 if (layout_thread == NULL) {
137 layout_thread->parser_thread = thread;
138 layout_thread->view_l = 0;
139 layout_thread->view_t = 0;
140 layout_thread->view_r = 0;
141 layout_thread->view_b = 0;
143 str = tc_strrchr(thread->title, TK_LPAR);
145 layout_thread->i_titlesepareter = thread->title_len;
147 layout_thread->i_titlesepareter = (str - thread->title) - 1;
150 return layout_thread;
153 LOCAL VOID sbjtlayout_thread_delete(sbjtlayout_thread_t *layout_thread)
155 sbjtparser_thread_delete(layout_thread->parser_thread);
159 LOCAL W sbjtlayout_thread_calcindexdrawsize(sbjtlayout_thread_t *layout_thread, GID gid, SIZE *sz)
164 len = WtoTCS(layout_thread->index, str);
165 str[len++] = TK_COLN;
168 err = gget_stw(gid, str, len, NULL, NULL);
173 err = gget_sth(gid, str, len, NULL, NULL);
182 LOCAL W sbjtlayout_thread_calctitledrawsize(sbjtlayout_thread_t *layout_thread, GID gid, SIZE *sz)
184 return tadlib_calcdrawsize(layout_thread->parser_thread->title, layout_thread->i_titlesepareter, gid, sz);
187 LOCAL W sbjtlayout_thread_calcresnumdrawsize(sbjtlayout_thread_t *layout_thread, GID gid, SIZE *sz)
189 return tadlib_calcdrawsize(layout_thread->parser_thread->title + layout_thread->i_titlesepareter, layout_thread->parser_thread->title_len - layout_thread->i_titlesepareter, gid, sz);
192 LOCAL W sbjtlayout_thread_calcsize(sbjtlayout_thread_t *layout_res, GID gid, W top, W index)
194 SIZE sz_index, sz_title, sz_resnum;
197 layout_res->index = index;
199 err = sbjtlayout_thread_calcindexdrawsize(layout_res, gid, &sz_index);
203 err = sbjtlayout_thread_calctitledrawsize(layout_res, gid, &sz_title);
207 err = sbjtlayout_thread_calcresnumdrawsize(layout_res, gid, &sz_resnum);
212 layout_res->sz_title = sz_title;
214 layout_res->view_t = top + 2;
215 layout_res->view_l = 0;
216 layout_res->view_b = layout_res->view_t + sz_title.v + 16;
217 layout_res->view_r = 16*6 + sz_title.h + sz_resnum.h;
219 layout_res->baseline = 20;
220 layout_res->vframe.c.left = sz_index.h + 16;
221 layout_res->vframe.c.top = layout_res->baseline - sz_title.v - 1;
222 layout_res->vframe.c.right = layout_res->vframe.c.left + sz_title.h + 21;
223 layout_res->vframe.c.bottom = layout_res->baseline + 3;
228 //#define sbjtlayout_fontconfig_class FTC_MINCHO
229 //#define sbjtlayout_fontconfig_class 0x000000c0 /* gothic */
230 #define sbjtlayout_fontconfig_class FTC_DEFAULT
232 LOCAL W sbjtlayout_setupgid(sbjtlayout_t *layout, GID gid)
234 return gset_fon(gid, &layout->fspec);
237 EXPORT W sbjtlayout_appendthread(sbjtlayout_t *layout, sbjtparser_thread_t *parser_thread)
239 sbjtlayout_thread_t *layout_thread;
242 layout_thread = sbjtlayout_thread_new(parser_thread);
243 if (layout_thread == NULL) {
244 return -1; /* TODO */
247 len = layout->len + 1;
248 layout->layout_thread = (sbjtlayout_thread_t**)realloc(layout->layout_thread, sizeof(sbjtlayout_thread_t*)*len);
249 layout->layout_thread[layout->len] = layout_thread;
252 sbjtlayout_setupgid(layout, layout->target);
254 sbjtlayout_thread_calcsize(layout_thread, layout->target, layout->draw_b, layout->len);
257 if (layout->draw_l > layout_thread->view_l) {
258 layout->draw_l = layout_thread->view_l;
260 if (layout->draw_t > layout_thread->view_t) {
261 layout->draw_t = layout_thread->view_t;
263 if (layout->draw_r < layout_thread->view_r) {
264 layout->draw_r = layout_thread->view_r;
266 if (layout->draw_b < layout_thread->view_b) {
267 layout->draw_b = layout_thread->view_b;
273 EXPORT VOID sbjtlayout_getdrawrect(sbjtlayout_t *layout, W *l, W *t, W *r, W *b)
281 EXPORT VOID sbjtlayout_clear(sbjtlayout_t *layout)
285 if (layout->layout_thread != NULL) {
286 for (i=0;i<layout->len;i++) {
287 sbjtlayout_thread_delete(layout->layout_thread[i]);
289 free(layout->layout_thread);
295 layout->layout_thread = NULL;
299 EXPORT VOID sbjtlayout_setfsspec(sbjtlayout_t *layout, FSSPEC *fspec)
301 memcpy(&layout->fspec, fspec, sizeof(FSSPEC));
304 EXPORT VOID sbjtlayout_setvobjbgcol(sbjtlayout_t *layout, COLOR color)
306 layout->vobjbgcol = color;
309 EXPORT COLOR sbjtlayout_getvobjbgcol(sbjtlayout_t *layout)
311 return layout->vobjbgcol;
314 EXPORT sbjtlayout_t* sbjtlayout_new(GID gid)
316 sbjtlayout_t *layout;
318 layout = (sbjtlayout_t*)malloc(sizeof(sbjtlayout_t));
319 if (layout == NULL) {
322 layout->target = gid;
327 layout->layout_thread = NULL;
329 layout->fspec.name[0] = TNULL;
330 layout->fspec.attr = FT_PROP|FT_GRAYSCALE;
331 layout->fspec.fclass = sbjtlayout_fontconfig_class;
332 layout->fspec.size.h = 16;
333 layout->fspec.size.v = 16;
334 layout->vobjbgcol = 0x10000000;
339 EXPORT VOID sbjtlayout_delete(sbjtlayout_t *layout)
343 if (layout->layout_thread != NULL) {
344 for (i=0;i<layout->len;i++) {
345 sbjtlayout_thread_delete(layout->layout_thread[i]);
347 free(layout->layout_thread);
353 sbjtlayout_t *layout;
354 W view_l, view_t, view_r, view_b;
357 LOCAL W sbjtdraw_entrydraw_drawtitle(sbjtlayout_thread_t *entry, GID gid, W dh, W dv)
359 TC *str = entry->parser_thread->title;
360 W len = entry->i_titlesepareter;
361 return tadlib_drawtext(str, len, gid, dh, dv);
364 LOCAL W sbjtdraw_entrydraw_drawresnum(sbjtlayout_thread_t *entry, GID gid, W dh, W dv)
366 TC *str = entry->parser_thread->title + entry->i_titlesepareter;
367 W len = entry->parser_thread->title_len - entry->i_titlesepareter;
368 return tadlib_drawtext(str, len, gid, dh, dv);
371 LOCAL W sbjtdraw_entrydraw_resnumber(sbjtlayout_thread_t *entry, W resnum, GID target)
376 len = WtoTCS(resnum, str);
377 return gdra_str(target, str, len, G_STORE);
380 LOCAL int sectrect_tmp(RECT a, W left, W top, W right, W bottom)
382 return (a.c.left<right && left<a.c.right && a.c.top<bottom && top<a.c.bottom);
385 LOCAL W sbjtdraw_drawthread(sbjtlayout_thread_t *entry, W index, GID target, RECT *r, W dh, W dv, COLOR vobjbgcol)
388 RECT view, vframe, vframe_b;
405 sect = sectrect_tmp(*r, entry->view_l - dh, entry->view_t - dv, entry->view_r - dh, entry->view_b - dv);
410 view.c.left = entry->view_l - dh;
411 view.c.top = entry->view_t - dv;
412 view.c.right = entry->view_r - dh;
413 view.c.bottom = entry->view_b - dv;
415 err = gset_chp(target, - dh, entry->view_t + entry->baseline - dv, 1);
419 err = sbjtdraw_entrydraw_resnumber(entry, index+1, target);
423 err = gdra_chr(target, TK_COLN, G_STORE);
428 err = gset_chp(target, 16, 0, 0);
433 vframe.c.left = entry->vframe.c.left + view.c.left;
434 vframe.c.top = entry->vframe.c.top + view.c.top;
435 vframe.c.right = entry->vframe.c.right + view.c.left;
436 vframe.c.bottom = entry->vframe.c.bottom + view.c.top;
437 vframe_b.c.left = vframe.c.left + 2;
438 vframe_b.c.top = vframe.c.top + 2;
439 vframe_b.c.right = vframe.c.right + 2;
440 vframe_b.c.bottom = vframe.c.bottom + 2;
441 pat1.spat.fgcol = vobjbgcol;
442 gfra_rec(target, vframe_b, 1, &pat0, 0, G_STORE);
443 gfil_rec(target, vframe, &pat1, 0, G_STORE);
444 gfra_rec(target, vframe, 1, &pat0, 0, G_STORE);
445 gset_chc(target, 0x10000000, vobjbgcol);
447 err = gset_chp(target, entry->vframe.c.left+view.c.left+10, entry->baseline + view.c.top, 1);
452 err = sbjtdraw_entrydraw_drawtitle(entry, target, dh, dv);
457 gset_chc(target, 0x10000000, 0x10FFFFFF);
458 err = gset_chp(target, 16, 0, 0);
462 err = sbjtdraw_entrydraw_drawresnum(entry, target, dh, dv);
470 EXPORT W sbjtdraw_draw(sbjtdraw_t *draw, RECT *r)
474 sbjtlayout_t *layout;
476 layout = draw->layout;
477 target = layout->target;
479 for (i=0;i < layout->len;i++) {
480 sbjtlayout_setupgid(layout, layout->target);
481 err = sbjtdraw_drawthread(layout->layout_thread[i], i, target, r, draw->view_l, draw->view_t, layout->vobjbgcol);
490 EXPORT W sbjtdraw_findthread(sbjtdraw_t *draw, PNT rel_pos, sbjtparser_thread_t **thread, RECT *vframe)
492 W i,abs_x,abs_y,l,t,r,b;
493 sbjtlayout_t *layout;
494 sbjtlayout_thread_t *sbjt_thread;
496 layout = draw->layout;
497 abs_x = rel_pos.x + draw->view_l;
498 abs_y = rel_pos.y + draw->view_t;
500 for (i=0;i < layout->len;i++) {
501 sbjt_thread = layout->layout_thread[i];
502 l = sbjt_thread->view_l + sbjt_thread->vframe.c.left;
503 t = sbjt_thread->view_t + sbjt_thread->vframe.c.top;
504 r = sbjt_thread->view_l + sbjt_thread->vframe.c.right;
505 b = sbjt_thread->view_t + sbjt_thread->vframe.c.bottom;
506 if ((l <= abs_x)&&(abs_x < r)
507 &&(t <= abs_y)&&(abs_y < b)) {
508 *thread = sbjt_thread->parser_thread;
509 if (vframe != NULL) {
510 vframe->c.left = l - draw->view_l;
511 vframe->c.top = t - draw->view_t;
512 vframe->c.right = r - draw->view_l;
513 vframe->c.bottom = b - draw->view_t;
522 EXPORT VOID sbjtdraw_setviewrect(sbjtdraw_t *draw, W l, W t, W r, W b)
530 EXPORT VOID sbjtdraw_getviewrect(sbjtdraw_t *draw, W *l, W *t, W *r, W *b)
538 EXPORT VOID sbjtdraw_scrollviewrect(sbjtdraw_t *draw, W dh, W dv)
546 EXPORT sbjtdraw_t* sbjtdraw_new(sbjtlayout_t *layout)
550 draw = (sbjtdraw_t*)malloc(sizeof(sbjtdraw_t));
554 draw->layout = layout;
563 EXPORT VOID sbjtdraw_delete(sbjtdraw_t *draw)