= Micro SVG Document Structure :toc: == Intro SVG Micro represents a strip down SVG Full 1.1 subset. Here is the main differences between SVG Full and SVG Micro. - No XML DTD. - No CSS. - `use`, `marker` and nested `svg` will be resolved. - Simplified path notation. Only absolute MoveTo, LineTo, CurveTo and ClosePath segments are allowed. - No inheritable attributes. - No `xlink:href`, except the `image` element. - No recursive references. - Only valid elements and attributes. - No unused elements. - No redundant groups. - No units. - No `style` attribute. - Default attributes are implicit. You can use https://github.com/RazrFalcon/resvg/tree/master/usvg[usvg] to convert a random SVG into a SVG Micro almost losslessly. == Elements [[svg-element]] === The `svg` element The `svg` element is the root element of the document. It's defined only once and can't be nested, unlike by the SVG spec. *Children:* * <> * <> * <> * <> *Attributes:* * `width` = < >> + The width of the rectangular region into which the referenced document is placed. * `height` = < >> + The height of the rectangular region into which the referenced document is placed. * `viewBox` = < >> * `preserveAspectRatio` = < >>? [[defs-element]] === The `defs` element Always present. Always the first `svg` child. Can be empty. *Children:* * <> * <> * <> * <> * <> * <> *Attributes:* * none [[linearGradient-element]] === The `linearGradient` element Doesn't have a `xlink:href` attribute because all attributes and `stop` children will be resolved. *Children:* * At least two <> *Attributes:* * `id` = < >> + The element ID. Always set. Guarantee to be unique. * `x1` = < >> * `y1` = < >> * `x2` = < >> * `y2` = < >> * `gradientUnits` = `userSpaceOnUse`? * `spreadMethod` = `reflect | repeat`? * `gradientTransform` = < >>? [[radialGradient-element]] === The `radialGradient` element Doesn't have a `xlink:href` attribute because all attributes and `stop` children will be resolved. *Children:* * At least two <> *Attributes:* * `id` = < >> + The element ID. Always set. Guarantee to be unique. * `cx` = < >> * `cy` = < >> * `fx` = < >> + Guarantee to be the circle defined by `cx`, `cy` and `r`. * `fy` = < >> + Guarantee to be inside the circle defined by `cx`, `cy` and `r`. * `r` = < >> * `gradientUnits` = `userSpaceOnUse`? * `spreadMethod` = `reflect | repeat`? * `gradientTransform` = < >>? [[stop-element]] === The `stop` element Gradient's `stop` children will always have unique, ordered `offset` values in the 0..1 range. *Children:* * none *Attributes:* * `offset` = < >> * `stop-color` = < >> * `stop-opacity` = < >>? + Default: 1 [[pattern-element]] === The `pattern` element Doesn't have a `xlink:href` attribute because all attributes and children will be resolved. *Children:* * `g` * `path` * `image` *Attributes:* * `id` = < >> + The element ID. Always set. Guarantee to be unique. * `x` = < >> * `y` = < >> * `width` = < >> * `height` = < >> * `viewBox` = < >>? * `preserveAspectRatio` = < >>? * `patternUnits` = `userSpaceOnUse`? + Default: objectBoundingBox * `patternContentUnits` = `objectBoundingBox`? + Default: userSpaceOnUse * `patternTransform` = < >>? [[clipPath-element]] === The `clipPath` element *Children:* * `path` *Attributes:* * `id` = < >> + The element ID. Always set. Guarantee to be unique. * `clip-path` = < >>? + An optional reference to a supplemental `clipPath`. + Default: none * `clipPathUnits` = `objectBoundingBox`? + Default: userSpaceOnUse * `transform` = < >>? [[mask-element]] === The `mask` element *Children:* * `g` * `path` * `image` *Attributes:* * `id` = < >> + The element ID. Always set. Guarantee to be unique. * `mask` = < >>? + An optional reference to a supplemental `mask`. + Default: none * `x` = < >> * `y` = < >> * `width` = < >> * `height` = < >> * `maskUnits` = `userSpaceOnUse`? + Default: objectBoundingBox * `maskContentUnits` = `objectBoundingBox`? + Default: userSpaceOnUse [[filter-element]] === The `filter` element Doesn't have a `xlink:href` attribute because all attributes and children will be resolved. *Children:* * <> *Attributes:* * `id` = < >> + The element ID. Always set. Guarantee to be unique. * `x` = < >> * `y` = < >> * `width` = < >> * `height` = < >> * `filterUnits` = `userSpaceOnUse`? + Default: objectBoundingBox * `primitiveUnits` = `objectBoundingBox`? + Default: userSpaceOnUse [[g-element]] === The `g` element The group element indicates that a new canvas should be created. All group's children elements will be rendered on it and then merged into the parent canvas. Since it's pretty expensive, especially memory wise, _usvg_ will remove as many groups as possible. And all the remaining one will indicate that a new canvas must be created. A group can have no children when it has a `filter` attribute. A group will have at least one of the attributes present. *Children:* * <> * <> * <> *Attributes:* * `id` = < >>? + An optional, but never empty, element ID. * `opacity` = < >>? * `clip-path` = < >>? + Cannot be set to `none`. * `mask` = < >>? + Cannot be set to `none`. * `filter` = < >>? + Cannot be set to `none`. * `transform` = < >>? [[path-element]] === The `path` element *Children:* * none *Attributes:* * `id` = < >>? + An optional, but never empty, element ID. * `d` = < >> + * `fill` = `none` | < >> | < >>? + If not set, than all fill-* attributes will not be set too. + Default: black * `fill-opacity` = < >>? + Default: 1 * `fill-rule` = `evenodd`? + Default: nonzero * `stroke` = < >> | < >>? + If not set, than all stroke-* attributes will not be set too. + Default: none * `stroke-width` = < >>? + Default: 1 * `stroke-linecap` = `round | square`? + Default: butt * `stroke-linejoin` = `round | bevel`? + Default: miter * `stroke-miterlimit` = < >>? + Guarantee to be > 1. + Default: 4 * `stroke-dasharray` = ``? + Guarantee to have even amount of numbers. + Default: none * `stroke-dashoffset` = < >>? * `stroke-opacity` = < >>? + Default: 1 * `clip-rule` = `evenodd`? + Will be set only inside the <>, instead of `fill-rule`. * `clip-path` = < >>? + Available only inside the <>. * `shape-rendering` = `optimizeSpeed | crispEdges`? + Default: geometricPrecision * `visibility` = `hidden | collapse`? + Default: visible * `transform` = < >>? [[image-element]] === The `image` element *Children:* * none *Attributes:* * `id` = < >>? + An optional, but never empty, element ID. * `xlink:href` = < >> + The IRI contains a file path or base64 encoded image. * `x` = < >> * `y` = < >> * `width` = < >> * `height` = < >> * `preserveAspectRatio` = < >>? * `image-rendering` = `optimizeSpeed`? + Default: optimizeQuality * `visibility` = `hidden | collapse`? + Default: visible * `transform` = < >>? == Filter primitives [[feGaussianBlur-element]] === Filter primitive attributes The attributes below are the same for all filter primitives. * `color-interpolation-filters` = `sRGB`? + Default: linearRGB * `x` = < >>? * `y` = < >>? * `width` = < >>? * `height` = < >>? * `result` = < >> The `x`, `y`, `width` and `height` attributes can be omited. SVG has a pretty complex https://www.w3.org/TR/SVG11/filters.html#FilterPrimitiveSubRegion[rules of resolving them] and I don't fully understand them yet. Neither do others, because they are pretty poorly implemented. === Filter primitive `feBlend` *Attributes:* * `in` = < >> * `in2` = < >> * `mode` = `normal | multiply | screen | darken | lighten` * <> === Filter primitive `feComposite` *Attributes:* * `in` = < >> * `in2` = < >> * `operator` = `over | in | out | atop | xor | arithmetic` * `k1` = < >> + Present only when `operator=arithmetic`. * `k2` = < >> + Present only when `operator=arithmetic`. * `k3` = < >> + Present only when `operator=arithmetic`. * `k4` = < >> + Present only when `operator=arithmetic`. * <> === Filter primitive `feFlood` *Attributes:* * `flood-color` = < >> * `flood-opacity` = < >> * <> === Filter primitive `feGaussianBlur` *Attributes:* * `in` = < >> * `stdDeviation` = < >> " " < >> * <> === Filter primitive `feImage` *Attributes:* * `preserveAspectRatio` = < >> * `image-rendering` = `optimizeSpeed`? + Default: optimizeQuality * `xlink:href` = < >>? + The IRI contains a file path or base64 encoded image. Link to an element (like in `use`) is not supported. + Unlike the `image` element, `feImage` can be without the `href` attribute. In this case the filter primitive is an empty canvas. * <> === Filter primitive `feMerge` *Children:* * `feMergeNode` *Attributes:* * <> *`feMergeNode` attributes:* * `in` = < >> === Filter primitive `feOffset` *Attributes:* * `in` = < >> * `dx` = < >> * `dy` = < >> * <> === Filter primitive `feTile` *Attributes:* * `in` = < >> * <> == Data types If an attribute has the `?` symbol after the type that's mean that that this attribute is optional. [[string-type]] ** - A Unicode string. [[number-type]] ** - A real number. + `number ::= [-]? [0-9]* "." [0-9]+` [[positive-number-type]] ** - A positive, non-zero real <>. + `positive-number ::= [0-9]* "." [0-9]+` [[opacity-type]] ** - A real <> in a 0..1 range. + `opacity ::= positive-number` [[offset-type]] ** - A real <> in a 0..1 range. + `offset ::= positive-number` [[compositing-coefficient-type]] ** - A real <> in a 0..1 range. + `compositing-coefficient ::= positive-number` [[color-type]] ** - A hex-encoded RGB color. ``` color ::= "#" hexdigit hexdigit hexdigit hexdigit hexdigit hexdigit hexdigit ::= [0-9a-f] ``` [[iri-type]] ** - An Internationalized Resource Identifier. Always a valid, local reference. + `IRI ::= string` [[func-iri-type]] ** - Functional notation for an <>. Always a valid, local reference. + `FuncIRI ::= url( )` [[filter-input-type]] ** - A filter source. A reference to a _result_ guarantee to be valid. ``` filter-input ::= SourceGraphic | SourceAlpha | BackgroundImage | BackgroundAlpha | FillPaint | StrokePaint | ``` [[viewBox-type]] ** - Defines an element viewBox. `viewBox ::= " " " " " " ` [[preserveAspectRatio-type]] ** - A scaling method definition. Works exactly the same https://www.w3.org/TR/SVG11/coords.html#PreserveAspectRatioAttribute[as described] in the SVG spec. [[transform-type]] ** - A transformation matrix. Always a `matrix` and not `translate`, `scale`, etc. Numbers are space-separated. + `transform ::= matrix( " " " " " " " " " " )` [[path-data-type]] ** - A path data. * Contains only absolute MoveTo, LineTo, CurveTo and ClosePath segments. * All segments are explicit. * The first segment is guarantee to be MoveTo. * Segments, commands and coordinates are separated only by space. * Path and all subpaths are guarantee to have at least two segments. Grammar: ``` svg-path: moveto-drawto-command-groups moveto-drawto-command-groups: moveto-drawto-command-group | moveto-drawto-command-group " " moveto-drawto-command-groups moveto-drawto-command-group: moveto " " drawto-commands drawto-commands: drawto-command | drawto-command " " drawto-commands drawto-command: closepath | lineto | curveto moveto: "M " coordinate-pair lineto: "L " coordinate-pair curveto: "C " coordinate-pair " " coordinate-pair " " coordinate-pair closepath: "Z" coordinate-pair: coordinate " " coordinate coordinate: sign? digit-sequence "." digit-sequence sign: "-" digit-sequence: digit | digit digit-sequence digit: "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ```