Styling PDFs with Shadings Using C# and .NET

A shading pattern defines a color gradient that produces a smooth transition between colors across the area. The colors used to paint the shading pattern are specified as a function of the position of the painted area using various shading types.

In the following example, see how to fill a path with a shading pattern and clip shading content (represented by the PdfShadingContent class) to text and a path.

Полный код

using System;
using SautinSoft.Pdf;
using System.IO;
using SautinSoft.Pdf.Objects;
using SautinSoft.Pdf.Content;
using SautinSoft.Pdf.Content.Patterns;

class Program
{
    /// <summary>
    /// Shadings.
    /// </summary>
    /// <remarks>
    /// Details: https://sautinsoft.com/products/pdf/help/net/developer-guide/pdf-content-formatting-shadings.php
    /// </remarks>
    static void Main()
    {
        // Before starting this example, please get a free 100-day trial key:
        // https://sautinsoft.com/start-for-free/

        // Apply the key here:
        // PdfDocument.SetLicense("...");

        using (var document = new PdfDocument())
        {
            // Create axial shading
            // as specified in http://www.adobe.com/content/dam/acom/en/devnet/pdf/PDF32000_2008.pdf#page=193
            var shadingDictionary = PdfDictionary.Create();
            PdfIndirectObject.Create(shadingDictionary);
            shadingDictionary[PdfName.Create("ShadingType")] = PdfInteger.Create(2);
            // Color values of the shading will be expressed in DeviceRGB color space.
            shadingDictionary[PdfName.Create("ColorSpace")] = PdfName.Create("DeviceRGB");
            // Shading transitions the colors in the axis from location (0, 0) to location (250, 250).
            shadingDictionary[PdfName.Create("Coords")] = PdfArray.Create(PdfNumber.Create(0), PdfNumber.Create(0), PdfNumber.Create(250), PdfNumber.Create(250));
            var functionDictionary = PdfDictionary.Create();
            functionDictionary[PdfName.Create("FunctionType")] = PdfInteger.Create(2);
            functionDictionary[PdfName.Create("Domain")] = PdfArray.Create(PdfNumber.Create(0), PdfNumber.Create(1));
            functionDictionary[PdfName.Create("N")] = PdfNumber.Create(1);
            // Red color transitions from 1 (C0[0]) to 0 (C1[0]).
            // Green color transitions from 0 (C0[1]) to 1 (C1[1]).
            // Blue color is always 0 (C0[2] and C1[2] are 0).
            functionDictionary[PdfName.Create("C0")] = PdfArray.Create(PdfNumber.Create(1), PdfNumber.Create(0), PdfNumber.Create(0));
            functionDictionary[PdfName.Create("C1")] = PdfArray.Create(PdfNumber.Create(0), PdfNumber.Create(1), PdfNumber.Create(0));
            shadingDictionary[PdfName.Create("Function")] = functionDictionary;
            var shading = PdfShading.FromDictionary(shadingDictionary);

            var shadingPattern = new PdfShadingPattern(document, shading);

            var page = document.Pages.Add();

            // Add a background rectangle over the entire page that shows how the shading pattern, by default, starts from the bottom-left corner of the page.
            var mediaBox = page.MediaBox;
            var backgroundRect = page.Content.Elements.AddPath();
            backgroundRect.AddRectangle(mediaBox.Left, mediaBox.Bottom, mediaBox.Width, mediaBox.Height);
            var format = backgroundRect.Format;
            format.Fill.IsApplied = true;
            format.Fill.Color = PdfColor.FromPattern(shadingPattern);
            format.Fill.Opacity = 0.2;

            // Add a square that is filled with the shading pattern.
            var square = page.Content.Elements.AddPath();
            square.AddRectangle(25, 25, 200, 200);
            format = square.Format;
            format.Fill.IsApplied = true;
            format.Fill.Color = PdfColor.FromPattern(shadingPattern);
            format.Stroke.IsApplied = true;

            // Add a text group inside another group because it is recommended to change the Transform only for a single element in a group.
            var textGroup = page.Content.Elements.AddGroup().Elements.AddGroup();
            textGroup.Transform = PdfMatrix.CreateTranslation(25, 550);
            using (var formattedText = new PdfFormattedText())
            {
                formattedText.Font = new PdfFont("Helvetica", 96);
                formattedText.AppendLine("Hello ").Append("world!");

                // Draw the formatted text in the bottom-left corner of the group.
                textGroup.DrawText(formattedText, new PdfPoint(0, 0));
            }
            format = textGroup.Format;
            // Don't fill the text, but make it a clipping region for next content - shading.
            format.Fill.IsApplied = false;
            format.Clip.IsApplied = true;
            // Add a bounding rectangle before (because it would not be visible otherwise because all following content is clipped by the text) text elements.
            var path = textGroup.Elements.AddPath(textGroup.Elements.First);
            path.AddRectangle(0, 0, 250, 250);
            path.Format.Stroke.IsApplied = true;
            // Add shading content that is clipped by the text content.
            // In this case shading doesn't start from the bottom-left corner of the page, but from the bottom-left corner of the group.
            textGroup.Elements.AddShading(shading);

            // Add a path group inside another group because it is recommended to change the Transform only for a single element in a group.
            var pathGroup = page.Content.Elements.AddGroup().Elements.AddGroup();
            pathGroup.Transform = PdfMatrix.CreateTranslation(325, 550);
            path = pathGroup.Elements.AddPath();
            path.AddRectangle(0, 0, 250, 250);
            // Make path a clipping region for next content - shading.
            path.Format.Clip.IsApplied = true;
            // Add shading content that is clipped by the path content.
            // In this case shading doesn't start from the bottom-left corner of the page, but from the bottom-left corner of the group.
            var shadingContent = pathGroup.Elements.AddShading(shading);
            // Make the shading 50% opaque.
            shadingContent.Format.Fill.Opacity = 0.5;

            document.Save("Shadings.pdf");
        }

        System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo("Shadings.pdf") { UseShellExecute = true });
    }
}

Download

Option Infer On

Imports System
Imports SautinSoft.Pdf
Imports System.IO
Imports SautinSoft.Pdf.Objects
Imports SautinSoft.Pdf.Content
Imports SautinSoft.Pdf.Content.Patterns

Friend Class Program
	''' <summary>
	''' Shadings.
	''' </summary>
	''' <remarks>
	''' Details: https://sautinsoft.com/products/pdf/help/net/developer-guide/pdf-content-formatting-shadings.php
	''' </remarks>
	Shared Sub Main()
		' Before starting this example, please get a free 100-day trial key:
		' https://sautinsoft.com/start-for-free/

		' Apply the key here:
		' PdfDocument.SetLicense("...");

		Using document = New PdfDocument()
			' Create axial shading
			' as specified in http://www.adobe.com/content/dam/acom/en/devnet/pdf/PDF32000_2008.pdf#page=193
			Dim shadingDictionary = PdfDictionary.Create()
			PdfIndirectObject.Create(shadingDictionary)
			shadingDictionary(PdfName.Create("ShadingType")) = PdfInteger.Create(2)
			' Color values of the shading will be expressed in DeviceRGB color space.
			shadingDictionary(PdfName.Create("ColorSpace")) = PdfName.Create("DeviceRGB")
			' Shading transitions the colors in the axis from location (0, 0) to location (250, 250).
			shadingDictionary(PdfName.Create("Coords")) = PdfArray.Create(PdfNumber.Create(0), PdfNumber.Create(0), PdfNumber.Create(250), PdfNumber.Create(250))
			Dim functionDictionary = PdfDictionary.Create()
			functionDictionary(PdfName.Create("FunctionType")) = PdfInteger.Create(2)
			functionDictionary(PdfName.Create("Domain")) = PdfArray.Create(PdfNumber.Create(0), PdfNumber.Create(1))
			functionDictionary(PdfName.Create("N")) = PdfNumber.Create(1)
			' Red color transitions from 1 (C0[0]) to 0 (C1[0]).
			' Green color transitions from 0 (C0[1]) to 1 (C1[1]).
			' Blue color is always 0 (C0[2] and C1[2] are 0).
			functionDictionary(PdfName.Create("C0")) = PdfArray.Create(PdfNumber.Create(1), PdfNumber.Create(0), PdfNumber.Create(0))
			functionDictionary(PdfName.Create("C1")) = PdfArray.Create(PdfNumber.Create(0), PdfNumber.Create(1), PdfNumber.Create(0))
			shadingDictionary(PdfName.Create("Function")) = functionDictionary
			Dim shading = PdfShading.FromDictionary(shadingDictionary)

			Dim shadingPattern = New PdfShadingPattern(document, shading)

			Dim page = document.Pages.Add()

			' Add a background rectangle over the entire page that shows how the shading pattern, by default, starts from the bottom-left corner of the page.
			Dim mediaBox = page.MediaBox
			Dim backgroundRect = page.Content.Elements.AddPath()
			backgroundRect.AddRectangle(mediaBox.Left, mediaBox.Bottom, mediaBox.Width, mediaBox.Height)
			Dim format = backgroundRect.Format
			format.Fill.IsApplied = True
			format.Fill.Color = PdfColor.FromPattern(shadingPattern)
			format.Fill.Opacity = 0.2

			' Add a square that is filled with the shading pattern.
			Dim square = page.Content.Elements.AddPath()
			square.AddRectangle(25, 25, 200, 200)
			format = square.Format
			format.Fill.IsApplied = True
			format.Fill.Color = PdfColor.FromPattern(shadingPattern)
			format.Stroke.IsApplied = True

			' Add a text group inside another group because it is recommended to change the Transform only for a single element in a group.
			Dim textGroup = page.Content.Elements.AddGroup().Elements.AddGroup()
			textGroup.Transform = PdfMatrix.CreateTranslation(25, 550)
			Using formattedText = New PdfFormattedText()
				formattedText.Font = New PdfFont("Helvetica", 96)
				formattedText.AppendLine("Hello ").Append("world!")

				' Draw the formatted text in the bottom-left corner of the group.
				textGroup.DrawText(formattedText, New PdfPoint(0, 0))
			End Using
			format = textGroup.Format
			' Don't fill the text, but make it a clipping region for next content - shading.
			format.Fill.IsApplied = False
			format.Clip.IsApplied = True
			' Add a bounding rectangle before (because it would not be visible otherwise because all following content is clipped by the text) text elements.
			Dim path = textGroup.Elements.AddPath(textGroup.Elements.First)
			path.AddRectangle(0, 0, 250, 250)
			path.Format.Stroke.IsApplied = True
			' Add shading content that is clipped by the text content.
			' In this case shading doesn't start from the bottom-left corner of the page, but from the bottom-left corner of the group.
			textGroup.Elements.AddShading(shading)

			' Add a path group inside another group because it is recommended to change the Transform only for a single element in a group.
			Dim pathGroup = page.Content.Elements.AddGroup().Elements.AddGroup()
			pathGroup.Transform = PdfMatrix.CreateTranslation(325, 550)
			path = pathGroup.Elements.AddPath()
			path.AddRectangle(0, 0, 250, 250)
			' Make path a clipping region for next content - shading.
			path.Format.Clip.IsApplied = True
			' Add shading content that is clipped by the path content.
			' In this case shading doesn't start from the bottom-left corner of the page, but from the bottom-left corner of the group.
			Dim shadingContent = pathGroup.Elements.AddShading(shading)
			' Make the shading 50% opaque.
			shadingContent.Format.Fill.Opacity = 0.5

			document.Save("Shadings.pdf")
		End Using

		System.Diagnostics.Process.Start(New System.Diagnostics.ProcessStartInfo("Shadings.pdf") With {.UseShellExecute = True})
	End Sub
End Class

Download


Если вам нужен пример кода или у вас есть вопрос: напишите нам по адресу support@sautinsoft.com или спросите в онлайн-чате (правый нижний угол этой страницы) или используйте форму ниже:



Вопросы и предложения всегда приветствуются!

Мы разрабатываем компоненты .Net с 2002 года. Мы знаем форматы PDF, DOCX, RTF, HTML, XLSX и Images. Если вам нужна помощь в создании, изменении или преобразовании документов в различных форматах, мы можем вам помочь. Мы напишем для вас любой пример кода абсолютно бесплатно.