Version 1, last updated by wycc at Sep 28 18:46 2010 UTC

DOM operation

SVG can be represented as a DOM tree so that we can change any elements inside a single SVG document. Actually, each SVG document can contains as manay smaller objects inside it. The C program can move, resize, delete or duplicate the objects inside a SVG document inb order to implement a complete user interface.

However, after the SVG is loaded into the memory as cairo objects. We lose the original SVG structures. Therefore, we should create a similiar DOM tree in the memory so that we can use it latter. In order to prevent unnecessary overhead, we can provides two version of construction functions. One with DOM tree and the other one drop all DOM information for space and speed.

In order to reduce the size of the DOM tree, we will keep only the group only. The id of other elements will be dropped unless they are started from m_. However, we can still access them in unnamed DOM operation. For example,

<svg>
     <text id="id111" x="10" y = "100">sadasd</text>
     <g id="id112">
         <text id="m_title" x="100" y="100">aaaa</text>
     </g>
</svg>

In this case, the id112 and m_title will be kept and the id111 will be dropped. This document will be translated into

; FIXME, this is incorrect.
rdman_object_t *s_text = {type:SHAPE_TEXT,id:NULL,x:10,y:100,text:"sadasd"};
rdman_object_t *s_text1 = {type:SHAPE_TEXT,id:"m_title",text:"aaaa"};
rdman_object_t *s_group = {type:SHAPE_GROUP,id:"id112",obj:{s_text1}};

rdman_object_t *svg={type:SHAPE_GROUP,id:NULL,obj:{s_text,s_group}};

coord_t

This name looks like it's a coordinate of an object. However, it's far beyond that. This class defines the transformation matrix, which can move , rorate and scale the object. In simple word, an coord_t can be thinked as a group object. Actually, I believe that name it to be group_t may be a better idea. When we traverse the DOM tree, we are actually traverising the coord_t tree. The root of the DOM tree is started at root_coord of the redraw_man_t.

Curently, the group id is not saved in the coord_t. Instead, it is generated as the variable name of the header files. We should change the rdman_coord_new function to supply an name for the group. This function will generate a new coord_t and put it as the child of the parent coord_t.

child = rdman_coord_new(rdman, parent_coord,"gun");

The above code will generate a new coord_t whose parent coord_t is parent_coord. In this way, we can traverse DOM tree by checking the children member variable of the coord_t.

coord_t *rdman_dom_get(coord_t *root, char *dom[])
{
    coord_t *obj = root;
    while(*dom) {
        // traverse the coord_t tree
        FORCHILDREN(obj,child) {
            if (strcmp(child->id, *dom)==0) {
                obj = child;
                dom++;
                continue;
            }
        }
        if (dom[1] == NULL) {
            // For the last reference, we check the shapes as well if it has name.
            while(shape && (shape = STAILQ_NEXT(shape_t, sh_next, shape))) {
                if (strcmp(shape->id,*dom)==0) {
                    return shape;
                }
            }
        }
        return NULL;
    }
    return obj;
}

The above code is actually not working since the DOM may point to a coord_t or a shape_t. Therefore, we will define a mbdom_t to hold both types of the result. The rdman_dom_get will use mbdom_t as the first argument. It will reeturn the same type as well. The DOM tree can be changed and fetched by using

mbdom_t * rdman_dom_get_root(rdman_t *rdman);
mbdom_t * rdman_dom_get_obj(mbdom_t *root, char *dom[]);
char *rdman_dom_get_string(mbdom_t *root, char *var, char *value);
float rdman_dom_get_float(mbdom_t*root, char *var, floar value);
int rdman_dom_get_int(mbdom_t*root, char *var, int value);

void rdman_dom_set_string(mbdom_t *root, char *var, char *value);
void rdman_dom_set_float(mbdom_t*root, char *var, floar value);
void rdman_dom_set_int(mbdom_t*root, char *var, int value);