root/applications/generators/SVG/v3.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. buildGlobalAttributeList
  2. generateSVGCode_V3

/*
 *                      GPAC - Multimedia Framework C SDK
 *
 *                      Authors: Cyril Concolato
 *                      Copyright (c) Telecom ParisTech 2004-2012
 *                                      All rights reserved
 *
 *  This file is part of GPAC / SVG Scene Graph Generator sub-project
 *
 *  GPAC is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  GPAC is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include "svggen.h"


void buildGlobalAttributeList(GF_List *svg_elements, GF_List *all_atts)
{
        u32 i, j, k;
        Bool added = 0;

        for (i=0; i<gf_list_count(svg_elements); i++) {
                SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
                for (j = 0; j < gf_list_count(elt->generic_attributes); j++) {
                        SVGGenAttribute *att = gf_list_get(elt->generic_attributes, j);
                        added = 0;
                        if (!strcmp(att->impl_type, "SMIL_Fill")) {
                                strcpy(att->implementation_name, "smil_fill");
                        } else if (!strcmp(att->impl_type, "SVG_TransformType")) {
                                strcpy(att->implementation_name, "transform_type");
                        }
                        for (k = 0; k < gf_list_count(all_atts); k++) {
                                SVGGenAttribute *a = gf_list_get(all_atts, k);
                                if (!strcmp(a->implementation_name, att->implementation_name)
                                        && !strcmp(a->impl_type, att->impl_type)) {
                                        added = 1;
                                        break;
                                }
                        }
                        if (!added) {
                                gf_list_add(all_atts, att);
                        }
                }
                for (j = 0; j < gf_list_count(elt->attributes); j++) {
                        SVGGenAttribute *att = gf_list_get(elt->attributes, j);
                        added = 0;
                        if (!strcmp(elt->svg_name, "text")) {
                                if (!strcmp(att->implementation_name, "x")) {
                                        strcpy(att->implementation_name, "text_x");
                                } else if (!strcmp(att->implementation_name, "y")) {
                                        strcpy(att->implementation_name, "text_y");
                                } else if (!strcmp(att->implementation_name, "rotate")) {
                                        strcpy(att->implementation_name, "text_rotate");
                                }
                        } else if (!strcmp(elt->svg_name, "listener") && !strcmp(att->implementation_name, "target")) {
                                strcpy(att->implementation_name, "listener_target");
                        } else if (!strcmp(elt->svg_name, "a") && !strcmp(att->implementation_name, "target")) {
                                strcpy(att->impl_type, "SVG_String");
                        } else if (!strcmp(elt->svg_name, "cursorManager")) {
                                if (!strcmp(att->implementation_name, "x")) {
                                        strcpy(att->implementation_name, "cursorManager_x");
                                } else if (!strcmp(att->implementation_name, "y")) {
                                        strcpy(att->implementation_name, "cursorManager_y");
                                }
                        }
                        for (k = 0; k < gf_list_count(all_atts); k++) {
                                SVGGenAttribute *a = gf_list_get(all_atts, k);
                                if (!strcmp(a->implementation_name, att->implementation_name)
                                        && !strcmp(a->impl_type, att->impl_type)) {
                                        added = 1;
                                        break;
                                }
                        }
                        if (!added) {
                                gf_list_add(all_atts, att);
                        }
                }
        }
        /*motionTransform is not parsed in rng*/
        {
                SVGGenAttribute *att = NewSVGGenAttribute();
                strcpy(att->implementation_name, "motionTransform");
                strcpy(att->impl_type, "SVG_Motion");
                att->svg_name = "motionTransform";
                att->svg_type = "SVG_Motion";
                gf_list_add(all_atts, att);
        }
}

void generateSVGCode_V3(GF_List *svg_elements)
{
        FILE *output;
        u32 i;
        GF_List *all_atts = gf_list_new();

        buildGlobalAttributeList(svg_elements, all_atts);

        /***************************************************/
        /***************************************************/
        /*************** Creating .h file ******************/
        /***************************************************/
        /***************************************************/
        output = BeginFile(0);
        fprintf(output, "#include <gpac/scenegraph_svg.h>\n\n\n");

        /* Generation of ELEMENT tags */
        fprintf(output, "/* Definition of SVG 3 Alternate element internal tags */\n");
        fprintf(output, "/* TAG names are made of \"TAG_SVG\" + SVG element name (with - replaced by _) */\n");
        fprintf(output, "enum {\n");
        for (i=0; i<gf_list_count(svg_elements); i++) {
                SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
                if (i == 0) {
                        fprintf(output, "\tTAG_SVG_%s = GF_NODE_RANGE_FIRST_SVG", elt->implementation_name);
                } else {
                        fprintf(output, ",\n\tTAG_SVG_%s", elt->implementation_name);
                }
        }
        fprintf(output, ",\n\t/*undefined elements (when parsing) use this tag*/\n\tTAG_SVG_UndefinedElement\n};\n\n");

        /* Generation of ATTRIBUTE tags */
        fprintf(output, "/* Definition of SVG 3 attribute internal tags - %d defined */\n", gf_list_count(all_atts));
        fprintf(output, "/* TAG names are made of \"TAG_SVG_ATT_\" + SVG attribute name (with - replaced by _) */\n");
        fprintf(output, "enum {\n");

        for (i=0; i<gf_list_count(all_atts); i++) {
                SVGGenAttribute *att = (SVGGenAttribute *)gf_list_get(all_atts, i);
                if (i) fprintf(output, "\tTAG_SVG_ATT_%s,\n", att->implementation_name);
                else fprintf(output, "\tTAG_SVG_ATT_%s = TAG_SVG_ATT_RANGE_FIRST,\n", att->implementation_name);
        }
        fprintf(output, "\t/*undefined attributes (when parsing) use this tag*/\n\tTAG_SVG_ATT_Unknown\n};\n\n");

        /* Generation of the flatten structure pointing to all possible attributes in SVG */
        fprintf(output, "struct _all_atts {\n");
        for (i=0; i<gf_list_count(all_atts); i++) {
                SVGGenAttribute *att = (SVGGenAttribute *)gf_list_get(all_atts, i);
                fprintf(output, "\t%s *%s;\n", att->impl_type, att->implementation_name);
        }
        fprintf(output, "};\n");

        EndFile(output, 0);

        /***************************************************/
        /***************************************************/
        /*************** Creating .c file ******************/
        /***************************************************/
        /***************************************************/
        output = BeginFile(1);
        fprintf(output, "#ifndef GPAC_DISABLE_SVG\n\n");
        fprintf(output, "#include <gpac/internal/scenegraph_dev.h>\n\n");
        fprintf(output, "#include <gpac/nodes_svg_da.h>\n\n");


        /****************************************************************/
        /* u32 gf_svg_get_attribute_tag(u32 element_tag, const char *attribute_name) */
        /****************************************************************/
        fprintf(output, "u32 gf_svg_get_attribute_tag(u32 element_tag, const char *attribute_name)\n{\n\tif (!attribute_name) return TAG_SVG_ATT_Unknown;\n");
        for (i=0; i<gf_list_count(all_atts); i++) {
                SVGGenAttribute *att = (SVGGenAttribute *)gf_list_get(all_atts, i);

                /* get rid of duplicates */
                if (!strcmp(att->impl_type, "SMIL_Fill")) continue;
                if (!strcmp(att->impl_type, "SVG_ContentType")) continue;
                if (!strcmp(att->implementation_name, "text_x")) continue;
                if (!strcmp(att->implementation_name, "text_y")) continue;
                if (!strcmp(att->implementation_name, "text_rotate")) continue;
                if (!strcmp(att->implementation_name, "cursorManager_x")) continue;
                if (!strcmp(att->implementation_name, "cursorManager_y")) continue;

                if (!strcmp(att->svg_name, "x") || !strcmp(att->svg_name, "y")) {
                        fprintf(output, "\tif (!stricmp(attribute_name, \"%s\")) {\n", att->svg_name);
                        fprintf(output, "\t\tif (element_tag == TAG_SVG_text) return TAG_SVG_ATT_text_%s;\n", att->implementation_name);
                        fprintf(output, "\t\telse if (element_tag == TAG_SVG_cursorManager) return TAG_SVG_ATT_cursorManager_%s;\n", att->implementation_name);
                        fprintf(output, "\t\telse return TAG_SVG_ATT_%s;\n", att->implementation_name);
                        fprintf(output, "\t}\n");
                } else if (!strcmp(att->svg_name, "rotate")) {
                        fprintf(output, "\tif (!stricmp(attribute_name, \"%s\")) {\n", att->svg_name);
                        fprintf(output, "\t\tif (element_tag == TAG_SVG_text) return TAG_SVG_ATT_text_%s;\n", att->implementation_name);
                        fprintf(output, "\t\telse return TAG_SVG_ATT_%s;\n", att->implementation_name);
                        fprintf(output, "\t}\n");
                } else if (!strcmp(att->svg_name, "type")) {
                        fprintf(output, "\tif (!stricmp(attribute_name, \"%s\")) {\n", att->svg_name);
                        fprintf(output, "\t\tif (element_tag == TAG_SVG_animateTransform) return TAG_SVG_ATT_transform_type;\n");
                        fprintf(output, "\t\telse return TAG_SVG_ATT_%s;\n", att->implementation_name);
                        fprintf(output, "\t}\n");
                } else if (!strcmp(att->svg_name, "fill")) {
                        fprintf(output, "\tif (!stricmp(attribute_name, \"%s\")) {\n", att->svg_name);
                        fprintf(output, "\t\tif (element_tag == TAG_SVG_animate || element_tag == TAG_SVG_animateColor || element_tag == TAG_SVG_animateMotion || element_tag == TAG_SVG_animateTransform || element_tag == TAG_SVG_animation || element_tag == TAG_SVG_audio || element_tag == TAG_SVG_video || element_tag == TAG_SVG_set) return TAG_SVG_ATT_smil_fill;\n");
                        fprintf(output, "\t\telse return TAG_SVG_ATT_%s;\n", att->implementation_name);
                        fprintf(output, "\t}\n");
                } else {
                        fprintf(output, "\tif (!stricmp(attribute_name, \"%s\")) return TAG_SVG_ATT_%s;\n", att->svg_name, att->implementation_name);
                }
        }
        fprintf(output, "\treturn TAG_SVG_ATT_Unknown;\n}\n\n");

        /****************************************************************/
        /* u32 gf_svg_get_attribute_type(u32 tag) */
        /****************************************************************/
        fprintf(output, "u32 gf_svg_get_attribute_type(u32 tag)\n{\n");
        fprintf(output, "\tswitch(tag) {\n");
        for (i=0; i<gf_list_count(all_atts); i++) {
                SVGGenAttribute *att = (SVGGenAttribute *)gf_list_get(all_atts, i);
                fprintf(output, "\t\tcase TAG_SVG_ATT_%s: return %s_datatype;\n", att->implementation_name, att->impl_type);
        }
        fprintf(output, "\t\tdefault: return SVG_Unknown_datatype;\n");
        fprintf(output, "\t}\n");
        fprintf(output, "\treturn TAG_SVG_ATT_Unknown;\n}\n\n");

        /****************************************************************/
        /* const char* gf_svg_get_attribute_name(u32 tag) */
        /****************************************************************/
        fprintf(output, "const char*gf_svg_get_attribute_name(u32 tag)\n{\n");
        fprintf(output, "\tswitch(tag) {\n");
        for (i=0; i<gf_list_count(all_atts); i++) {
                SVGGenAttribute *att = (SVGGenAttribute *)gf_list_get(all_atts, i);
                fprintf(output, "\t\tcase TAG_SVG_ATT_%s: return \"%s\";\n", att->implementation_name, att->svg_name);
        }
        fprintf(output, "\t\tdefault: return \"unknown\";\n");
        fprintf(output, "\t}\n");
        fprintf(output, "}\n\n");

        /***************************************************/
        /* SVGAttribute *gf_svg_create_attribute(GF_Node *node, u32 tag) */
        /***************************************************/
        fprintf(output, "SVGAttribute *gf_svg_create_attribute(GF_Node *node, u32 tag)\n{\n\tswitch(tag) {\n");
        for (i=0; i<gf_list_count(all_atts); i++) {
                SVGGenAttribute *att = (SVGGenAttribute *)gf_list_get(all_atts, i);
                fprintf(output, "\tcase TAG_SVG_ATT_%s: return gf_svg_create_attribute_from_datatype(%s_datatype, tag);\n", att->implementation_name, att->impl_type);
        }
        fprintf(output, "\tdefault: return NULL;\n\t}\n}\n\n");

        /****************************************************************/
        /* void gf_svg_flatten_attributes(SVG_Element *e, SVGAllAttributes *all_atts) */
        /****************************************************************/
        fprintf(output, "void gf_svg_flatten_attributes(SVG_Element *e, SVGAllAttributes *all_atts)\n");

        fprintf(output, "{\n");
        fprintf(output, "\tSVGAttribute *att;\n");
        fprintf(output, "\tmemset(all_atts, 0, sizeof(SVGAllAttributes));\n");
        fprintf(output, "\tif (e->sgprivate->tag <= GF_NODE_FIRST_DOM_NODE_TAG) return;\n");
        fprintf(output, "\tatt = e->attributes;\n");
        fprintf(output, "\twhile (att) {\n");
        fprintf(output, "\t\tswitch(att->tag) {\n");
        for (i=0; i<gf_list_count(all_atts); i++) {
                SVGGenAttribute *att = (SVGGenAttribute *)gf_list_get(all_atts, i);
                fprintf(output, "\t\tcase TAG_SVG_ATT_%s: all_atts->%s = (%s *)att->data; break;\n", att->implementation_name, att->implementation_name, att->impl_type);
        }
        fprintf(output, "\t\t}\n");
        fprintf(output, "\tatt = att->next;\n");
        fprintf(output, "\t}\n");
        fprintf(output, "}\n");
        fprintf(output, "\n");

        /****************************************************************/
        /* u32 gf_svg_get_element_tag(const char *element_name) */
        /****************************************************************/
        fprintf(output, "u32 gf_svg_get_element_tag(const char *element_name)\n{\n\tif (!element_name) return TAG_UndefinedNode;\n");
        for (i=0; i<gf_list_count(svg_elements); i++) {
                SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
                fprintf(output, "\tif (!stricmp(element_name, \"%s\")) return TAG_SVG_%s;\n", elt->svg_name, elt->implementation_name);
        }
        fprintf(output, "\treturn TAG_UndefinedNode;\n}\n\n");

        /***************************************************/
        /* const char *gf_svg_get_element_name(u32 tag) */
        /***************************************************/
        fprintf(output, "const char *gf_svg_get_element_name(u32 tag)\n{\n\tswitch(tag) {\n");
        for (i=0; i<gf_list_count(svg_elements); i++) {
                SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
                fprintf(output, "\tcase TAG_SVG_%s: return \"%s\";\n", elt->implementation_name, elt->svg_name);
        }
        fprintf(output, "\tdefault: return \"TAG_SVG_UndefinedNode\";\n\t}\n}\n\n");

        fprintf(output, "#endif /*GPAC_DISABLE_SVG*/\n\n");
        EndFile(output, 1);


        generate_laser_tables_da(all_atts);

        gf_list_del(all_atts);

}


/* [<][>][^][v][top][bottom][index][help] */