Paint Builder – Configure SVG Fill and Stroke in C#

What Is PaintBuilder?

The Aspose.SVG Builder API allows developers to configure SVG fill and stroke properties programmatically using a fluent syntax. The PaintBuilder class simplifies the creation of SVG paint values, including solid colors and references to paint servers such as patterns and gradients, in C# applications.

SVG paint configuration is commonly used for creating reusable backgrounds, decorative textures, chart styles, icon fills, and vector graphics effects. With nested builders and chained configuration methods, the Builder API makes SVG generation more readable and easier to maintain.

This article explains how to use PaintBuilder, a builder class for creating paint values for SVG elements. This class is used to specify the value of the stroke or fill attributes for SVG shapes and elements when applying colors, patterns, or gradients.

PaintBuilder is part of the Aspose.SVG Builder API and is used to configure SVG fill and stroke values. It supports multiple SVG paint values, including:

The Builder API uses a fluent configuration model that simplifies SVG element creation and styling.

Create SVG Pattern Fills

SVG patterns allow you to fill shapes using repeating graphical elements instead of solid colors. Patterns are defined once and can be reused across multiple SVG elements. In the following example, the PaintServerId() method of the PaintBuilder class sets the fill value to reference a paint server by its Id.

1using Aspose.Svg.Builder;
2using System.Drawing;
3using System.IO;
 1// Create SVG pattern with polygons and apply as fill to rectangle using C# Builder API
 2
 3using (SVGDocument document = new SVGDocument())
 4{
 5    SVGSVGElement svg = new SVGSVGElementBuilder()
 6        .Width(100, LengthType.Percentage).Height(100, LengthType.Percentage)
 7        .ViewBox(0, 0, 400, 400)
 8        .AddG(g => g
 9            .AddPattern(p => p.Id("stars")
10                .ViewBox(0, 0, 20, 20)
11                .Width(5, LengthType.Percentage)
12                .Height(5, LengthType.Percentage)
13                .PatternUnits(CoordinateUnits.UserSpaceOnUse)
14                .AddPolygon(points: new double[] { 5, 0, 7, 3, 10, 5, 7, 7, 5, 10, 3, 7, 0, 5, 3, 3 }, fill: Color.Teal)
15                .AddPolygon(points: new double[] { 15, 0, 17, 3, 20, 5, 17, 7, 15, 10, 13, 7, 10, 5, 13, 3 }, fill: Color.DarkRed)
16                .AddPolygon(points: new double[] { 15, 10, 17, 13, 20, 15, 17, 17, 15, 20, 13, 17, 10, 15, 13, 13 }, fill: Color.DarkBlue)
17            )
18            .AddRect(r => r.Rect(20, 40, 440, 80).Fill(pt => pt.PaintServerId("stars")))
19            )
20        .Build(document.FirstChild as SVGSVGElement);
21    document.Save(Path.Combine(OutputDir, "pattern-stars.svg"));
22}

In this example, a pattern is first defined using AddPattern(), where various colored polygons are combined to create a complex fill pattern. The AddPattern() method adds a <pattern> element configuration to the builder. The pattern is given an identifier stars. Subsequently, this pattern is applied to a rectangle element using the Fill() method with PaintServerId("stars"), which references the previously defined pattern.

Visualization of the stars pattern applied to an SVG rectangle.

Apply Patterns to SVG Shapes

Pattern fills can be applied to various SVG elements, including rectangles, circles, paths, polygons, and text elements. Any SVG element that supports the fill property can use a paint server reference created with PaintBuilder.

The following C# code example demonstrates how to create SVG patterns and apply them to shapes within the document. The code showcases the “builder within a builder” approach, which uses nested builder classes to facilitate the construction of complex objects and provides a modular, structured approach to SVG document creation:

1using Aspose.Svg.Builder;
2using System.Drawing;
3using System.IO;
 1// Create SVG patterns with reusable elements and apply them to circles using C# Builder API
 2
 3using (SVGDocument document = new SVGDocument())
 4{
 5    SVGSVGElement svg = new SVGSVGElementBuilder()
 6        .Width(100, LengthType.Percentage).Height(100, LengthType.Percentage)
 7        .ViewBox(0, 0, 600, 600)
 8        .AddG(g => g
 9            .FontFamily("Arial")
10            .FontSize(10)
11            .AddPattern(p => p.Id("Pat3a")
12                .Rect(0, 0, 20, 20)
13                .PatternUnits(CoordinateUnits.UserSpaceOnUse)
14                .AddRect(r => r.Rect(0, 0, 10, 10).Fill(Color.LightSlateGray))
15                .AddRect(r => r.Rect(10, 0, 10, 10).Fill(Color.Teal))
16                .AddRect(r => r.Rect(0, 10, 10, 10).Fill(Color.DarkRed))
17                .AddRect(r => r.Rect(10, 10, 10, 10).Fill(Color.Gold))
18            )
19            .AddPattern(p => p.Id("Pat3b")
20                .Href("#Pat3a")
21                .Width(23).Height(23)
22            )
23            .AddPattern(p => p.Id("Pat3c")
24                .Href("#Pat3a")
25                .Width(15).Height(15)
26            )
27            .AddCircle(circle => circle.Cx(90).Cy(130).R(70).Fill(pt => pt.PaintServerId("Pat3a")))
28            .AddText(t => t.X(55).Y(50)
29                .AddContent("Pattern #Pat3a")
30            )
31            .AddCircle(circle => circle.Cx(240).Cy(130).R(70).Fill(pt => pt.PaintServerId("Pat3b")))
32            .AddText(t => t.X(205).Y(50)
33                .AddContent("Pattern #Pat3b")
34            )
35            .AddCircle(circle => circle.Cx(390).Cy(130).R(70).Fill(pt => pt.PaintServerId("Pat3c")))
36            .AddText(t => t.X(355).Y(50)
37                .AddContent("Pattern #Pat3c")
38            )
39        )
40        .Build(document.FirstChild as SVGSVGElement);
41    document.Save(Path.Combine(OutputDir, "patterns.svg"));
42}

Visualization of the patterns.svg file with multiple SVG pattern fills.

How the Pattern Works

The <pattern> element defines a reusable tile that repeats across the filled shape. In this example:

The pattern can be reused for multiple SVG elements by referencing the same pattern ID. Smaller pattern dimensions create denser repetitions, while larger values increase spacing between repeated elements.

In the example, three different patterns, named Pat3a, Pat3b, and Pat3c, are added to the SVG document.

The height and width of a tile in a pattern element define the size of the repeated pattern unit in the SVG document. This size determines how the pattern will look when applied to shapes or elements in the document. In pattern Pat3b, increasing the height and width of the tile enlarges the pattern unit, resulting in unfilled (transparent) areas. In the pattern Pat3c, reducing the height and width of the tile makes the pattern appear denser, creating a different visual effect.

So, adjusting the height and width of the tile in an SVG <pattern> element allows you to control the density and repetition of the pattern within the SVG document and enables the creation of diverse visual effects.

Create Linear Gradient Fills

Aspose.SVG Builder API allows you to create reusable SVG linear gradients and apply them to SVG shapes programmatically. Gradient fills are commonly used for backgrounds, buttons, charts, decorative graphics, and UI elements.

 1using Aspose.Svg.Builder;
 2using System.Drawing;
 3using System.IO;
 4
 5using (SVGDocument document = new SVGDocument())
 6{
 7    SVGSVGElement svg = new SVGSVGElementBuilder()
 8        .Width(400).Height(200)
 9        .ViewBox(0, 0, 400, 200)
10        .AddDefs(defs => defs
11            .AddLinearGradient(gradient => gradient
12                .Id("gradientFill")
13                .X1(0, LengthType.Percentage).Y1(0, LengthType.Percentage)
14                .X2(100, LengthType.Percentage).Y2(0, LengthType.Percentage)
15                .AddStop(stop => stop
16                    .Offset(0, StopUnitType.Percentage)
17                    .Attribute("stop-color", "gold"))
18                .AddStop(stop => stop
19                    .Offset(100, StopUnitType.Percentage)
20                    .Attribute("stop-color", "teal"))))
21        .AddRect(rect => rect
22            .Rect(20, 20, 360, 160)
23            .Fill(paint => paint.PaintServerId("gradientFill")))
24        .Build(document.FirstChild as SVGSVGElement);
25
26    document.Save(Path.Combine(OutputDir, "linear-gradient-fill.svg"));
27}

How the Gradient Works

The example creates a reusable SVG <linearGradient> definition inside the <defs> section and applies it to a rectangle fill.

Common Mistakes and Fixes

ProblemCauseFix
Pattern is not visibleIncorrect pattern IDEnsure PaintServerId() matches the pattern Id()
Pattern appears stretchedTile size is too largeAdjust pattern Width() and Height()
Pattern does not repeat correctlyIncorrect PatternUnits valueUse UserSpaceOnUse when fixed tile sizes are required
Fill is not appliedPattern is defined outside accessible scopeDefine patterns before applying them

FAQ

1. What is a paint server in SVG?
A paint server is an SVG resource used to provide fill or stroke values. Common paint servers include patterns and gradients referenced through url(#id).

2. Can I reuse the same SVG pattern for multiple shapes?
Yes. A single SVG pattern can be reused across multiple elements by referencing the same pattern ID with PaintServerId().

3. What is the difference between the CoordinateUnits: UserSpaceOnUse and ObjectBoundingBox?
UserSpaceOnUse uses fixed coordinates for pattern rendering, while ObjectBoundingBox scales the pattern relative to the size of the target element.

4. Why does my SVG pattern appear stretched?
This usually happens when the pattern tile size is too large or when the pattern coordinate system does not match the target SVG element dimensions.

5. Can I apply SVG patterns to text elements?
Yes. SVG text elements support the fill property and can use pattern fills in the same way as shapes.

6. Are SVG gradients supported by PaintBuilder?
Yes. PaintBuilder supports gradient paint server references for configuring SVG gradient fills programmatically.

Related Resources

Close
Loading

Analyzing your prompt, please hold on...

An error occurred while retrieving the results. Please refresh the page and try again.

Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.