Skip to content

Commit 95e6f5f

Browse files
committed
feat: Add PaintServers namespace (Chapter 14)
Implement complete Chapter 14 Paint Servers: - Add W3C_SVG2.PaintServers namespace - Add LinearGradient element (Section 14.2.3) - Add RadialGradient element (Section 14.2.4) - Add Stop element (Section 14.2.2) - Add Pattern element (Section 14.3) - Add comprehensive tests for all PaintServers elements Paint servers enable fill and stroke properties to reference reusable graphical resources: - LinearGradient: Smooth color transitions along vector line - RadialGradient: Color transitions from focal point to outer circle - Stop: Define color positions within gradients - Pattern: Tile graphic elements for fill/stroke Tests: 50 passing in 20 suites
1 parent cff86f3 commit 95e6f5f

File tree

6 files changed

+606
-0
lines changed

6 files changed

+606
-0
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
//
2+
// W3C_SVG2.PaintServers.LinearGradient.swift
3+
// swift-w3c-svg
4+
//
5+
// The 'linearGradient' element (SVG 2 Section 14.2.3)
6+
//
7+
8+
extension W3C_SVG2.PaintServers {
9+
/// The 'linearGradient' element
10+
///
11+
/// W3C SVG 2 Section 14.2.3
12+
/// https://www.w3.org/TR/SVG2/pservers.html#LinearGradientElement
13+
///
14+
/// Linear gradients define smooth color transitions along a vector line.
15+
///
16+
/// ## Gradient Vector
17+
///
18+
/// The gradient vector is defined by start point (x1, y1) and end point (x2, y2).
19+
/// When start and end points coincide, the area fills with the terminal stop color.
20+
///
21+
/// ## Key Attributes
22+
///
23+
/// - **x1, y1**: Start point of gradient vector (default: 0%, 0%)
24+
/// - **x2, y2**: End point of gradient vector (default: 100%, 0%)
25+
/// - **gradientUnits**: Coordinate system mode (userSpaceOnUse or objectBoundingBox)
26+
/// - **spreadMethod**: Behavior beyond gradient bounds (pad, reflect, repeat)
27+
///
28+
/// ## Usage
29+
///
30+
/// Referenced via URL syntax in fill or stroke properties:
31+
/// ```
32+
/// fill="url(#myGradient)"
33+
/// ```
34+
///
35+
/// ## Example
36+
///
37+
/// ```swift
38+
/// let gradient = W3C_SVG2.PaintServers.LinearGradient(
39+
/// id: "myGradient",
40+
/// x1: "0%",
41+
/// y1: "0%",
42+
/// x2: "100%",
43+
/// y2: "100%"
44+
/// )
45+
/// ```
46+
///
47+
/// ## See Also
48+
///
49+
/// - ``RadialGradient``
50+
/// - ``Stop``
51+
public struct LinearGradient: Sendable, Equatable {
52+
/// Identifier for referencing the gradient
53+
public let id: String?
54+
55+
/// X-coordinate of gradient vector start point
56+
///
57+
/// Default value: 0%
58+
/// Accepts length or percentage values
59+
public let x1: String?
60+
61+
/// Y-coordinate of gradient vector start point
62+
///
63+
/// Default value: 0%
64+
/// Accepts length or percentage values
65+
public let y1: String?
66+
67+
/// X-coordinate of gradient vector end point
68+
///
69+
/// Default value: 100%
70+
/// Accepts length or percentage values
71+
public let x2: String?
72+
73+
/// Y-coordinate of gradient vector end point
74+
///
75+
/// Default value: 0%
76+
/// Accepts length or percentage values
77+
public let y2: String?
78+
79+
/// Reference to template gradient element
80+
///
81+
/// Format: "#elementId" or URL
82+
public let href: String?
83+
84+
/// Creates a linear gradient element
85+
///
86+
/// - Parameters:
87+
/// - id: Identifier for referencing (default: nil)
88+
/// - x1: Start point x-coordinate (default: nil, uses 0%)
89+
/// - y1: Start point y-coordinate (default: nil, uses 0%)
90+
/// - x2: End point x-coordinate (default: nil, uses 100%)
91+
/// - y2: End point y-coordinate (default: nil, uses 0%)
92+
/// - href: Template gradient reference (default: nil)
93+
public init(
94+
id: String? = nil,
95+
x1: String? = nil,
96+
y1: String? = nil,
97+
x2: String? = nil,
98+
y2: String? = nil,
99+
href: String? = nil
100+
) {
101+
self.id = id
102+
self.x1 = x1
103+
self.y1 = y1
104+
self.x2 = x2
105+
self.y2 = y2
106+
self.href = href
107+
}
108+
109+
/// SVG element tag name
110+
public static let tagName = "linearGradient"
111+
112+
/// Whether this element is self-closing
113+
public static let isSelfClosing = false
114+
}
115+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
//
2+
// W3C_SVG2.PaintServers.Pattern.swift
3+
// swift-w3c-svg
4+
//
5+
// The 'pattern' element (SVG 2 Section 14.3)
6+
//
7+
8+
extension W3C_SVG2.PaintServers {
9+
/// The 'pattern' element
10+
///
11+
/// W3C SVG 2 Section 14.3
12+
/// https://www.w3.org/TR/SVG2/pservers.html#Patterns
13+
///
14+
/// Patterns tile a graphic element to fill or stroke areas.
15+
///
16+
/// ## Tile Geometry
17+
///
18+
/// - **x, y**: Reference rectangle origin (default: 0)
19+
/// - **width, height**: Tile dimensions (default: 0; zero disables rendering)
20+
///
21+
/// ## Coordinate Systems
22+
///
23+
/// - **patternUnits**: For x, y, width, height (userSpaceOnUse or objectBoundingBox)
24+
/// - **patternContentUnits**: For pattern contents (default: userSpaceOnUse)
25+
///
26+
/// ## Clipping Behavior
27+
///
28+
/// The user agent stylesheet sets `overflow: hidden`, clipping pattern
29+
/// content to tile boundaries unless overridden.
30+
///
31+
/// ## Usage
32+
///
33+
/// Referenced via URL syntax in fill or stroke properties:
34+
/// ```
35+
/// fill="url(#myPattern)"
36+
/// ```
37+
///
38+
/// ## Example
39+
///
40+
/// ```swift
41+
/// let pattern = W3C_SVG2.PaintServers.Pattern(
42+
/// id: "dots",
43+
/// x: 0,
44+
/// y: 0,
45+
/// width: 10,
46+
/// height: 10
47+
/// )
48+
/// ```
49+
///
50+
/// ## See Also
51+
///
52+
/// - ``LinearGradient``
53+
/// - ``RadialGradient``
54+
public struct Pattern: Sendable, Equatable {
55+
/// Identifier for referencing the pattern
56+
public let id: String?
57+
58+
/// X-coordinate of reference rectangle origin
59+
///
60+
/// Default value: 0
61+
public let x: Double?
62+
63+
/// Y-coordinate of reference rectangle origin
64+
///
65+
/// Default value: 0
66+
public let y: Double?
67+
68+
/// Tile width
69+
///
70+
/// Default value: 0 (zero disables rendering)
71+
public let width: Double?
72+
73+
/// Tile height
74+
///
75+
/// Default value: 0 (zero disables rendering)
76+
public let height: Double?
77+
78+
/// The viewBox defining the coordinate system for pattern content
79+
public let viewBox: W3C_SVG2.Types.ViewBox?
80+
81+
/// Reference to template pattern element
82+
///
83+
/// Format: "#elementId" or URL
84+
public let href: String?
85+
86+
/// Creates a pattern element
87+
///
88+
/// - Parameters:
89+
/// - id: Identifier for referencing (default: nil)
90+
/// - x: Reference rectangle origin x (default: nil, uses 0)
91+
/// - y: Reference rectangle origin y (default: nil, uses 0)
92+
/// - width: Tile width (default: nil, uses 0)
93+
/// - height: Tile height (default: nil, uses 0)
94+
/// - viewBox: ViewBox coordinate system (default: nil)
95+
/// - href: Template pattern reference (default: nil)
96+
public init(
97+
id: String? = nil,
98+
x: Double? = nil,
99+
y: Double? = nil,
100+
width: Double? = nil,
101+
height: Double? = nil,
102+
viewBox: W3C_SVG2.Types.ViewBox? = nil,
103+
href: String? = nil
104+
) {
105+
self.id = id
106+
self.x = x
107+
self.y = y
108+
self.width = width
109+
self.height = height
110+
self.viewBox = viewBox
111+
self.href = href
112+
}
113+
114+
/// SVG element tag name
115+
public static let tagName = "pattern"
116+
117+
/// Whether this element is self-closing
118+
public static let isSelfClosing = false
119+
}
120+
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
//
2+
// W3C_SVG2.PaintServers.RadialGradient.swift
3+
// swift-w3c-svg
4+
//
5+
// The 'radialGradient' element (SVG 2 Section 14.2.4)
6+
//
7+
8+
extension W3C_SVG2.PaintServers {
9+
/// The 'radialGradient' element
10+
///
11+
/// W3C SVG 2 Section 14.2.4
12+
/// https://www.w3.org/TR/SVG2/pservers.html#RadialGradientElement
13+
///
14+
/// Radial gradients create color transitions radiating from a focal point
15+
/// to an outer circle.
16+
///
17+
/// ## Gradient Geometry
18+
///
19+
/// - **Outer Circle**: Defined by center (cx, cy) and radius (r)
20+
/// - **Focal Circle**: Defined by center (fx, fy) and radius (fr)
21+
/// - Color transitions radiate from focal circle to outer circle
22+
///
23+
/// ## New in SVG 2
24+
///
25+
/// The `fr` (focal radius) attribute is new in SVG 2, allowing for more
26+
/// complex radial gradient effects.
27+
///
28+
/// ## Geometric Consideration
29+
///
30+
/// Rings that are conceptually circular within object bounding box space
31+
/// will render as elliptical when non-uniform scaling applies.
32+
///
33+
/// ## Usage
34+
///
35+
/// Referenced via URL syntax in fill or stroke properties:
36+
/// ```
37+
/// fill="url(#myRadialGradient)"
38+
/// ```
39+
///
40+
/// ## Example
41+
///
42+
/// ```swift
43+
/// let gradient = W3C_SVG2.PaintServers.RadialGradient(
44+
/// id: "radialGrad",
45+
/// cx: "50%",
46+
/// cy: "50%",
47+
/// r: "50%"
48+
/// )
49+
/// ```
50+
///
51+
/// ## See Also
52+
///
53+
/// - ``LinearGradient``
54+
/// - ``Stop``
55+
public struct RadialGradient: Sendable, Equatable {
56+
/// Identifier for referencing the gradient
57+
public let id: String?
58+
59+
/// X-coordinate of outer circle center
60+
///
61+
/// Default value: 50%
62+
/// Accepts length or percentage values
63+
public let cx: String?
64+
65+
/// Y-coordinate of outer circle center
66+
///
67+
/// Default value: 50%
68+
/// Accepts length or percentage values
69+
public let cy: String?
70+
71+
/// Radius of outer circle
72+
///
73+
/// Default value: 50%
74+
/// Accepts length or percentage values
75+
public let r: String?
76+
77+
/// X-coordinate of focal circle center
78+
///
79+
/// Default value: cx value (if unspecified)
80+
/// Accepts length or percentage values
81+
public let fx: String?
82+
83+
/// Y-coordinate of focal circle center
84+
///
85+
/// Default value: cy value (if unspecified)
86+
/// Accepts length or percentage values
87+
public let fy: String?
88+
89+
/// Radius of focal circle
90+
///
91+
/// Default value: 0%
92+
/// New in SVG 2
93+
/// Accepts length or percentage values
94+
public let fr: String?
95+
96+
/// Reference to template gradient element
97+
///
98+
/// Format: "#elementId" or URL
99+
public let href: String?
100+
101+
/// Creates a radial gradient element
102+
///
103+
/// - Parameters:
104+
/// - id: Identifier for referencing (default: nil)
105+
/// - cx: Outer circle center x-coordinate (default: nil, uses 50%)
106+
/// - cy: Outer circle center y-coordinate (default: nil, uses 50%)
107+
/// - r: Outer circle radius (default: nil, uses 50%)
108+
/// - fx: Focal circle center x-coordinate (default: nil, uses cx)
109+
/// - fy: Focal circle center y-coordinate (default: nil, uses cy)
110+
/// - fr: Focal circle radius (default: nil, uses 0%)
111+
/// - href: Template gradient reference (default: nil)
112+
public init(
113+
id: String? = nil,
114+
cx: String? = nil,
115+
cy: String? = nil,
116+
r: String? = nil,
117+
fx: String? = nil,
118+
fy: String? = nil,
119+
fr: String? = nil,
120+
href: String? = nil
121+
) {
122+
self.id = id
123+
self.cx = cx
124+
self.cy = cy
125+
self.r = r
126+
self.fx = fx
127+
self.fy = fy
128+
self.fr = fr
129+
self.href = href
130+
}
131+
132+
/// SVG element tag name
133+
public static let tagName = "radialGradient"
134+
135+
/// Whether this element is self-closing
136+
public static let isSelfClosing = false
137+
}
138+
}

0 commit comments

Comments
 (0)