diff --git a/src/foundation/src/PDFsharp/src/PdfSharp/Drawing.Pdf/PdfGraphicsState.cs b/src/foundation/src/PDFsharp/src/PdfSharp/Drawing.Pdf/PdfGraphicsState.cs
index 69fcc3f7..5e899d8a 100644
--- a/src/foundation/src/PDFsharp/src/PdfSharp/Drawing.Pdf/PdfGraphicsState.cs
+++ b/src/foundation/src/PDFsharp/src/PdfSharp/Drawing.Pdf/PdfGraphicsState.cs
@@ -229,21 +229,28 @@ public void RealizeBrush(XBrush brush, PdfColorMode colorMode, int renderingMode
{
if (renderingMode != 0)
throw new InvalidOperationException("Rendering modes other than 0 can only be used with solid color brushes.");
-
- if (brush is XLinearGradientBrush gradientBrush)
+
+ Debug.Assert(UnrealizedCtm.IsIdentity, "Must realize ctm first.");
+ var matrix = renderer.DefaultViewMatrix;
+ matrix.Prepend(EffectiveCtm);
+ var pattern = new PdfShadingPattern(renderer.Owner);
+
+ switch (brush)
{
- Debug.Assert(UnrealizedCtm.IsIdentity, "Must realize ctm first.");
- XMatrix matrix = renderer.DefaultViewMatrix;
- matrix.Prepend(EffectiveCtm);
- PdfShadingPattern pattern = new PdfShadingPattern(renderer.Owner);
- pattern.SetupFromBrush(gradientBrush, matrix, renderer);
- string name = renderer.Resources.AddPattern(pattern);
- renderer.AppendFormatString("/Pattern cs\n", name);
- renderer.AppendFormatString("{0} scn\n", name);
-
- // Invalidate fill color.
- _realizedFillColor = XColor.Empty;
+ case XLinearGradientBrush gradientBrush:
+ pattern.SetupFromBrush(gradientBrush, matrix, renderer);
+ break;
+ case XRadialGradientBrush radialGradient:
+ pattern.SetupFromBrush(radialGradient, matrix, renderer);
+ break;
}
+
+ var name = renderer.Resources.AddPattern(pattern);
+ renderer.AppendFormatString("/Pattern cs\n", name);
+ renderer.AppendFormatString("{0} scn\n", name);
+
+ // Invalidate fill color.
+ _realizedFillColor = XColor.Empty;
}
}
diff --git a/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Advanced/PdfShading.cs b/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Advanced/PdfShading.cs
index 496597c6..64bb72e2 100644
--- a/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Advanced/PdfShading.cs
+++ b/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Advanced/PdfShading.cs
@@ -38,8 +38,6 @@ internal void SetupFromBrush(XLinearGradientBrush brush, XGraphicsPdfRenderer re
XColor color1 = ColorSpaceHelper.EnsureColorMode(colorMode, brush._color1);
XColor color2 = ColorSpaceHelper.EnsureColorMode(colorMode, brush._color2);
- PdfDictionary function = new PdfDictionary();
-
Elements[Keys.ShadingType] = new PdfInteger(2);
if (colorMode != PdfColorMode.Cmyk)
Elements[Keys.ColorSpace] = new PdfName("/DeviceRGB");
@@ -95,21 +93,77 @@ internal void SetupFromBrush(XLinearGradientBrush brush, XGraphicsPdfRenderer re
}
const string format = Config.SignificantDecimalPlaces3;
- Elements[Keys.Coords] = new PdfLiteral("[{0:" + format + "} {1:" + format + "} {2:" + format + "} {3:" + format + "}]", x1, y1, x2, y2);
+ Elements[Keys.Coords] =
+ new PdfLiteral("[{0:" + format + "} {1:" + format + "} {2:" + format + "} {3:" + format + "}]", x1, y1,
+ x2, y2);
//Elements[Keys.Background] = new PdfRawItem("[0 1 1]");
//Elements[Keys.Domain] =
- Elements[Keys.Function] = function;
- //Elements[Keys.Extend] = new PdfRawItem("[true true]");
+ Elements[Keys.Function] = SetupGradient(color1, color2);
+ Elements[Keys.Extend] = new PdfLiteral("[{0} {1}]",
+ brush.ExtendLeft ? "true" : "false",
+ brush.ExtendRight ? "true" : "false");
+ }
- string clr1 = "[" + PdfEncoders.ToString(color1, colorMode) + "]";
- string clr2 = "[" + PdfEncoders.ToString(color2, colorMode) + "]";
+ ///
+ /// Setups the shading from the specified brush.
+ ///
+ internal void SetupFromBrush(XRadialGradientBrush brush, XGraphicsPdfRenderer renderer)
+ {
+ if (brush == null)
+ throw new ArgumentNullException(nameof(brush));
+
+ var colorMode = _document.Options.ColorMode;
+ var color1 = ColorSpaceHelper.EnsureColorMode(colorMode, brush._color1);
+ var color2 = ColorSpaceHelper.EnsureColorMode(colorMode, brush._color2);
+
+ Elements[Keys.ShadingType] = new PdfInteger(3);
+ if (colorMode != PdfColorMode.Cmyk)
+ Elements[Keys.ColorSpace] = new PdfName("/DeviceRGB");
+ else
+ Elements[Keys.ColorSpace] = new PdfName("/DeviceCMYK");
+
+ double x1 = 0, y1 = 0, x2 = 0, y2 = 0;
+
+ XPoint pt1 = renderer.WorldToView(brush._point1);
+ XPoint pt2 = renderer.WorldToView(brush._point2);
+
+ x1 = pt1.X;
+ y1 = pt1.Y;
+ x2 = pt2.X;
+ y2 = pt2.Y;
+
+ const string format = Config.SignificantDecimalPlaces3;
+ Elements[Keys.Coords] =
+ new PdfLiteral(
+ "[{0:" + format + "} {1:" + format + "} {2:" + format + "} {3:" + format + "} {4:" + format +
+ "} {5:" + format + "}]", x1, y1, brush.InnerRadius,
+ x2, y2, brush.OuterRadius);
+
+ //Elements[Keys.Background] = new PdfRawItem("[0 1 1]");
+ //Elements[Keys.Domain] =
+
+ Elements[Keys.Function] = SetupGradient(color1, color2);
+ Elements[Keys.Extend] = new PdfLiteral("[{0} {1}]",
+ brush.ExtendLeft ? "true" : "false",
+ brush.ExtendRight ? "true" : "false");
+ }
+
+ private PdfDictionary SetupGradient(XColor color1, XColor color2)
+ {
+ var colorMode = _document.Options.ColorMode;
+ var function = new PdfDictionary();
+
+ var clr1 = "[" + PdfEncoders.ToString(color1, colorMode) + "]";
+ var clr2 = "[" + PdfEncoders.ToString(color2, colorMode) + "]";
function.Elements["/FunctionType"] = new PdfInteger(2);
function.Elements["/C0"] = new PdfLiteral(clr1);
function.Elements["/C1"] = new PdfLiteral(clr2);
function.Elements["/Domain"] = new PdfLiteral("[0 1]");
function.Elements["/N"] = new PdfInteger(1);
+
+ return function;
}
///
diff --git a/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Advanced/PdfShadingPattern.cs b/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Advanced/PdfShadingPattern.cs
index f45b2264..0a12fa20 100644
--- a/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Advanced/PdfShadingPattern.cs
+++ b/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Advanced/PdfShadingPattern.cs
@@ -43,6 +43,21 @@ internal void SetupFromBrush(XLinearGradientBrush brush, XMatrix matrix, XGraphi
//Elements[Keys.Matrix] = new PdfLiteral("[" + PdfEncoders.ToString(matrix) + "]");
Elements.SetMatrix(Keys.Matrix, matrix);
}
+
+ ///
+ /// Setups the shading pattern from the specified brush.
+ ///
+ internal void SetupFromBrush(XRadialGradientBrush brush, XMatrix matrix, XGraphicsPdfRenderer renderer)
+ {
+ if (brush == null)
+ throw new ArgumentNullException(nameof(brush));
+
+ PdfShading shading = new PdfShading(_document);
+ shading.SetupFromBrush(brush, renderer);
+ Elements[Keys.Shading] = shading;
+ //Elements[Keys.Matrix] = new PdfLiteral("[" + PdfEncoders.ToString(matrix) + "]");
+ Elements.SetMatrix(Keys.Matrix, matrix);
+ }
///
/// Common keys for all streams.
diff --git a/src/foundation/src/PDFsharp/tests/PdfSharp.Tests/Pdf/creation/BasicTests.cs b/src/foundation/src/PDFsharp/tests/PdfSharp.Tests/Pdf/creation/BasicTests.cs
index 41d2f455..afbcdcc3 100644
--- a/src/foundation/src/PDFsharp/tests/PdfSharp.Tests/Pdf/creation/BasicTests.cs
+++ b/src/foundation/src/PDFsharp/tests/PdfSharp.Tests/Pdf/creation/BasicTests.cs
@@ -372,5 +372,81 @@ public void Create_all_boxes_BasicTests()
// ...and start a viewer.
PdfFileUtility.ShowDocumentIfDebugging(filename);
}
+
+ [Fact]
+ public void Create_gradient_brushes()
+ {
+ // Create a new PDF document.
+ var document = new PdfDocument();
+ document.Info.Title = "Created with PDFsharp";
+
+ // Create an empty page in this document.
+ var page = document.AddPage();
+ var gfx = XGraphics.FromPdfPage(page);
+
+ gfx.Save();
+ gfx.TranslateTransform(50, 50);
+ gfx.DrawRectangle(null, new XLinearGradientBrush(new XPoint(50, 50), new XPoint(150, 150), XColors.Red, XColors.Green)
+ {
+ ExtendLeft = false,
+ ExtendRight = false
+ }, new XRect(0, 0, 200, 200));
+
+ gfx.Restore();
+ gfx.Save();
+ gfx.TranslateTransform(300, 50);
+
+ gfx.DrawRectangle(null, new XLinearGradientBrush(new XPoint(50, 50), new XPoint(150, 150), XColors.Red, XColors.Green)
+ {
+ ExtendLeft = true,
+ ExtendRight = true
+ }, new XRect(0, 0, 200, 200));
+
+ gfx.Restore();
+ gfx.Save();
+ gfx.TranslateTransform(50, 300);
+
+ gfx.DrawRectangle(null, new XRadialGradientBrush(new XPoint(100, 100), new XPoint(100, 100), 50, 100, XColors.Red, XColors.Green)
+ {
+ ExtendLeft = false,
+ ExtendRight = false
+ }, new XRect(0, 0, 200, 200));
+
+ gfx.Restore();
+ gfx.Save();
+ gfx.TranslateTransform(300, 300);
+
+ gfx.DrawRectangle(null, new XRadialGradientBrush(new XPoint(100, 100), new XPoint(100, 100), 50, 100, XColors.Red, XColors.Green)
+ {
+ ExtendLeft = true,
+ ExtendRight = true
+ }, new XRect(0, 0, 200, 200));
+
+ gfx.Restore();
+ gfx.Save();
+ gfx.TranslateTransform(50, 550);
+
+ gfx.DrawRectangle(null, new XRadialGradientBrush(new XPoint(50, 50), new XPoint(150, 150), 50, 100, XColors.Red, XColors.Green)
+ {
+ ExtendLeft = false,
+ ExtendRight = false
+ }, new XRect(0, 0, 200, 200));
+
+ gfx.Restore();
+ gfx.Save();
+ gfx.TranslateTransform(300, 550);
+
+ gfx.DrawRectangle(null, new XRadialGradientBrush(new XPoint(50, 50), new XPoint(150, 150), 50, 100, XColors.Red, XColors.Green)
+ {
+ ExtendLeft = true,
+ ExtendRight = true
+ }, new XRect(0, 0, 200, 200));
+
+ // Save the document...
+ string filename = PdfFileUtility.GetTempPdfFileName("GradientTest");
+ document.Save(filename);
+ // ...and start a viewer.
+ PdfFileUtility.ShowDocumentIfDebugging(filename);
+ }
}
}