Difference between revisions of "Patterns in PDF"

From
Jump to: navigation, search
(Created page with "==Pattern Colorspace== While everyone can imagine what a pattern is, a ''pattern colorspace'' looks very strange from the first sight. PDF treats patterns as ''regular col...")
 
m (Shading patterns)
Line 128: Line 128:
  
 
==Shading patterns==
 
==Shading patterns==
 +
Shading patterns provide a smooth transition between colors across an area to be painted, independent of the resolution of any particular output media and without specifying the number of steps in the color transition. Patterns of this type can be used to create complex fills and have several subtypes described in section ''8.7.4.5 “Shading Types”'' of the specification.
 +
Using the API provided by [[Apitron PDF Kit]] one is able to create advanced color gradient fills based on standard linear and exponential interpolation functions as well as pure [[PostScript]] function-based color transition effects.
 +
 +
In [[PDF]], the object used to create a complex fill is called ''Shading'', and you may read about all low level details involved in the section ''8.7.4 Shading Patterns'' of the PDF specification. Every ''Shading object'' requires a ''function object'' that defines the color transformation needed to create the final color at the each point where the shading is defined. Functions are described in section ''7.10 Functions'' of the [[PDF]] specification. Using various function types it becomes possible to implement '''linear''', '''bilinear''' and '''exponential interpolation''' as well as other color effects.
 +
One can use different functions to calculate the final value for each color component, or use the same function to calculate all of them. Currently available function types are: ''Sampled'', ''Exponential'', ''StitchingFunction'' and ''[[PostScript]]''. Shading types available are: ''axial'', ''radial'' and ''function-based''.
 +
 +
When the area to be painted has a relatively simple form and matches that of the gradient fill itself(think of a fill as a separate graphical object having desired appearance and overlapping the area to be filled) or you have a simple clipping path for it, the ''ClippedContent::PaintShading()'' function may be used instead of the usual painting approach. It accepts a ''Shading'' object as an operand and applies the corresponding gradient fill directly to the current user space applying the additional clipping path given as a parameter if needed.
 +
 +
Another way to use shadings is to define a ''ShadingPattern''. Similar to the ''TilingPattern'' object, it can be used as a color for filling and stroking operations if you set the current stroking or non-stroking colorspace to ''PredefinedColorpaces::Pattern''. This way you’ll be able to draw whatever you want using the specified shading pattern as a color provider for the stroked or filled path(or both).
 +
Both methods have their own pros and cons and it’s up to you to choose the one that works best in your situation. Sections below describe various functions types and shadings types in further details and sample code.

Revision as of 17:14, 26 February 2018

Pattern Colorspace

While everyone can imagine what a pattern is, a pattern colorspace looks very strange from the first sight. PDF treats patterns as regular colors defined in so-called Pattern Colorspace. Therefore if something needs to be filled or stroked with the pattern, this pattern is being selected as either non-stroking or stroking color and the current colorspace is being set to a special type Pattern.

Tiling patterns

In PDF, it’s possible to draw repeating content using objects called tiling patterns, and for the detailed explanation see section 8.7.3 “Tiling Patterns” of the specification. Tiling patterns can be of two types, colored and uncolored. The first one contains all color information needed to draw itself and is a self-contained entity while the second allows you to specify custom colors for its stroking and non-stroking operations making it context dependent.

The code below draws objects using both types of tiling patterns on PDF page one by one:

// open and load the file
using (FileStream outputStream = new FileStream("patterns.pdf", FileMode.Create))
{
    // create new PDF document
    using(FixedDocument document = new FixedDocument())
    {
        Page page = new Page(new PageBoundary(Boundaries.A4));
        document.Pages.Add(page);
                
        // set stroking settings
        page.Content.SetLineWidth(2);
        page.Content.SetLineDashPattern(new float[] { 2, 2, 4, 2 }, 3);
        page.Content.SetLineCapStyle(LineCapStyle.Round);
        page.Content.SetLineJoinStyle(LineJoinStyle.Bevel);                

        // draw colored pattern
        DrawColoredTilingPattern(page, document);

        // draw uncolored pattern
        DrawUncoloredTilingPattern(page, document);

        document.Save(outputStream);
    }
}
 

Corresponding drawing functions for each pattern type are defined in the subsections below.

Colored

This pattern contains all color information needed to draw itself and doesn’t require external parameters to be set for drawing.

See the code below:

private static void DrawColoredTilingPattern(Page page, FixedDocument document)
{
    // Create and register colored tiling pattern object
    string colorPatternId = "ColoredTilingPattern";

    TilingPattern coloredPattern = new TilingPattern(colorPatternId, new Boundary(0, 0, 30, 20), 30, 20);

    // path defining pattern content
    Path patternPath = new Path();
    patternPath.AppendRectangle(-15, -5, 25, 7);
    patternPath.AppendRectangle(15, -5, 25, 7);
    patternPath.AppendRectangle(-15, 15, 25, 7);
    patternPath.AppendRectangle(15, 15, 25, 7);
    patternPath.AppendRectangle(0, 5, 25, 7);

    // set gray color as fill color for the pattern  content
    coloredPattern.Content.SetDeviceNonStrokingColor(0.7);
    coloredPattern.Content.FillAndStrokePath(patternPath);

    // register pattern
    document.ResourceManager.RegisterResource(coloredPattern);

    // Set colored Pattern as fill color for the rect (!)
    page.Content.SetNonStrokingColorSpace(PredefinedColorSpaces.Pattern);
    page.Content.SetNonStrokingColor(colorPatternId);

    // Use RGB color to stroke the rect
    page.Content.SetStrokingColorSpace(PredefinedColorSpaces.RGB);
    page.Content.SetStrokingColor(1, 0.5, 0);

    // Draw rectangle
    Path path = new Path();
    path.AppendRectangle(100, 730, 200, 100);
    page.Content.FillAndStrokePath(path);
}
 

The resulting image showing the rectangle filled using the colored tiling pattern is below.

Colored tiling pattern

Uncolored

Don't be misleaded by the name, these patterns do have colors, but the uncolored tiling patterns differ from the colored in way of specifying its stroking and non-stroking colors. It requires the colorspace to be set that will define the actual colors used inside the pattern. Using Fixed layout API it can be achieved by using one of the predefined pattern colorspaces, e.g. RGBPattern.

The code below draws the uncolored pattern and fills the rect using it:

private static void DrawUncoloredTilingPattern(Page page, FixedDocument document)
{
    // Create and register uncolored tiling pattern object
    string uncoloredPatternId = "UnColoredTilingPattern";

    TilingPattern uncoloredPattern = new TilingPattern(uncoloredPatternId, new Boundary(0, 0, 30, 20), 30, 20, false);

    // path defining pattern content
    Path patternPath = new Path();
    patternPath.AppendRectangle(-15, -5, 25, 7);
    patternPath.AppendRectangle(15, -5, 25, 7);
    patternPath.AppendRectangle(-15, 15, 25, 7);
    patternPath.AppendRectangle(15, 15, 25, 7);
    patternPath.AppendRectangle(0, 5, 25, 7);
            
    uncoloredPattern.Content.FillAndStrokePath(patternPath);

    // register pattern
    document.ResourceManager.RegisterResource(uncoloredPattern);

    // Set uncolored Pattern as fill color space for the rect and RGB colorspace for its internal colors (!)
    page.Content.SetNonStrokingColorSpace(PredefinedColorSpaces.RGBPattern);
    // set pattern as fill color using its id and also set its internal fill color 
    page.Content.SetNonStrokingColor(uncoloredPatternId, 0.1, 0.7, 0.2);
    // set stroking color as device RGB
    page.Content.SetDeviceStrokingColor(1,0.5,0);
            
    // Draw rectangle
    Path path = new Path();
    path.AppendRectangle(350, 730, 200, 100);
    page.Content.FillAndStrokePath(path);
}
 

You see that after setting the RGBPattern colorspace as a non-stroking colorspace, we also set our pattern as the current non-stroking color along with specifying the internal fill color for it.

The resulting image that shows the rectangle filled with the uncolored tiling pattern is below:

Uncolored tiling pattern

Uncolored patterns are a good way to reuse various repeating drawings and make them use different stroking and non-stroking colors assigned on demand.

Shading patterns

Shading patterns provide a smooth transition between colors across an area to be painted, independent of the resolution of any particular output media and without specifying the number of steps in the color transition. Patterns of this type can be used to create complex fills and have several subtypes described in section 8.7.4.5 “Shading Types” of the specification. Using the API provided by Apitron PDF Kit one is able to create advanced color gradient fills based on standard linear and exponential interpolation functions as well as pure PostScript function-based color transition effects.

In PDF, the object used to create a complex fill is called Shading, and you may read about all low level details involved in the section 8.7.4 Shading Patterns of the PDF specification. Every Shading object requires a function object that defines the color transformation needed to create the final color at the each point where the shading is defined. Functions are described in section 7.10 Functions of the PDF specification. Using various function types it becomes possible to implement linear, bilinear and exponential interpolation as well as other color effects. One can use different functions to calculate the final value for each color component, or use the same function to calculate all of them. Currently available function types are: Sampled, Exponential, StitchingFunction and PostScript. Shading types available are: axial, radial and function-based.

When the area to be painted has a relatively simple form and matches that of the gradient fill itself(think of a fill as a separate graphical object having desired appearance and overlapping the area to be filled) or you have a simple clipping path for it, the ClippedContent::PaintShading() function may be used instead of the usual painting approach. It accepts a Shading object as an operand and applies the corresponding gradient fill directly to the current user space applying the additional clipping path given as a parameter if needed.

Another way to use shadings is to define a ShadingPattern. Similar to the TilingPattern object, it can be used as a color for filling and stroking operations if you set the current stroking or non-stroking colorspace to PredefinedColorpaces::Pattern. This way you’ll be able to draw whatever you want using the specified shading pattern as a color provider for the stroked or filled path(or both). Both methods have their own pros and cons and it’s up to you to choose the one that works best in your situation. Sections below describe various functions types and shadings types in further details and sample code.