Skip to content

Commit 7118a5d

Browse files
committed
feat: add missing SVG 2 elements and attributes for spec compliance
Add missing SVG element types: - Path element for vector path data - Image element for embedded raster images - ForeignObject for embedding non-SVG content - Switch element for conditional processing Complete SVG 2 attribute coverage: - Symbol: add refX, refY, preserveAspectRatio - Pattern: add patternUnits, patternContentUnits, patternTransform, preserveAspectRatio - Marker: add markerUnits, preserveAspectRatio - ClipPath: add clipPathUnits - Mask: add maskUnits, maskContentUnits - LinearGradient: add gradientUnits, gradientTransform, spreadMethod, href - RadialGradient: add gradientUnits, gradientTransform, spreadMethod, href - Stop: add stopColor, stopOpacity Type safety improvements: - Restore Length type for SVG width/height (was incorrectly using Double) - Add coordinate tuple initializers to Polygon and Polyline - Update tests to use type-safe Length values All changes follow W3C SVG 2 specification exactly.
1 parent a2f7fa9 commit 7118a5d

17 files changed

+550
-24
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,4 +333,4 @@ Contributions are welcome! Please feel free to submit a Pull Request.
333333

334334
## Support
335335

336-
For issues, questions, or contributions, please visit the [GitHub repository](https://github.com/coenttb/swift-svg-types).
336+
For issues, questions, or contributions, please visit the [GitHub repository](https://github.com/swift-standard/swift-svg-standard).

Sources/W3C SVG/W3C_SVG2.Document.SVG.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,19 @@ extension W3C_SVG2.Document {
4545
///
4646
/// Default value: 0
4747
/// Note: Has no effect on outermost svg element
48-
public let x: Double?
48+
public let x: W3C_SVG2.Types.Length?
4949

5050
/// The y-axis coordinate for embedded svg elements
5151
///
5252
/// Default value: 0
5353
/// Note: Has no effect on outermost svg element
54-
public let y: Double?
54+
public let y: W3C_SVG2.Types.Length?
5555

5656
/// The intrinsic width or viewport width
57-
public let width: Double?
57+
public let width: W3C_SVG2.Types.Length?
5858

5959
/// The intrinsic height or viewport height
60-
public let height: Double?
60+
public let height: W3C_SVG2.Types.Length?
6161

6262
/// The viewBox defining the coordinate system
6363
public let viewBox: W3C_SVG2.Types.ViewBox?
@@ -71,10 +71,10 @@ extension W3C_SVG2.Document {
7171
/// - height: The height (default: nil)
7272
/// - viewBox: The viewBox coordinate system (default: nil)
7373
public init(
74-
x: Double? = nil,
75-
y: Double? = nil,
76-
width: Double? = nil,
77-
height: Double? = nil,
74+
x: W3C_SVG2.Types.Length? = nil,
75+
y: W3C_SVG2.Types.Length? = nil,
76+
width: W3C_SVG2.Types.Length? = nil,
77+
height: W3C_SVG2.Types.Length? = nil,
7878
viewBox: W3C_SVG2.Types.ViewBox? = nil
7979
) {
8080
self.x = x

Sources/W3C SVG/W3C_SVG2.Document.Symbol.swift

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,21 @@ extension W3C_SVG2.Document {
8383
/// The viewBox defining the coordinate system
8484
public let viewBox: W3C_SVG2.Types.ViewBox?
8585

86+
/// Reference X coordinate for alignment
87+
///
88+
/// Can be a length or keyword (left, center, right)
89+
/// Default value: 0
90+
public let refX: Double?
91+
92+
/// Reference Y coordinate for alignment
93+
///
94+
/// Can be a length or keyword (top, center, bottom)
95+
/// Default value: 0
96+
public let refY: Double?
97+
98+
/// Controls aspect ratio preservation
99+
public let preserveAspectRatio: String?
100+
86101
/// Creates a symbol element
87102
///
88103
/// - Parameters:
@@ -92,20 +107,29 @@ extension W3C_SVG2.Document {
92107
/// - width: Symbol width (default: nil)
93108
/// - height: Symbol height (default: nil)
94109
/// - viewBox: ViewBox coordinate system (default: nil)
110+
/// - refX: Reference X coordinate (default: nil, uses 0)
111+
/// - refY: Reference Y coordinate (default: nil, uses 0)
112+
/// - preserveAspectRatio: Aspect ratio control (default: nil)
95113
public init(
96114
id: String? = nil,
97115
x: Double? = nil,
98116
y: Double? = nil,
99117
width: Double? = nil,
100118
height: Double? = nil,
101-
viewBox: W3C_SVG2.Types.ViewBox? = nil
119+
viewBox: W3C_SVG2.Types.ViewBox? = nil,
120+
refX: Double? = nil,
121+
refY: Double? = nil,
122+
preserveAspectRatio: String? = nil
102123
) {
103124
self.id = id
104125
self.x = x
105126
self.y = y
106127
self.width = width
107128
self.height = height
108129
self.viewBox = viewBox
130+
self.refX = refX
131+
self.refY = refY
132+
self.preserveAspectRatio = preserveAspectRatio
109133
}
110134

111135
/// SVG element tag name
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//
2+
// W3C_SVG2.Embedded.ForeignObject.swift
3+
// swift-w3c-svg
4+
//
5+
// The 'foreignObject' element (SVG 2 Section 13.7)
6+
//
7+
8+
extension W3C_SVG2.Embedded {
9+
/// The 'foreignObject' element
10+
///
11+
/// W3C SVG 2 Section 13.7
12+
/// https://www.w3.org/TR/SVG2/embedded.html#ForeignObjectElement
13+
///
14+
/// The 'foreignObject' element allows for inclusion of elements from a different
15+
/// XML namespace within SVG content. Typically this is used to embed XHTML content.
16+
///
17+
/// ## Geometry Properties
18+
///
19+
/// - **x**: The x-coordinate of the foreign object (default: 0)
20+
/// - **y**: The y-coordinate of the foreign object (default: 0)
21+
/// - **width**: The width of the viewport for foreign content
22+
/// - **height**: The height of the viewport for foreign content
23+
///
24+
/// ## Behavior
25+
///
26+
/// - Child elements must be from a non-SVG namespace (typically XHTML)
27+
/// - Content is clipped to the specified width and height
28+
/// - Useful for embedding HTML form controls, rich text, etc.
29+
/// - Not all renderers support foreignObject (fallback may be needed)
30+
///
31+
/// ## CSS and Styling
32+
///
33+
/// - Foreign content can use CSS styling
34+
/// - SVG presentation attributes do not apply to foreign content
35+
/// - Foreign content inherits computed values from SVG context
36+
///
37+
/// ## Example
38+
///
39+
/// ```swift
40+
/// let htmlEmbed = W3C_SVG2.Embedded.ForeignObject(
41+
/// x: 10,
42+
/// y: 10,
43+
/// width: 200,
44+
/// height: 100
45+
/// )
46+
/// // Content would contain XHTML elements
47+
/// ```
48+
///
49+
/// ## See Also
50+
///
51+
/// - ``Image``
52+
public struct ForeignObject: SVGElementType, Sendable, Equatable {
53+
/// The x-coordinate of the foreign object
54+
///
55+
/// Default value: 0
56+
public let x: Double?
57+
58+
/// The y-coordinate of the foreign object
59+
///
60+
/// Default value: 0
61+
public let y: Double?
62+
63+
/// The width of the viewport for foreign content
64+
///
65+
/// A negative value is an error.
66+
public let width: Double?
67+
68+
/// The height of the viewport for foreign content
69+
///
70+
/// A negative value is an error.
71+
public let height: Double?
72+
73+
/// Creates a foreignObject element
74+
///
75+
/// - Parameters:
76+
/// - x: The x-coordinate (default: nil, uses 0)
77+
/// - y: The y-coordinate (default: nil, uses 0)
78+
/// - width: The width (default: nil)
79+
/// - height: The height (default: nil)
80+
public init(
81+
x: Double? = nil,
82+
y: Double? = nil,
83+
width: Double? = nil,
84+
height: Double? = nil
85+
) {
86+
self.x = x
87+
self.y = y
88+
self.width = width
89+
self.height = height
90+
}
91+
92+
/// SVG element tag name
93+
public static let tagName = "foreignObject"
94+
95+
/// Whether this element is self-closing
96+
public static let isSelfClosing = false
97+
}
98+
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
//
2+
// W3C_SVG2.Embedded.Image.swift
3+
// swift-w3c-svg
4+
//
5+
// The 'image' element (SVG 2 Section 13.6)
6+
//
7+
8+
extension W3C_SVG2.Embedded {
9+
/// The 'image' element
10+
///
11+
/// W3C SVG 2 Section 13.6
12+
/// https://www.w3.org/TR/SVG2/embedded.html#ImageElement
13+
///
14+
/// The 'image' element indicates that the contents of a complete file are to be
15+
/// rendered into a given rectangle within the current user coordinate system.
16+
/// The 'image' element can reference raster image files such as PNG or JPEG,
17+
/// or other SVG files.
18+
///
19+
/// ## Geometry Properties
20+
///
21+
/// - **x**: The x-coordinate of the image (default: 0)
22+
/// - **y**: The y-coordinate of the image (default: 0)
23+
/// - **width**: The width of the image viewport
24+
/// - **height**: The height of the image viewport
25+
///
26+
/// ## Resource Properties
27+
///
28+
/// - **href**: URL reference to the image file
29+
/// - **preserveAspectRatio**: Controls scaling and alignment
30+
///
31+
/// ## Behavior
32+
///
33+
/// - If width or height is not specified, the image is not rendered
34+
/// - Supports common raster formats (PNG, JPEG, GIF, WebP)
35+
/// - Can embed other SVG documents
36+
/// - Security restrictions may prevent loading from external origins
37+
///
38+
/// ## Example
39+
///
40+
/// ```swift
41+
/// let image = W3C_SVG2.Embedded.Image(
42+
/// x: 10,
43+
/// y: 10,
44+
/// width: 100,
45+
/// height: 100,
46+
/// href: "photo.jpg",
47+
/// preserveAspectRatio: "xMidYMid meet"
48+
/// )
49+
/// ```
50+
///
51+
/// ## See Also
52+
///
53+
/// - ``ForeignObject``
54+
public struct Image: SVGElementType, Sendable, Equatable {
55+
/// The x-coordinate of the image
56+
///
57+
/// Default value: 0
58+
public let x: Double?
59+
60+
/// The y-coordinate of the image
61+
///
62+
/// Default value: 0
63+
public let y: Double?
64+
65+
/// The width of the image viewport
66+
///
67+
/// A negative value is an error. If not specified or zero, image is not rendered.
68+
public let width: Double?
69+
70+
/// The height of the image viewport
71+
///
72+
/// A negative value is an error. If not specified or zero, image is not rendered.
73+
public let height: Double?
74+
75+
/// URL reference to the image file
76+
///
77+
/// Can be:
78+
/// - Relative URL: "images/photo.jpg"
79+
/// - Absolute URL: "https://example.com/photo.jpg"
80+
/// - Data URI: "data:image/png;base64,..."
81+
/// - Fragment identifier: "#svgElementId"
82+
public let href: String?
83+
84+
/// Controls how the image is scaled and aligned
85+
///
86+
/// Format: "<align> [<meetOrSlice>]"
87+
/// Default: "xMidYMid meet"
88+
public let preserveAspectRatio: String?
89+
90+
/// Creates an image element
91+
///
92+
/// - Parameters:
93+
/// - x: The x-coordinate (default: nil, uses 0)
94+
/// - y: The y-coordinate (default: nil, uses 0)
95+
/// - width: The width (default: nil)
96+
/// - height: The height (default: nil)
97+
/// - href: The image URL (default: nil)
98+
/// - preserveAspectRatio: Scaling/alignment control (default: nil)
99+
public init(
100+
x: Double? = nil,
101+
y: Double? = nil,
102+
width: Double? = nil,
103+
height: Double? = nil,
104+
href: String? = nil,
105+
preserveAspectRatio: String? = nil
106+
) {
107+
self.x = x
108+
self.y = y
109+
self.width = width
110+
self.height = height
111+
self.href = href
112+
self.preserveAspectRatio = preserveAspectRatio
113+
}
114+
115+
/// SVG element tag name
116+
public static let tagName = "image"
117+
118+
/// Whether this element is self-closing
119+
public static let isSelfClosing = false
120+
}
121+
}

Sources/W3C SVG/W3C_SVG2.PaintServers.LinearGradient.swift

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,19 @@ extension W3C_SVG2.PaintServers {
8181
/// Format: "#elementId" or URL
8282
public let href: String?
8383

84+
/// Coordinate system for gradient geometry
85+
///
86+
/// Default value: objectBoundingBox
87+
public let gradientUnits: GradientUnits?
88+
89+
/// Transform applied to gradient coordinate system
90+
public let gradientTransform: String?
91+
92+
/// Behavior beyond gradient bounds
93+
///
94+
/// Default value: pad
95+
public let spreadMethod: SpreadMethod?
96+
8497
/// Coordinate system for gradient geometry
8598
///
8699
/// W3C SVG 2 Section 14.2.3.4
@@ -117,20 +130,29 @@ extension W3C_SVG2.PaintServers {
117130
/// - x2: End point x-coordinate (default: nil, uses 100%)
118131
/// - y2: End point y-coordinate (default: nil, uses 0%)
119132
/// - href: Template gradient reference (default: nil)
133+
/// - gradientUnits: Coordinate system (default: nil, uses objectBoundingBox)
134+
/// - gradientTransform: Transform for coordinate system (default: nil)
135+
/// - spreadMethod: Behavior beyond bounds (default: nil, uses pad)
120136
public init(
121137
id: String? = nil,
122138
x1: String? = nil,
123139
y1: String? = nil,
124140
x2: String? = nil,
125141
y2: String? = nil,
126-
href: String? = nil
142+
href: String? = nil,
143+
gradientUnits: GradientUnits? = nil,
144+
gradientTransform: String? = nil,
145+
spreadMethod: SpreadMethod? = nil
127146
) {
128147
self.id = id
129148
self.x1 = x1
130149
self.y1 = y1
131150
self.x2 = x2
132151
self.y2 = y2
133152
self.href = href
153+
self.gradientUnits = gradientUnits
154+
self.gradientTransform = gradientTransform
155+
self.spreadMethod = spreadMethod
134156
}
135157

136158
/// SVG element tag name

0 commit comments

Comments
 (0)