# SvgIcon class

Namespace: [Grasshopper2.UI.Icon.Vector](https://developer.rhino3d.com/api/gh2/namespace/grasshopper2.ui.icon.vector.md) · Assembly: [Grasshopper2](https://developer.rhino3d.com/api/gh2/assembly/grasshopper2.md)

```cs
public static class SvgIcon
```

PROOF OF CONCEPT — import an SVG document into a native, fully themeable [VectorIcon](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.vector.vectoricon.md) instead of rasterising it to a bitmap.

WHY THIS IS NOT JUST A GENERIC SVG RENDERER The point of this class is not to draw arbitrary SVG art. It is to let an SVG-authored icon become a first-class Grasshopper icon that participates in Grasshopper's runtime icon theming. A normal SVG (and any SVG we rasterise to a bitmap) bakes its colours into fixed RGB pixels; those pixels cannot react to the user's theme. By parsing the SVG once into native [VectorElement](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.vector.vectorelement.md)s, every colour is re-resolved on each redraw through [IconContext.ResolveSpecialColour(Color)](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.iconcontext/resolvespecialcolour.md) — exactly like a hand-authored vector icon. As a bonus the result is resolution-independent (no bitmap, so none of the Windows `DrawImage` upsampling trouble that plagues raster icons), and it responds to the desaturate / flatten / high-contrast icon filters for free.

THE SPECIAL-COLOUR CONCEPT (the whole reason this class exists) Grasshopper does not think of icon colours as fixed RGB values. It thinks in semantic roles — see the [SpecialColour](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.specialcolour.md) enum. A role such as [SpecialColour.Foreground](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.specialcolour.md) or [SpecialColour.Input](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.specialcolour.md) is resolved to an actual colour at draw time, taking into account the background the icon is sitting on (so it adapts between light and dark themes), the user-configurable palette, and any active filter. That is why a role-authored icon "just works" on a dark canvas, on a light canvas, when desaturated, and after the user recolours their palette — the artwork never changed, only the resolution of its roles did.

Grasshopper's palette carries roles that mean something about a component's function, so an icon can speak the same visual language as the rest of the UI:

- [SpecialColour.Input](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.specialcolour.md) — the colour family for input / parameter-like things.
- [SpecialColour.Output](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.specialcolour.md) — for components that produce / generate something.
- [SpecialColour.Analysis](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.specialcolour.md) — for components that measure / analyse existing data.
- [SpecialColour.Symbolic](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.specialcolour.md) — for abstract / symbolic operations.
- [SpecialColour.Foreground](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.specialcolour.md) / [SpecialColour.Background](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.specialcolour.md) — the neutral figure/ground pair, with `Firm` and `Stark` variants for stronger contrast.
- [SpecialColour.Warning](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.specialcolour.md), [SpecialColour.Error](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.specialcolour.md), [SpecialColour.Hint](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.specialcolour.md), [SpecialColour.Success](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.specialcolour.md), [SpecialColour.Selected](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.specialcolour.md) — status signals.

Each palette family (`Input`, `Output`, `Analysis`, `Symbolic`) also exposes a set of coordinated shades — `…Shine` (brightest), `…Light`, the base role, `…Dark`, and `…Edge` (for outlines against the background). Authoring an icon's highlights and shadows from one family's shades makes the whole icon re-shade coherently when the palette or theme changes: swap every `gh:Input` for `gh:Output` and the same artwork becomes a correctly-shaded "output" icon.

HOW AN AUTHOR OPTS INTO A ROLE (the theming hook in the SVG) A paint value of the form `fill="gh:Foreground"` (or the long form `fill="gh-special:Input"`) is mapped to the matching [SpecialColour](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.specialcolour.md) and stays themeable; the name after the prefix is any member of the [SpecialColour](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.specialcolour.md) enum, case-insensitively. `fill="currentColor"` is shorthand for [SpecialColour.Foreground](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.specialcolour.md). An unrecognised role name renders as deep pink so the mistake is obvious. Any ordinary CSS colour (hex / `rgb()` / named) becomes a constant, non-themeable colour, exactly as in a normal SVG. An element with no fill specified at all defaults to the themeable [SpecialColour.Foreground](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.specialcolour.md) role (NOT SVG's literal black) so an un-annotated component icon stays legible on any background. These roles are inherited through `<g>` groups like any other SVG presentation attribute.

SUPPORTED SVG SUBSET Deliberately the flat-fill component-icon subset that maps cleanly onto the native vector vocabulary (see the demo .svg for authoring notes):

- Elements: `g, rect, circle, ellipse, line, polyline, polygon, path`. `defs, title, desc, metadata, style` are parsed and skipped; any other element is ignored.
- Path `d` commands: `M L H V C S Q T Z`, absolute and relative, including the smooth-curve shorthands `S`/`T` (control-point reflection).
- Paint / presentation: `fill, stroke, stroke-width, fill-opacity, stroke-opacity`, given either as attributes or inside `style="…"`, and inherited through `<g>`.
- Sizing: `viewBox` (preferred) else `width`/`height`; a trailing unit such as `px` on a length is tolerated.

NOT SUPPORTED (by design, for this PoC)

- Gradients — `<linearGradient>` / `<radialGradient>` and `fill="url(#…)"` are NOT supported. (The native `LinearFill` / `RadialFill` types could carry these in a later pass; for now, a gradient paint is unrecognised and renders as deep pink.) Author multi-tone shading with the palette's shade family instead — that is what themes correctly anyway.
- Elliptical-arc path command `A` — its 7 parameters are consumed and it is approximated by a straight line to the endpoint. Pre-flatten arcs, or use `circle`/`ellipse`.
- `transform` attributes — ignored. Geometry must be authored in the final viewBox coordinate system (flatten transforms in your editor before export). The `viewBox` is also assumed to start at `0,0`; a non-zero origin is not compensated for.
- `clipPath`, `mask`, `<filter>` effects, opacity on groups, rounded-rect corners (`rx`/`ry`), and even-odd "holes" (each sub-path is filled on its own rather than being subtracted).
- Per-element opacity applied on top of an inherited themeable role is ignored rather than baked into a constant, so the role keeps its theming (see ApplyPresentation).

## Methods

- [FromResource](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.vector.svgicon/fromresource.md): (static) Build a themeable vector icon from an embedded SVG resource. The first manifest resource whose name contains `nameFragment` (case-insensitive) is used, so callers can pass a short file name without the namespace prefix.
- [FromXml](https://developer.rhino3d.com/api/gh2/type/grasshopper2.ui.icon.vector.svgicon/fromxml.md): (static) Build a themeable vector icon from an SVG document string.
