This source file includes following definitions.
- NewSVGGenAttribute
- deleteSVGGenAttribute
- NewSVGGenAttrGrp
- NewSVGGenElement
- deleteSVGGenElement
- sortElements
- sortAttrGrp
- sortAttr
- svgNameToImplementationName
- isGenericAttributesGroup
- setGenericAttributesFlags
- flattenAttributeGroups
- flattenAttributeGroup
- findAttribute
- countAttributesAllInGroup
- findNodes
- setAttributeType
- getAttributeType
- getRealAttributes
- getOneGlobalAttrGrp
- getAllGlobalAttrGrp
- getElements
- BeginFile
- EndFile
- generateAttributes
- replaceIncludes
- main
#include "svggen.h"
SVGGenAttribute *NewSVGGenAttribute()
{
SVGGenAttribute *att;
GF_SAFEALLOC(att, SVGGenAttribute)
return att;
}
void deleteSVGGenAttribute(SVGGenAttribute **p)
{
xmlFree((*p)->svg_name);
xmlFree((*p)->svg_type);
gf_free(*p);
*p = NULL;
}
SVGGenAttrGrp *NewSVGGenAttrGrp()
{
SVGGenAttrGrp *tmp;
GF_SAFEALLOC(tmp, SVGGenAttrGrp)
tmp->attrs = gf_list_new();
tmp->attrgrps = gf_list_new();
return tmp;
}
SVGGenElement *NewSVGGenElement()
{
SVGGenElement *elt;
GF_SAFEALLOC(elt, SVGGenElement);
if (elt) {
elt->attributes = gf_list_new();
elt->generic_attributes = gf_list_new();
}
return elt;
}
void deleteSVGGenElement(SVGGenElement **p)
{
u32 i;
xmlFree((*p)->svg_name);
for (i = 0; i < gf_list_count((*p)->attributes); i++) {
SVGGenAttribute *a = gf_list_get((*p)->attributes, i);
deleteSVGGenAttribute(&a);
}
gf_list_del((*p)->attributes);
gf_free(*p);
*p = NULL;
}
static GF_List *sortElements(GF_List *elements)
{
u32 i, j;
GF_List *sorted_elements = gf_list_new();
for (i = 0; i< gf_list_count(elements); i++) {
u8 is_added = 0;
SVGGenElement *elt = gf_list_get(elements, i);
for (j = 0; j < gf_list_count(sorted_elements); j++) {
SVGGenElement *selt = gf_list_get(sorted_elements, j);
if (strcmp(elt->svg_name, selt->svg_name) < 0) {
gf_list_insert(sorted_elements, elt, j);
is_added = 1;
break;
}
}
if (!is_added) gf_list_add(sorted_elements, elt);
}
gf_list_del(elements);
return sorted_elements;
}
static GF_List *sortAttrGrp(GF_List *attgrps)
{
u32 i, j;
GF_List *sorted_attgrps = gf_list_new();
for (i = 0; i< gf_list_count(attgrps); i++) {
u8 is_added = 0;
SVGGenAttrGrp *grp = gf_list_get(attgrps, i);
for (j = 0; j < gf_list_count(sorted_attgrps); j++) {
SVGGenAttrGrp *sgrp = gf_list_get(sorted_attgrps, j);
if (strcmp(grp->name, sgrp->name) < 0) {
gf_list_insert(sorted_attgrps, grp, j);
is_added = 1;
break;
}
}
if (!is_added) gf_list_add(sorted_attgrps, grp);
}
gf_list_del(attgrps);
return sorted_attgrps;
}
static GF_List *sortAttr(GF_List *atts)
{
u32 i, j;
GF_List *sorted_atts = gf_list_new();
for (i = 0; i< gf_list_count(atts); i++) {
u8 is_added = 0;
SVGGenAttribute *att = gf_list_get(atts, i);
for (j = 0; j < gf_list_count(sorted_atts); j++) {
SVGGenAttribute *satt = gf_list_get(sorted_atts, j);
if (strcmp(att->svg_name, satt->svg_name) < 0) {
gf_list_insert(sorted_atts, att, j);
is_added = 1;
break;
}
}
if (!is_added) gf_list_add(sorted_atts, att);
}
gf_list_del(atts);
return sorted_atts;
}
void svgNameToImplementationName(xmlChar *svg_name, char implementation_name[50]) {
char *tmp;
strcpy(implementation_name, svg_name);
tmp = implementation_name;
while ( (tmp = strchr(tmp, '.')) ) {
*tmp='_';
tmp++;
}
tmp = implementation_name;
while ( (tmp = strchr(tmp, '-')) ) {
*tmp='_';
tmp++;
}
tmp = implementation_name;
while ( (tmp = strchr(tmp, ':')) ) {
*tmp='_';
tmp++;
}
}
static Bool isGenericAttributesGroup(char *name)
{
if (!strcmp(name, "svg.Core.attr") ||
!strcmp(name, "svg.CorePreserve.attr") ||
!strcmp(name, "svg.External.attr") ||
!strcmp(name, "svg.Properties.attr") ||
!strcmp(name, "svg.Media.attr") ||
!strcmp(name, "svg.MediaClip.attr") ||
!strcmp(name, "svg.Opacity.attr") ||
!strcmp(name, "svg.FocusHighlight.attr") ||
!strcmp(name, "svg.Focus.attr") ||
!strcmp(name, "svg.AnimateCommon.attr") ||
!strcmp(name, "svg.XLinkEmbed.attr") ||
!strcmp(name, "svg.XLinkRequired.attr") ||
!strcmp(name, "svg.XLinkReplace.attr") ||
!strcmp(name, "svg.AnimateTiming.attr") ||
!strcmp(name, "svg.AnimateTimingNoMinMax.attr") ||
!strcmp(name, "svg.AnimateBegin.attr") ||
!strcmp(name, "svg.AnimateTimingNoFillNoMinMax.attr") ||
!strcmp(name, "svg.AnimateSync.attr") ||
!strcmp(name, "svg.AnimateSyncDefault.attr") ||
!strcmp(name, "svg.AnimateAttributeCommon.attr") ||
!strcmp(name, "svg.AnimateToCommon.attr") ||
!strcmp(name, "svg.AnimateValueCommon.attr") ||
!strcmp(name, "svg.AnimateAdditionCommon.attr") ||
!strcmp(name, "svg.AnimateTypeCommon.attr") ||
!strcmp(name, "svg.Conditional.attr") ||
!strcmp(name, "svg.Transform.attr")) {
return 1;
} else {
return 0;
}
}
static Bool setGenericAttributesFlags(char *name, SVGGenElement *e)
{
Bool ret = 1;
if (!strcmp(name, "svg.Core.attr") ||
!strcmp(name, "svg.CorePreserve.attr") ||
!strcmp(name, "svg.External.attr")) {
e->has_svg_generic = 1;
e->has_xml_generic = 1;
} else if (!strcmp(name, "svg.Properties.attr")) {
e->has_properties = 1;
e->has_media_properties = 1;
} else if (!strcmp(name, "svg.Media.attr")) {
e->has_media_properties = 1;
} else if (!strcmp(name, "svg.Opacity.attr")) {
e->has_opacity_properties = 1;
} else if (!strcmp(name, "svg.FocusHighlight.attr") ||
!strcmp(name, "svg.Focus.attr")) {
e->has_focus = 1;
} else if (!strcmp(name, "svg.AnimateCommon.attr") ||
!strcmp(name, "svg.XLinkEmbed.attr") ||
!strcmp(name, "svg.XLinkRequired.attr") ||
!strcmp(name, "svg.XLinkReplace.attr")) {
e->has_xlink = 1;
} else if (!strcmp(name, "svg.AnimateTiming.attr") ||
!strcmp(name, "svg.AnimateTimingNoMinMax.attr") ||
!strcmp(name, "svg.AnimateBegin.attr") ||
!strcmp(name, "svg.AnimateTimingNoFillNoMinMax.attr")) {
e->has_timing = 1;
} else if (!strcmp(name, "svg.AnimateSync.attr") ||
!strcmp(name, "svg.AnimateSyncDefault.attr")) {
e->has_sync= 1;
} else if (!strcmp(name, "svg.AnimateAttributeCommon.attr") ||
!strcmp(name, "svg.AnimateToCommon.attr") ||
!strcmp(name, "svg.AnimateValueCommon.attr") ||
!strcmp(name, "svg.AnimateAdditionCommon.attr") ||
!strcmp(name, "svg.AnimateTypeCommon.attr")) {
e->has_animation = 1;
} else if (!strcmp(name, "svg.Conditional.attr")) {
e->has_conditional = 1;
} else if (!strcmp(name, "svg.Transform.attr")) {
e->has_transform = 1;
} else if (!strcmp(name, "svg.XY.attr")) {
e->has_xy = 1;
} else {
ret = 0;
}
return ret;
}
static void flattenAttributeGroup(SVGGenAttrGrp attgrp, SVGGenElement *e, Bool all);
static void flattenAttributeGroups(GF_List *attrgrps, SVGGenElement *e, Bool all)
{
u32 i;
for (i = 0; i < gf_list_count(attrgrps); i ++) {
SVGGenAttrGrp *ag = gf_list_get(attrgrps, i);
flattenAttributeGroup(*ag, e, all);
}
}
static void flattenAttributeGroup(SVGGenAttrGrp attgrp, SVGGenElement *e, Bool all)
{
u32 i;
if (isGenericAttributesGroup(attgrp.name) && !all) {
setGenericAttributesFlags(attgrp.name, e);
flattenAttributeGroups(attgrp.attrgrps, e, 1);
for (i = 0; i < gf_list_count(attgrp.attrs); i++) {
gf_list_add(e->generic_attributes, gf_list_get(attgrp.attrs, i));
}
} else {
flattenAttributeGroups(attgrp.attrgrps, e, all);
for (i = 0; i < gf_list_count(attgrp.attrs); i++) {
if (all)
gf_list_add(e->generic_attributes, gf_list_get(attgrp.attrs, i));
else
gf_list_add(e->attributes, gf_list_get(attgrp.attrs, i));
}
}
}
SVGGenAttribute *findAttribute(SVGGenElement *e, char *name)
{
u32 i;
for (i = 0; i < gf_list_count(e->attributes); i++) {
SVGGenAttribute *a = gf_list_get(e->attributes, i);
if (!strcmp(a->svg_name, name)) return a;
}
for (i = 0; i < gf_list_count(e->generic_attributes); i++) {
SVGGenAttribute *a = gf_list_get(e->generic_attributes, i);
if (!strcmp(a->svg_name, name)) return a;
}
return NULL;
}
static u32 countAttributesAllInGroup(SVGGenAttrGrp *ag)
{
u32 i, ret = 0;
for (i = 0; i < gf_list_count(ag->attrgrps); i ++) {
SVGGenAttrGrp *agtmp = gf_list_get(ag->attrgrps, i);
ret += countAttributesAllInGroup(agtmp);
}
ret += gf_list_count(ag->attrs);
return ret;
}
xmlNodeSetPtr findNodes( xmlXPathContextPtr ctxt, xmlChar * path )
{
xmlXPathObjectPtr res = NULL;
if ( ctxt->node != NULL && path != NULL ) {
xmlXPathCompExprPtr comp;
xmlDocPtr tdoc = NULL;
xmlNodePtr froot = ctxt->node;
comp = xmlXPathCompile( path );
if ( comp == NULL ) {
return NULL;
}
if ( ctxt->node->doc == NULL ) {
tdoc = xmlNewDoc( NULL );
while ( froot != NULL ) {
if ( froot->parent == NULL ) {
break;
}
froot = froot->parent;
}
xmlAddChild((xmlNodePtr)tdoc, froot);
ctxt->node->doc = tdoc;
}
res = xmlXPathCompiledEval(comp, ctxt);
xmlXPathFreeCompExpr(comp);
if ( tdoc != NULL ) {
xmlSetTreeDoc(froot,NULL);
froot->doc = NULL;
tdoc->children = NULL;
tdoc->last = NULL;
froot->parent = NULL;
ctxt->node->doc = NULL;
xmlFreeDoc( tdoc );
}
}
if (res && res->type == XPATH_NODESET)
return res->nodesetval;
else
return NULL;
}
void setAttributeType(SVGGenAttribute *att)
{
if (!att->svg_type) {
if (!strcmp(att->svg_name, "textContent")) {
strcpy(att->impl_type, "SVG_TextContent");
} else if (!strcmp(att->svg_name, "class")) {
strcpy(att->implementation_name, "_class");
strcpy(att->impl_type, "SVG_String");
} else if (!strcmp(att->svg_name, "visibility")) {
strcpy(att->impl_type, "SVG_Visibility");
} else if (!strcmp(att->svg_name, "display")) {
strcpy(att->impl_type, "SVG_Display");
} else if (!strcmp(att->svg_name, "stroke-linecap")) {
strcpy(att->impl_type, "SVG_StrokeLineCap");
} else if (!strcmp(att->svg_name, "stroke-dasharray")) {
strcpy(att->impl_type, "SVG_StrokeDashArray");
} else if (!strcmp(att->svg_name, "stroke-linejoin")) {
strcpy(att->impl_type, "SVG_StrokeLineJoin");
} else if (!strcmp(att->svg_name, "font-style")) {
strcpy(att->impl_type, "SVG_FontStyle");
} else if (!strcmp(att->svg_name, "font-weight")) {
strcpy(att->impl_type, "SVG_FontWeight");
} else if (!strcmp(att->svg_name, "text-anchor")) {
strcpy(att->impl_type, "SVG_TextAnchor");
} else if (!strcmp(att->svg_name, "fill")) {
strcpy(att->impl_type, "SMIL_Fill");
} else if (!strcmp(att->svg_name, "fill-rule")) {
strcpy(att->impl_type, "SVG_FillRule");
} else if (!strcmp(att->svg_name, "font-family")) {
strcpy(att->impl_type, "SVG_FontFamily");
} else if (!strcmp(att->svg_name, "calcMode")) {
strcpy(att->impl_type, "SMIL_CalcMode");
} else if (!strcmp(att->svg_name, "values")) {
strcpy(att->impl_type, "SMIL_AnimateValues");
} else if (!strcmp(att->svg_name, "keyTimes")) {
strcpy(att->impl_type, "SMIL_KeyTimes");
} else if (!strcmp(att->svg_name, "keySplines")) {
strcpy(att->impl_type, "SMIL_KeySplines");
} else if (!strcmp(att->svg_name, "keyPoints")) {
strcpy(att->impl_type, "SMIL_KeyPoints");
} else if (!strcmp(att->svg_name, "from") ||
!strcmp(att->svg_name, "to") ||
!strcmp(att->svg_name, "by")) {
strcpy(att->impl_type, "SMIL_AnimateValue");
} else if (!strcmp(att->svg_name, "additive")) {
strcpy(att->impl_type, "SMIL_Additive");
} else if (!strcmp(att->svg_name, "accumulate")) {
strcpy(att->impl_type, "SMIL_Accumulate");
} else if (!strcmp(att->svg_name, "begin") ||
!strcmp(att->svg_name, "end")
) {
strcpy(att->impl_type, "SMIL_Times");
} else if (!strcmp(att->svg_name, "clipBegin") ||
!strcmp(att->svg_name, "clipEnd")
) {
strcpy(att->impl_type, "SVG_Clock");
} else if (!strcmp(att->svg_name, "min") ||
!strcmp(att->svg_name, "max") ||
!strcmp(att->svg_name, "dur") ||
!strcmp(att->svg_name, "repeatDur")
) {
strcpy(att->impl_type, "SMIL_Duration");
} else if (!strcmp(att->svg_name, "repeat")) {
strcpy(att->impl_type, "SMIL_Repeat");
} else if (!strcmp(att->svg_name, "restart")) {
strcpy(att->impl_type, "SMIL_Restart");
} else if (!strcmp(att->svg_name, "repeatCount")) {
strcpy(att->impl_type, "SMIL_RepeatCount");
} else if (!strcmp(att->svg_name, "attributeName")) {
strcpy(att->impl_type, "SMIL_AttributeName");
} else if (!strcmp(att->svg_name, "type")) {
strcpy(att->impl_type, "SVG_TransformType");
} else if (!strcmp(att->svg_name, "font-size")) {
strcpy(att->impl_type, "SVG_FontSize");
} else if (!strcmp(att->svg_name, "viewBox")) {
strcpy(att->impl_type, "SVG_ViewBox");
} else if (!strcmp(att->svg_name, "preserveAspectRatio")) {
strcpy(att->impl_type, "SVG_PreserveAspectRatio");
} else if (!strcmp(att->svg_name, "zoomAndPan")) {
strcpy(att->impl_type, "SVG_ZoomAndPan");
} else if (!strcmp(att->svg_name, "path")) {
strcpy(att->impl_type, "SVG_PathData");
} else if (!strcmp(att->svg_name, "image-rendering")) {
strcpy(att->impl_type, "SVG_RenderingHint");
} else if (!strcmp(att->svg_name, "color-rendering")) {
strcpy(att->impl_type, "SVG_RenderingHint");
} else if (!strcmp(att->svg_name, "text-rendering")) {
strcpy(att->impl_type, "SVG_RenderingHint");
} else if (!strcmp(att->svg_name, "shape-rendering")) {
strcpy(att->impl_type, "SVG_RenderingHint");
} else if (!strcmp(att->svg_name, "pointer-events")) {
strcpy(att->impl_type, "SVG_PointerEvents");
} else if (!strcmp(att->svg_name, "vector-effect")) {
strcpy(att->impl_type, "SVG_VectorEffect");
} else if (!strcmp(att->svg_name, "vector-effect")) {
strcpy(att->impl_type, "SVG_VectorEffect");
} else if (!strcmp(att->svg_name, "display-align")) {
strcpy(att->impl_type, "SVG_DisplayAlign");
} else if (!strcmp(att->svg_name, "text-align")) {
strcpy(att->impl_type, "SVG_TextAlign");
} else if (!strcmp(att->svg_name, "propagate")) {
strcpy(att->impl_type, "XMLEV_Propagate");
} else if (!strcmp(att->svg_name, "defaultAction")) {
strcpy(att->impl_type, "XMLEV_DefaultAction");
} else if (!strcmp(att->svg_name, "phase")) {
strcpy(att->impl_type, "XMLEV_Phase");
} else if (!strcmp(att->svg_name, "syncBehavior")) {
strcpy(att->impl_type, "SMIL_SyncBehavior");
} else if (!strcmp(att->svg_name, "syncBehaviorDefault")) {
strcpy(att->impl_type, "SMIL_SyncBehavior");
} else if (!strcmp(att->svg_name, "attributeType")) {
strcpy(att->impl_type, "SMIL_AttributeType");
} else if (!strcmp(att->svg_name, "playbackOrder")) {
strcpy(att->impl_type, "SVG_PlaybackOrder");
} else if (!strcmp(att->svg_name, "timelineBegin")) {
strcpy(att->impl_type, "SVG_TimelineBegin");
} else if (!strcmp(att->svg_name, "xml:space")) {
strcpy(att->impl_type, "XML_Space");
} else if (!strcmp(att->svg_name, "snapshotTime")) {
strcpy(att->impl_type, "SVG_Clock");
} else if (!strcmp(att->svg_name, "version")) {
strcpy(att->impl_type, "SVG_String");
} else if (!strcmp(att->svg_name, "gradientUnits")) {
strcpy(att->impl_type, "SVG_GradientUnit");
} else if (!strcmp(att->svg_name, "baseProfile")) {
strcpy(att->impl_type, "SVG_String");
} else if (!strcmp(att->svg_name, "focusHighlight")) {
strcpy(att->impl_type, "SVG_FocusHighlight");
} else if (!strcmp(att->svg_name, "initialVisibility")) {
strcpy(att->impl_type, "SVG_InitialVisibility");
} else if (!strcmp(att->svg_name, "overlay")) {
strcpy(att->impl_type, "SVG_Overlay");
} else if (!strcmp(att->svg_name, "transformBehavior")) {
strcpy(att->impl_type, "SVG_TransformBehavior");
} else if (!strcmp(att->svg_name, "rotate")) {
strcpy(att->impl_type, "SVG_Rotate");
} else if (!strcmp(att->svg_name, "font-variant")) {
strcpy(att->impl_type, "SVG_FontVariant");
} else if (!strcmp(att->svg_name, "lsr:enabled")) {
strcpy(att->impl_type, "SVG_Boolean");
} else if (!strcmp(att->svg_name, "spreadMethod")) {
strcpy(att->impl_type, "SVG_SpreadMethod");
} else if (!strcmp(att->svg_name, "gradientTransform")) {
strcpy(att->impl_type, "SVG_Transform_Full");
} else if (!strcmp(att->svg_name, "editable")) {
strcpy(att->impl_type, "SVG_Boolean");
} else if (!strcmp(att->svg_name, "choice")) {
strcpy(att->impl_type, "LASeR_Choice");
} else if (!strcmp(att->svg_name, "size") ||
!strcmp(att->svg_name, "delta")) {
strcpy(att->impl_type, "LASeR_Size");
} else if (!strcmp(att->svg_name, "syncReference")) {
strcpy(att->impl_type, "XMLRI");
} else {
strcpy(att->impl_type, "SVG_String");
fprintf(stdout, "Warning: using type SVG_String for attribute %s.\n", att->svg_name);
}
} else {
if (!strcmp(att->svg_name, "color")) {
strcpy(att->impl_type, "SVG_Paint");
} else if (!strcmp(att->svg_name, "viewport-fill")) {
strcpy(att->impl_type, "SVG_Paint");
} else if (!strcmp(att->svg_name, "syncTolerance")) {
strcpy(att->impl_type, "SMIL_SyncTolerance");
} else if (!strcmp(att->svg_name, "syncToleranceDefault")) {
strcpy(att->impl_type, "SMIL_SyncTolerance");
} else if (!strcmp(att->svg_name, "transform")) {
strcpy(att->impl_type, "SVG_Transform");
} else if (!strcmp(att->svg_name, "gradientTransform")) {
strcpy(att->impl_type, "SVG_Transform");
} else if (!strcmp(att->svg_name, "focusable")) {
strcpy(att->impl_type, "SVG_Focusable");
} else if (!strcmp(att->svg_name, "event") || !strcmp(att->svg_name, "ev:event")) {
strcpy(att->impl_type, "XMLEV_Event");
} else if (!strcmp(att->svg_type, "IRI.datatype")) {
strcpy(att->impl_type, "XMLRI");
} else if (!strcmp(att->svg_type, "IDREF.datatype")) {
strcpy(att->impl_type, "XML_IDREF");
} else if (strstr(att->svg_type, "datatype")) {
char *tmp;
sprintf(att->impl_type, "SVG_%s", att->svg_type);
tmp = att->impl_type;
while ( (tmp = strstr(tmp, "-")) ) {
*tmp='_';
tmp++;
}
tmp = att->impl_type;
while ( (tmp = strstr(tmp, ".")) ) {
*tmp='_';
tmp++;
}
tmp = att->impl_type;;
if ( (tmp = strstr(tmp, "datatype")) ) {
tmp--;
*tmp = 0;
}
}
}
}
void getAttributeType(xmlDocPtr doc, xmlXPathContextPtr xpathCtx,
xmlNodePtr attributeNode, SVGGenAttribute *a)
{
xmlNodeSetPtr refNodes;
xpathCtx->node = attributeNode;
refNodes = findNodes(xpathCtx, ".//rng:ref");
if (refNodes->nodeNr == 0) {
} else if (refNodes->nodeNr == 1) {
xmlNodePtr ref = refNodes->nodeTab[0];
a->svg_type = xmlStrdup(xmlGetProp(ref, "name"));
} else {
}
}
void getRealAttributes(xmlDocPtr doc, xmlXPathContextPtr xpathCtx, xmlNodePtr newCtxNode,
GF_List *attributes)
{
xmlNodeSetPtr attributeNodes;
int k;
u32 j;
xpathCtx->node = newCtxNode;
attributeNodes = findNodes(xpathCtx, ".//rng:attribute");
for (k = 0; k < attributeNodes->nodeNr; k++) {
Bool already_exists = 0;
xmlNodePtr attributeNode = attributeNodes->nodeTab[k];
if (attributeNode->type == XML_ELEMENT_NODE) {
SVGGenAttribute *a = NewSVGGenAttribute();
a->svg_name = xmlGetProp(attributeNode, "name");
a->optional = xmlStrEqual(attributeNode->parent->name, "optional");
svgNameToImplementationName(a->svg_name, a->implementation_name);
getAttributeType(doc, xpathCtx, attributeNode, a);
setAttributeType(a);
for (j=0; j<gf_list_count(attributes); j++) {
SVGGenAttribute *ta = gf_list_get(attributes, j);
if (xmlStrEqual(ta->svg_name, a->svg_name)) {
already_exists = 1;
break;
}
}
if (already_exists) {
deleteSVGGenAttribute(&a);
} else {
gf_list_add(attributes, a);
}
}
}
}
SVGGenAttrGrp *getOneGlobalAttrGrp(xmlDocPtr doc, xmlXPathContextPtr xpathCtx, xmlChar *name)
{
SVGGenAttrGrp *attgrp = NULL;
xmlNodeSetPtr attrGrpDefNodes;
xmlChar *expr;
u32 j;
int i, l;
for (j = 0; j < gf_list_count(globalAttrGrp); j++) {
SVGGenAttrGrp *attgrp = gf_list_get(globalAttrGrp, j);
if (!strcmp(attgrp->name, name)) {
return attgrp;
}
}
expr = xmlStrdup("//rng:define[@name=\"");
expr = xmlStrcat(expr, name);
expr = xmlStrcat(expr, "\" and not(rng:empty) and not(rng:notAllowed)]");
attrGrpDefNodes = findNodes(xpathCtx, expr);
if (!attrGrpDefNodes->nodeNr) {
fprintf(stdout, "Warning: found 0 non-empty or allowed definition for the Group of Attributes: %s\n", name);
return NULL;
}
attgrp = NewSVGGenAttrGrp();
attgrp->name = gf_strdup(name);
svgNameToImplementationName(attgrp->name, attgrp->imp_name);
gf_list_add(globalAttrGrp, attgrp);
for (i = 0; i < attrGrpDefNodes->nodeNr; i++) {
xmlNodePtr attrGrp = attrGrpDefNodes->nodeTab[i];
getRealAttributes(doc, xpathCtx, attrGrp, attgrp->attrs);
{
xmlNodeSetPtr refNodes;
xpathCtx->node = attrGrp;
refNodes = findNodes(xpathCtx, ".//rng:ref");
for (l = 0; l < refNodes->nodeNr; l++) {
xmlNodePtr ref = refNodes->nodeTab[l];
xmlChar *rname = xmlGetProp(ref, "name");
if (xmlStrstr(rname, ".attr")) {
SVGGenAttrGrp *g2 = getOneGlobalAttrGrp(doc, xpathCtx, rname);
if (g2) {
gf_list_add(attgrp->attrgrps, g2);
}
}
}
}
}
return attgrp;
}
void getAllGlobalAttrGrp(xmlDocPtr doc, xmlXPathContextPtr xpathCtx)
{
xmlNodeSetPtr elementNodes = findNodes(xpathCtx, "//rng:define");
int k;
for (k = 0; k < elementNodes->nodeNr; k++) {
xmlNodePtr elementNode = elementNodes->nodeTab[k];
if (elementNode->type == XML_ELEMENT_NODE) {
xmlChar *name = NULL;
name = xmlGetProp(elementNode, "name");
if (xmlStrstr(name, ".attr")) {
getOneGlobalAttrGrp(doc, xpathCtx, name);
}
}
}
}
GF_List *getElements(xmlDocPtr doc, xmlXPathContextPtr xpathCtx)
{
xmlChar *expr;
GF_List *elements = gf_list_new();
xmlNodeSetPtr ATNodes;
xmlNodeSetPtr refNodes, elementNodes = findNodes(xpathCtx, "//rng:element");
int k, j;
u32 i;
for (k = 0; k < elementNodes->nodeNr; k++) {
xmlNodePtr elementNode = elementNodes->nodeTab[k];
if (elementNode->type == XML_ELEMENT_NODE) {
SVGGenElement *e = NewSVGGenElement();
e->svg_name = xmlStrdup(xmlGetProp(elementNode, "name"));
svgNameToImplementationName(e->svg_name, e->implementation_name);
expr = xmlStrdup("//rng:define[@name=\"");
if (!xmlStrcmp(e->svg_name, "polygon") || !xmlStrcmp(e->svg_name, "polyline")) {
expr = xmlStrcat(expr, "polyCommon");
} else {
expr = xmlStrcat(expr, e->svg_name);
}
expr = xmlStrcat(expr, ".AT\"]");
ATNodes = findNodes(xpathCtx, expr);
if (ATNodes->nodeNr) {
xpathCtx->node = ATNodes->nodeTab[0];
refNodes = findNodes(xpathCtx, ".//rng:ref");
for (j = 0; j <refNodes->nodeNr; j++) {
xmlNodePtr refNode = refNodes->nodeTab[j];
char *name = xmlGetProp(refNode, "name");
for (i = 0; i < gf_list_count(globalAttrGrp); i++) {
SVGGenAttrGrp *a = gf_list_get(globalAttrGrp, i);
if (!strcmp(a->name, name)) {
if (isGenericAttributesGroup(a->name)) {
setGenericAttributesFlags(a->name, e);
flattenAttributeGroup(*a, e, 1);
} else {
flattenAttributeGroup(*a, e, 0);
}
break;
}
}
}
getRealAttributes(doc, xpathCtx, ATNodes->nodeTab[0], e->attributes);
}
{
Bool found = 0;
for (i=0; i<gf_list_count(elements); i++) {
SVGGenElement *etmp = gf_list_get(elements, i);
if (!strcmp(etmp->svg_name, e->svg_name)) {
found = 1;
break;
}
}
if (!found) gf_list_add(elements, e);
}
}
}
return elements;
}
FILE *BeginFile(u32 type)
{
FILE *f;
char sPath[GF_MAX_PATH];
if (!type) {
#ifdef LOCAL_SVG_NODES
sprintf(sPath, "nodes_svg.h", GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR);
#else
if (generation_mode == 1)
sprintf(sPath, "..%c..%c..%c..%cinclude%cgpac%cnodes_svg_sa.h", GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR);
else if (generation_mode == 2)
sprintf(sPath, "..%c..%c..%c..%cinclude%cgpac%cnodes_svg_sani.h", GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR);
else if (generation_mode == 3)
sprintf(sPath, "..%c..%c..%c..%cinclude%cgpac%cnodes_svg_da.h", GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR);
#endif
} else if (type==1) {
#ifdef LOCAL_SVG_NODES
sprintf(sPath, "svg_nodes.c", GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR);
#else
if (generation_mode == 1)
sprintf(sPath, "..%c..%c..%c..%csrc%cscenegraph%csvg_nodes_sa.c", GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR);
else if (generation_mode == 2)
sprintf(sPath, "..%c..%c..%c..%csrc%cscenegraph%csvg_nodes_sani.c", GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR);
else if (generation_mode == 3)
sprintf(sPath, "..%c..%c..%c..%csrc%cscenegraph%csvg_nodes_da.c", GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR);
#endif
} else {
#ifdef LOCAL_SVG_NODES
sprintf(sPath, "lsr_tables.c", GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR);
#else
if (generation_mode == 1)
sprintf(sPath, "..%c..%c..%c..%csrc%claser%clsr_tables_sa.c", GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR);
else if (generation_mode == 2)
sprintf(sPath, "..%c..%c..%c..%csrc%claser%clsr_tables_sani.c", GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR);
else if (generation_mode == 3)
sprintf(sPath, "..%c..%c..%c..%csrc%claser%clsr_tables.c", GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR);
#endif
}
f = gf_fopen(sPath, "wt");
fprintf(f, "%s\n", COPYRIGHT);
{
time_t rawtime;
time(&rawtime);
fprintf(f, "\n/*\n\tDO NOT MOFIFY - File generated on GMT %s\n\tBY SVGGen for GPAC Version %s\n*/\n\n", asctime(gmtime(&rawtime)), GPAC_VERSION);
}
if (!type) {
if (generation_mode == 1) {
fprintf(f, "#ifndef _GF_SVG_SA_NODES_H\n");
fprintf(f, "#define _GF_SVG_SA_NODES_H\n\n");
} else if (generation_mode == 2) {
fprintf(f, "#ifndef _GF_SVG_SANI_NODES_H\n");
fprintf(f, "#define _GF_SVG_SANI_NODES_H\n\n");
} else if (generation_mode == 3) {
fprintf(f, "#ifndef _GF_SVG_NODES_H\n");
fprintf(f, "#define _GF_SVG_NODES_H\n\n");
}
fprintf(f, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n");
}
return f;
}
void EndFile(FILE *f, u32 type)
{
if (!type) {
fprintf(f, "#ifdef __cplusplus\n}\n#endif\n\n");
if (generation_mode == 1) fprintf(f, "\n\n#endif\t\t/*_GF_SVG_SA_NODES_H*/\n\n");
if (generation_mode == 2) fprintf(f, "\n\n#endif\t\t/*_GF_SVG_SANI_NODES_H*/\n\n");
if (generation_mode == 3) fprintf(f, "\n\n#endif\t\t/*_GF_SVG_NODES_H*/\n\n");
} else {
fprintf(f, "\n");
}
gf_fclose(f);
}
void generateAttributes(FILE *output, GF_List *attributes, Bool inDefine)
{
u32 i;
for (i = 0; i<gf_list_count(attributes); i++) {
SVGGenAttribute *att = (SVGGenAttribute *)gf_list_get(attributes, i);
if (inDefine)
if (i == gf_list_count(attributes) -1)
fprintf(output, "\t%s %s;\n", att->impl_type, att->implementation_name);
else
fprintf(output, "\t%s %s; \\\n", att->impl_type, att->implementation_name);
else
fprintf(output, "\t%s %s;\n", att->impl_type, att->implementation_name);
}
}
void replaceIncludes(xmlDocPtr doc, xmlXPathContextPtr xpathCtx)
{
int k;
xmlNodeSetPtr nodes;
xmlXPathObjectPtr xpathObj;
xpathObj = xmlXPathEvalExpression("//rng:include", xpathCtx);
if(xpathObj == NULL || xpathObj->type != XPATH_NODESET) return;
nodes = xpathObj->nodesetval;
for (k = 0; k < nodes->nodeNr; k++) {
xmlNodePtr node = nodes->nodeTab[k];
if (node->type == XML_ELEMENT_NODE) {
xmlChar *href;
xmlDocPtr sub_doc;
href = xmlGetNoNsProp(node, "href");
sub_doc = xmlParseFile(href);
xmlReplaceNode(nodes->nodeTab[k], xmlDocGetRootElement(sub_doc));
}
}
xmlXPathFreeObject(xpathObj);
}
int main(int argc, char **argv)
{
xmlDocPtr doc = NULL;
xmlXPathContextPtr xpathCtx = NULL;
GF_List *svg_elements = NULL;
xmlInitParser();
LIBXML_TEST_VERSION
doc = xmlParseFile(argv[1]);
if (!doc) {
printf("error: could not parse file %s\n", argv[1]);
return -1;
}
xpathCtx = xmlXPathNewContext(doc);
if(xpathCtx == NULL) {
fprintf(stderr,"Error: unable to create new XPath context\n");
xmlFreeDoc(doc);
return(-1);
}
xmlXPathRegisterNs(xpathCtx, RNG_PREFIX, RNG_NS);
xmlXPathRegisterNs(xpathCtx, RNGA_PREFIX, RNGA_NS);
xmlXPathRegisterNs(xpathCtx, SVGA_PREFIX, SVGA_NS);
replaceIncludes(doc, xpathCtx);
xmlSaveFile("completerng_props.xml", doc);
globalAttrGrp = gf_list_new();
getAllGlobalAttrGrp(doc, xpathCtx);
svg_elements = getElements(doc, xpathCtx);
svg_elements = sortElements(svg_elements);
if (argv[2] && !strcmp(argv[2], "-html")) {
generate_table(svg_elements);
} else {
if (generation_mode == 1) generateSVGCode_V1(svg_elements);
if (generation_mode == 2) generateSVGCode_V2(svg_elements);
if (generation_mode == 3) generateSVGCode_V3(svg_elements);
}
xmlXPathFreeContext(xpathCtx);
xmlCleanupParser();
return 0;
}