diff options
author | Andrew Sidwell <andy@entai.co.uk> | 2008-07-11 18:34:36 +0000 |
---|---|---|
committer | Andrew Sidwell <andy@entai.co.uk> | 2008-07-11 18:34:36 +0000 |
commit | 421e7d357831d852bb5ce50bd1729cad12b13dbf (patch) | |
tree | ffe6e32797d170c5e3627c6227e764a52b96d12a /src/treebuilder/in_foreign_content.c | |
parent | 76eeba6e538eb6ca44910bdfb5c1900cfb78b076 (diff) | |
download | libhubbub-421e7d357831d852bb5ce50bd1729cad12b13dbf.tar.gz libhubbub-421e7d357831d852bb5ce50bd1729cad12b13dbf.tar.bz2 |
Make at least a good start on SVG support (commented-out in the spec). Move foreign attribute name processing to in_foreign_content.c.
svn path=/trunk/hubbub/; revision=4614
Diffstat (limited to 'src/treebuilder/in_foreign_content.c')
-rw-r--r-- | src/treebuilder/in_foreign_content.c | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/src/treebuilder/in_foreign_content.c b/src/treebuilder/in_foreign_content.c index c400c1f..ac42b4a 100644 --- a/src/treebuilder/in_foreign_content.c +++ b/src/treebuilder/in_foreign_content.c @@ -12,6 +12,190 @@ #include "treebuilder/internal.h" #include "treebuilder/treebuilder.h" #include "utils/utils.h" +#include "utils/string.h" + + +/*** Attribute-correction stuff ***/ + +#define S(s) s, SLEN(s) + +static const struct +{ + const char *attr; + size_t attr_len; + const char *proper; +} svg_attributes[] = { + { S("attributename"), "attributeName" }, + { S("attributetype"), "attributeType" }, + { S("basefrequency"), "baseFrequency" }, + { S("baseprofile"), "baseProfile" }, + { S("calcmode"), "calcMode" }, + { S("clippathunits"), "clipPathUnits" }, + { S("contentscripttype"), "contentScriptType" }, + { S("contentstyletype"), "contentStyleType" }, + { S("diffuseconstant"), "diffuseConstant" }, + { S("edgemode"), "edgeMode" }, + { S("externalresourcesrequired"), "externalResourcesRequired" }, + { S("filterres"), "filterRes" }, + { S("filterunits"), "filterUnits" }, + { S("glyphref"), "glyphRef" }, + { S("gradienttransform"), "gradientTransform" }, + { S("gradientunits"), "gradientUnits" }, + { S("kernelmatrix"), "kernelMatrix" }, + { S("kernelunitlength"), "kernelUnitLength" }, + { S("keypoints"), "keyPoints" }, + { S("keysplines"), "keySplines" }, + { S("keytimes"), "keyTimes" }, + { S("lengthadjust"), "lengthAdjust" }, + { S("limitingconeangle"), "limitingConeAngle" }, + { S("markerheight"), "markerHeight" }, + { S("markerunits"), "markerUnits" }, + { S("markerwidth"), "markerWidth" }, + { S("maskcontentunits"), "maskContentUnits" }, + { S("maskunits"), "maskUnits" }, + { S("numoctaves"), "numOctaves" }, + { S("pathlength"), "pathLength" }, + { S("patterncontentunits"), "patternContentUnits" }, + { S("patterntransform"), "patternTransform" }, + { S("patternunits"), "patternUnits" }, + { S("pointsatx"), "pointsAtX" }, + { S("pointsaty"), "pointsAtY" }, + { S("pointsatz"), "pointsAtZ" }, + { S("preservealpha"), "preserveAlpha" }, + { S("preserveaspectratio"), "preserveAspectRatio" }, + { S("primitiveunits"), "primitiveUnits" }, + { S("refx"), "refX" }, + { S("refy"), "refY" }, + { S("repeatcount"), "repeatCount" }, + { S("repeatdur"), "repeatDur" }, + { S("requiredextensions"), "requiredExtensions" }, + { S("requiredfeatures"), "requiredFeatures" }, + { S("specularconstant"), "specularConstant" }, + { S("specularexponent"), "specularExponent" }, + { S("spreadmethod"), "spreadMethod" }, + { S("startoffset"), "startOffset" }, + { S("stddeviation"), "stdDeviation" }, + { S("stitchtiles"), "stitchTiles" }, + { S("surfacescale"), "surfaceScale" }, + { S("systemlanguage"), "systemLanguage" }, + { S("tablevalues"), "tableValues" }, + { S("targetx"), "targetX" }, + { S("targety"), "targetY" }, + { S("textlength"), "textLength" }, + { S("viewbox"), "viewBox" }, + { S("viewtarget"), "viewTarget" }, + { S("xchannelselector"), "xChannelSelector" }, + { S("ychannelselector"), "yChannelSelector" }, + { S("zoomandpan"), "zoomAndPan" }, +}; + +#undef S + +#define N_ELEMENTS(x) (sizeof(x) / sizeof((x)[0])) + + +/** + * Adjust SVG attributes. + * + * \param treebuilder Treebuilder instance + * \param tag Tag to adjust the attributes of + */ +void adjust_svg_attributes(hubbub_treebuilder *treebuilder, + hubbub_tag *tag) +{ + for (size_t i = 0; i < tag->n_attributes; i++) { + hubbub_attribute *attr = &tag->attributes[i]; + + uint8_t *name = (uint8_t *) treebuilder->input_buffer + + attr->name.data.off; + size_t len = attr->name.len; + + for (size_t j = 0; j < N_ELEMENTS(svg_attributes); j++) { + if (hubbub_string_match(name, len, + (uint8_t *)svg_attributes[j].attr, + svg_attributes[j].attr_len)) { + attr->name.type = HUBBUB_STRING_PTR; + attr->name.data.ptr = + (uint8_t *)svg_attributes[j].proper; + } + } + } +} + + + +#define S(s) (uint8_t *) s, SLEN(s) + +/** + * Adjust foreign attributes. + * + * \param treebuilder Treebuilder instance + * \param tag Tag to adjust the attributes of + */ +void adjust_foreign_attributes(hubbub_treebuilder *treebuilder, + hubbub_tag *tag) +{ + for (size_t i = 0; i < tag->n_attributes; i++) { + hubbub_attribute *attr = &tag->attributes[i]; + const uint8_t *name = treebuilder->input_buffer + + attr->name.data.off; + + /* 10 == strlen("xlink:href") */ + if (attr->name.len >= 10 && + strncmp((char *) name, "xlink:", + SLEN("xlink:")) == 0) { + size_t len = attr->name.len - 6; + name += 6; + + if (hubbub_string_match(name, len, S("actutate")) || + hubbub_string_match(name, len, + S("arcrole")) || + hubbub_string_match(name, len, + S("href")) || + hubbub_string_match(name, len, + S("role")) || + hubbub_string_match(name, len, + S("show")) || + hubbub_string_match(name, len, + S("title")) || + hubbub_string_match(name, len, + S("type"))) { + attr->ns = HUBBUB_NS_XLINK; + attr->name.data.off += 6; + attr->name.len -= 6; + } + /* 8 == strlen("xml:base") */ + } else if (attr->name.len >= 8 && + strncmp((char *) name, "xml:", SLEN("xml:")) == 0) { + size_t len = attr->name.len - 4; + name += 4; + + if (hubbub_string_match(name, len, S("base")) || + hubbub_string_match(name, len, + S("lang")) || + hubbub_string_match(name, len, + S("space"))) { + attr->ns = HUBBUB_NS_XML; + attr->name.data.off += 4; + attr->name.len -= 4; + } + } else if (hubbub_string_match(name, attr->name.len, + S("xmlns")) || + hubbub_string_match(name, attr->name.len, + S("xmlns:xlink"))) { + attr->ns = HUBBUB_NS_XMLNS; + attr->name.data.off += 6; + attr->name.len -= 6; + } + + } +} + +#undef S + + + +/*** Foreign content insertion mode ***/ /** |