OSDN Git Service

implement rendering tree traversal structure for event element position.
authorornse01 <ornse01@users.sourceforge.jp>
Wed, 20 Nov 2013 16:12:10 +0000 (16:12 +0000)
committerornse01 <ornse01@users.sourceforge.jp>
Wed, 20 Nov 2013 16:12:10 +0000 (16:12 +0000)
git-svn-id: http://svn.sourceforge.jp/svnroot/bchan/bchanf/trunk@586 20a0b8eb-f62a-4a12-8fe1-b598822500fb

src/css/cssrendering_box.c
src/css/cssrendering_box.h
src/css/test_cssrendering_box.c

index 58ab453..6d9aef4 100644 (file)
@@ -204,3 +204,67 @@ EXPORT VOID cssrendering_drawtraversal_finalize(cssrendering_drawtraversal_t *tr
 {
        treebase_preordertraversal_finalize(&traversal->base);
 }
+
+/* cssrendering_hittraversal */
+
+EXPORT Bool cssrendering_hittraversal_next(cssrendering_hittraversal_t *traversal, cssrendering_hittraversal_result *result)
+{
+       Bool cont, ok;
+       TREEBASE_TRAVERSAL_DIRECTION dir;
+       union {
+               cssrendering_basebox_t base;
+               cssrendering_linebox_t l;
+               cssrendering_anonymousbox_t a;
+               cssrendering_blockbox_t b;
+       } *box;
+       cssmetric_rectangle_t r;
+
+       for (;;) {
+               cont = treebase_postordertraversal_next(&traversal->base, (treebase_node_t**)&box, &dir);
+               if (cont == False) {
+                       break;
+               }
+               if (dir == TREEBASE_TRAVERSAL_DIRECTION_DOWN) {
+                       if ((box->base.type == CSSRENDEREING_BOX_TYPE_BLOCK)||(box->base.type == CSSRENDEREING_BOX_TYPE_ANONYMOUS)) {
+                               traversal->origin.x += box->base.content_edge.c.left;
+                               traversal->origin.y += box->base.content_edge.c.top;
+                       } else if (box->base.type == CSSRENDEREING_BOX_TYPE_LINE) {
+                               r = box->base.content_edge;
+                               r.c.left += traversal->origin.x;
+                               r.c.top += traversal->origin.y;
+                               r.c.right += traversal->origin.x;
+                               r.c.bottom += traversal->origin.y;
+                               ok = cssmetric_rectangle_andrect(r, traversal->draw);
+                               if (ok == False) {
+                                       continue;
+                               }
+
+                               result->type = CSSRENDERING_HITTRAVERSAL_RESULTTYPE_LINE;
+                               result->data.line.content_edge = r;
+                               result->data.line.nodedata = box->base.userdata;
+                               break;
+                       }
+               } else {
+                       if ((box->base.type == CSSRENDEREING_BOX_TYPE_BLOCK)||(box->base.type == CSSRENDEREING_BOX_TYPE_ANONYMOUS)) {
+                               traversal->origin.x -= box->base.content_edge.c.left;
+                               traversal->origin.y -= box->base.content_edge.c.top;
+                       } else {
+                       }
+               }
+       }
+
+       return cont;
+}
+
+EXPORT VOID cssrendering_hittraversal_initialize(cssrendering_hittraversal_t *traversal, cssrendering_blockbox_t *root, cssmetric_rectangle_t draw)
+{
+       treebase_postordertraversal_initialize(&traversal->base, &root->base.base);
+       traversal->origin.x = 0;
+       traversal->origin.y = 0;
+       traversal->draw = draw;
+}
+
+EXPORT VOID cssrendering_hittraversal_finalize(cssrendering_hittraversal_t *traversal)
+{
+       treebase_postordertraversal_finalize(&traversal->base);
+}
index 95c02ad..5c1ec9e 100644 (file)
@@ -110,6 +110,32 @@ struct cssrendering_drawtraversal_result_ {
 };
 typedef struct cssrendering_drawtraversal_result_ cssrendering_drawtraversal_result;
 
+/* Functionality name: cssrendering */
+/* Detail name: hittraversal */
+struct cssrendering_hittraversal_t_ {
+       treebase_postordertraversal_t base;
+       cssmetric_point_t origin;
+       cssmetric_rectangle_t draw;
+};
+typedef struct cssrendering_hittraversal_t_ cssrendering_hittraversal_t;
+
+/* Functionality name: cssrendering */
+/* Detail name: hittraversal */
+/* Data structure identifier: result */
+struct cssrendering_hittraversal_result_ {
+       enum {
+               CSSRENDERING_HITTRAVERSAL_RESULTTYPE_BLOCK,
+               CSSRENDERING_HITTRAVERSAL_RESULTTYPE_LINE,
+       } type;
+       union {
+               struct {
+                       cssmetric_rectangle_t content_edge;
+                       VP nodedata;
+               } line;
+       } data;
+};
+typedef struct cssrendering_hittraversal_result_ cssrendering_hittraversal_result;
+
 IMPORT VOID cssrendering_linebox_initialize(cssrendering_linebox_t *box);
 IMPORT VOID cssrendering_linebox_finalize(cssrendering_linebox_t *box);
 IMPORT VOID cssrendering_linebox_setuserdata(cssrendering_linebox_t *box, VP data);
@@ -128,4 +154,8 @@ IMPORT VOID cssrendering_drawtraversal_initialize(cssrendering_drawtraversal_t *
 IMPORT VOID cssrendering_drawtraversal_finalize(cssrendering_drawtraversal_t *traversal);
 IMPORT Bool cssrendering_drawtraversal_next(cssrendering_drawtraversal_t *traversal, cssrendering_drawtraversal_result *result);
 
+IMPORT VOID cssrendering_hittraversal_initialize(cssrendering_hittraversal_t *traversal, cssrendering_blockbox_t *root, cssmetric_rectangle_t draw);
+IMPORT VOID cssrendering_hittraversal_finalize(cssrendering_hittraversal_t *traversal);
+IMPORT Bool cssrendering_hittraversal_next(cssrendering_hittraversal_t *traversal, cssrendering_hittraversal_result *result);
+
 #endif
index 7becd99..03ca50d 100644 (file)
@@ -115,7 +115,86 @@ LOCAL UNITTEST_RESULT test_cssrendering_drawtraversal_1()
        return ret;
 }
 
+LOCAL UNITTEST_RESULT test_cssrendering_hittraversal_1()
+{
+       cssrendering_blockbox_t root;
+       cssrendering_anonymousbox_t anon;
+       cssrendering_linebox_t line[5];
+       cssrendering_hittraversal_t traversal;
+       cssrendering_hittraversal_result result;
+       cssmetric_rectangle_t draw;
+       Bool cont, line_called[5] = {False, False, False, False, False};
+       UNITTEST_RESULT ret = UNITTEST_RESULT_PASS;
+
+       cssrendering_blockbox_initialize(&root);
+       cssrendering_anonymousbox_initialize(&anon);
+       cssrendering_linebox_initialize(line+0);
+       cssrendering_linebox_initialize(line+1);
+       cssrendering_linebox_initialize(line+2);
+       cssrendering_linebox_initialize(line+3);
+       cssrendering_linebox_initialize(line+4);
+
+       cssrendering_blockbox_appendanonymouschild(&root, &anon);
+       cssrendering_anonymousbox_appendchild(&anon, line+0);
+       cssrendering_anonymousbox_appendchild(&anon, line+1);
+       cssrendering_anonymousbox_appendchild(&anon, line+2);
+       cssrendering_anonymousbox_appendchild(&anon, line+3);
+       cssrendering_anonymousbox_appendchild(&anon, line+4);
+
+       line[0].base.content_edge = (cssmetric_rectangle_t){{0, 0, 100, 100}};
+       cssrendering_linebox_setuserdata(line+0, line+0);
+       line[1].base.content_edge = (cssmetric_rectangle_t){{0, 100, 100, 200}};
+       cssrendering_linebox_setuserdata(line+1, line+1);
+       line[2].base.content_edge = (cssmetric_rectangle_t){{0, 200, 100, 300}};
+       cssrendering_linebox_setuserdata(line+2, line+2);
+       line[3].base.content_edge = (cssmetric_rectangle_t){{0, 300, 100, 400}};
+       cssrendering_linebox_setuserdata(line+3, line+3);
+       line[4].base.content_edge = (cssmetric_rectangle_t){{0, 400, 100, 500}};
+       cssrendering_linebox_setuserdata(line+4, line+4);
+
+       draw = (cssmetric_rectangle_t){{25, 150, 75, 350}};
+       cssrendering_hittraversal_initialize(&traversal, &root, draw);
+       for (;;) {
+               cont = cssrendering_hittraversal_next(&traversal, &result);
+               if (cont == False) {
+                       break;
+               }
+               if (result.type != CSSRENDERING_HITTRAVERSAL_RESULTTYPE_LINE) {
+                       continue;
+               }
+               if (result.data.line.nodedata == (line+0)) {
+                       line_called[0] = True;
+               } else if (result.data.line.nodedata == (line+1)) {
+                       line_called[1] = True;
+               } else if (result.data.line.nodedata == (line+2)) {
+                       line_called[2] = True;
+               } else if (result.data.line.nodedata == (line+3)) {
+                       line_called[3] = True;
+               } else if (result.data.line.nodedata == (line+4)) {
+                       line_called[4] = True;
+               }
+       }
+       cssrendering_hittraversal_finalize(&traversal);
+
+       if ((line_called[0] == False)&&(line_called[1] != False)&&(line_called[2] != False)&&(line_called[3] != False)&&(line_called[4] == False)) {
+               ret = UNITTEST_RESULT_PASS;
+       } else {
+               ret = UNITTEST_RESULT_FAIL;
+       }
+
+       cssrendering_linebox_finalize(line+4);
+       cssrendering_linebox_finalize(line+3);
+       cssrendering_linebox_finalize(line+2);
+       cssrendering_linebox_finalize(line+1);
+       cssrendering_linebox_finalize(line+0);
+       cssrendering_anonymousbox_finalize(&anon);
+       cssrendering_blockbox_finalize(&root);
+
+       return ret;
+}
+
 EXPORT VOID test_cssrendering_box_main(unittest_driver_t *driver)
 {
        UNITTEST_DRIVER_REGIST(driver, test_cssrendering_drawtraversal_1);
+       UNITTEST_DRIVER_REGIST(driver, test_cssrendering_hittraversal_1);
 }