public override ContentObject ToInlineObject(PrimitiveComposer composer)
        {
            ContentObject barcodeObject = composer.BeginLocalState();

            {
                fonts::Font font     = fonts::PdfType1Font.Load(composer.Scanner.Contents.Document, fonts::PdfType1Font.FamilyEnum.Helvetica, false, false);
                double      fontSize = (DigitGlyphWidth / font.GetWidth(code.Substring(0, 1), 1));

                // 1. Bars.
                {
                    double elementX      = DigitWidth;
                    int[]  elementWidths = GetElementWidths();

                    double guardBarIndentY = DigitHeight / 2;
                    bool   isBar           = true;
                    for (int elementIndex = 0; elementIndex < elementWidths.Length; elementIndex++)
                    {
                        double elementWidth = elementWidths[elementIndex];
                        // Dark element?

                        /*
                         * NOTE: EAN symbol elements alternate bars to spaces.
                         */
                        if (isBar)
                        {
                            composer.DrawRectangle(
                                SKRect.Create(
                                    (float)elementX,
                                    0,
                                    (float)elementWidth,
                                    (float)(BarHeight + (
                                                // Guard bar?
                                                Array.BinarySearch <int>(GuardBarIndexes, elementIndex) >= 0
                                    ? guardBarIndentY // Guard bar.
                                    : 0               // Symbol character.
                                                ))
                                    )
                                );
                        }

                        elementX += elementWidth;
                        isBar     = !isBar;
                    }
                    composer.Fill();
                }

                // 2. Digits.
                {
                    composer.SetFont(font, fontSize);
                    double digitY = BarHeight + (DigitHeight - (font.GetAscent(fontSize))) / 2;
                    // Showing the digits...
                    for (int digitIndex = 0; digitIndex < 13; digitIndex++)
                    {
                        string digit = code.Substring(digitIndex, 1);
                        double pX    = DigitGlyphXs[digitIndex]              // Digit position.
                                       - font.GetWidth(digit, fontSize) / 2; // Centering.
                                                                             // Show the current digit!
                        composer.ShowText(
                            digit,
                            new SKPoint((float)pX, (float)digitY)
                            );
                    }
                }
                composer.End();
            }
            return(barcodeObject);
        }
Exemple #2
0
        private FormXObject BuildTemplate(Document document, DateTime creationDate)
        {
            // Create a template (form)!
            FormXObject template     = new FormXObject(document, document.PageSize.Value);
            SKSize      templateSize = template.Size;

            // Get form content stream!
            PrimitiveComposer composer = new PrimitiveComposer(template);

            // Showing the header image inside the common content stream...
            // Instantiate a jpeg image object!
            entities::Image image = entities::Image.Get(GetResourcePath("images" + Path.DirectorySeparatorChar + "mountains.jpg")); // Abstract image (entity).

            // Show the image inside the common content stream!
            composer.ShowXObject(
                image.ToXObject(document),
                new SKPoint(0, 0),
                new SKSize(templateSize.Width - 50, 125)
                );

            // Showing the 'PdfClown' label inside the common content stream...
            composer.BeginLocalState();
            composer.SetFillColor(new colorSpaces::DeviceRGBColor(115f / 255, 164f / 255, 232f / 255));
            // Set the font to use!
            composer.SetFont(fonts::PdfType1Font.Load(document, fonts::PdfType1Font.FamilyEnum.Times, true, false), 120);
            // Show the text!
            composer.ShowText(
                "PdfClown",
                new SKPoint(
                    0,
                    templateSize.Height - (float)composer.State.Font.GetAscent(composer.State.FontSize)
                    )
                );

            // Drawing the side rectangle...
            composer.DrawRectangle(
                SKRect.Create(
                    (float)templateSize.Width - 50,
                    0,
                    50,
                    (float)templateSize.Height
                    )
                );
            composer.Fill();
            composer.End();

            // Showing the side text inside the common content stream...
            composer.BeginLocalState();
            {
                composer.SetFont(fonts::PdfType1Font.Load(document, fonts::PdfType1Font.FamilyEnum.Helvetica, false, false), 8);
                composer.SetFillColor(colorSpaces::DeviceRGBColor.White);
                composer.BeginLocalState();
                {
                    composer.Rotate(
                        90,
                        new SKPoint(
                            templateSize.Width - 50,
                            templateSize.Height - 25
                            )
                        );
                    BlockComposer blockComposer = new BlockComposer(composer);
                    blockComposer.Begin(
                        SKRect.Create(0, 0, 300, 50),
                        XAlignmentEnum.Left,
                        YAlignmentEnum.Middle
                        );
                    {
                        blockComposer.ShowText("Generated by PDF Clown on " + creationDate);
                        blockComposer.ShowBreak();
                        blockComposer.ShowText("For more info, visit http://www.pdfclown.org");
                    }
                    blockComposer.End();
                }
                composer.End();
            }
            composer.End();

            composer.Flush();

            return(template);
        }
        private void BuildSimpleTextPage(
            Document document
            )
        {
            // 1. Add the page to the document!
            Page page = new Page(document); // Instantiates the page inside the document context.

            document.Pages.Add(page);       // Puts the page in the pages collection.

            SizeF pageSize = page.Size;

            // 2. Create a content composer for the page!
            PrimitiveComposer composer = new PrimitiveComposer(page);

            // 3. Inserting contents...
            // Set the font to use!
            composer.SetFont(
                new fonts::StandardType1Font(
                    document,
                    fonts::StandardType1Font.FamilyEnum.Courier,
                    true,
                    false
                    ),
                32
                );

            XAlignmentEnum[] xAlignments = (XAlignmentEnum[])Enum.GetValues(typeof(XAlignmentEnum));
            YAlignmentEnum[] yAlignments = (YAlignmentEnum[])Enum.GetValues(typeof(YAlignmentEnum));
            int step = (int)(pageSize.Height) / ((xAlignments.Length - 1) * yAlignments.Length + 1);

            BlockComposer blockComposer = new BlockComposer(composer);
            RectangleF    frame         = new RectangleF(
                30,
                0,
                pageSize.Width - 60,
                step / 2
                );

            blockComposer.Begin(frame, XAlignmentEnum.Center, YAlignmentEnum.Middle);
            blockComposer.ShowText("Simple alignment");
            blockComposer.End();

            frame = new RectangleF(
                30,
                pageSize.Height - step / 2,
                pageSize.Width - 60,
                step / 2 - 10
                );
            blockComposer.Begin(frame, XAlignmentEnum.Left, YAlignmentEnum.Bottom);
            composer.SetFont(composer.State.Font, 10);
            blockComposer.ShowText(
                "NOTE: showText(...) methods return the actual bounding box of the text shown.\n"
                + "NOTE: The rotation parameter can be freely defined as a floating point value."
                );
            blockComposer.End();

            composer.SetFont(composer.State.Font, 12);
            int x = 30;
            int y = step;
            int alignmentIndex = 0;

            foreach (XAlignmentEnum xAlignment
                     in (XAlignmentEnum[])Enum.GetValues(typeof(XAlignmentEnum)))
            {
                /*
                 * NOTE: As text shown through PrimitiveComposer has no bounding box constraining its extension,
                 * applying the justified alignment has no effect (it degrades to center alignment);
                 * in order to get such an effect, use BlockComposer instead.
                 */
                if (xAlignment.Equals(XAlignmentEnum.Justify))
                {
                    continue;
                }

                foreach (YAlignmentEnum yAlignment
                         in (YAlignmentEnum[])Enum.GetValues(typeof(YAlignmentEnum)))
                {
                    if (alignmentIndex % 2 == 0)
                    {
                        composer.BeginLocalState();
                        composer.SetFillColor(BackColor);
                        composer.DrawRectangle(
                            new RectangleF(
                                0,
                                y - step / 2,
                                pageSize.Width,
                                step
                                )
                            );
                        composer.Fill();
                        composer.End();
                    }

                    composer.ShowText(
                        xAlignment + " " + yAlignment + ":",
                        new PointF(x, y),
                        XAlignmentEnum.Left,
                        YAlignmentEnum.Middle,
                        0
                        );

                    y += step;
                    alignmentIndex++;
                }
            }

            float rotationStep = 0;
            float rotation     = 0;

            for (
                int columnIndex = 0;
                columnIndex < 2;
                columnIndex++
                )
            {
                switch (columnIndex)
                {
                case 0:
                    x            = 200;
                    rotationStep = 0;
                    break;

                case 1:
                    x            = (int)pageSize.Width / 2 + 100;
                    rotationStep = 360 / ((xAlignments.Length - 1) * yAlignments.Length - 1);
                    break;
                }
                y        = step;
                rotation = 0;
                foreach (XAlignmentEnum xAlignment
                         in (XAlignmentEnum[])Enum.GetValues(typeof(XAlignmentEnum)))
                {
                    /*
                     * NOTE: As text shown through PrimitiveComposer has no bounding box constraining its extension,
                     * applying the justified alignment has no effect (it degrades to center alignment);
                     * in order to get such an effect, use BlockComposer instead.
                     */
                    if (xAlignment.Equals(XAlignmentEnum.Justify))
                    {
                        continue;
                    }

                    foreach (YAlignmentEnum yAlignment
                             in (YAlignmentEnum[])Enum.GetValues(typeof(YAlignmentEnum)))
                    {
                        float startArcAngle = 0;
                        switch (xAlignment)
                        {
                        case XAlignmentEnum.Left:
                            // OK -- NOOP.
                            break;

                        case XAlignmentEnum.Right:
                        case XAlignmentEnum.Center:
                            startArcAngle = 180;
                            break;
                        }

                        composer.DrawArc(
                            new RectangleF(
                                x - 10,
                                y - 10,
                                20,
                                20
                                ),
                            startArcAngle,
                            startArcAngle + rotation
                            );

                        DrawText(
                            composer,
                            "PDF Clown",
                            new PointF(x, y),
                            xAlignment,
                            yAlignment,
                            rotation
                            );
                        y        += step;
                        rotation += rotationStep;
                    }
                }
            }

            // 4. Flush the contents into the page!
            composer.Flush();
        }
Exemple #4
0
        /*
         * TODO: refresh should happen just before serialization, on document event (e.g. OnWrite())
         */
        private void RefreshAppearance(
            )
        {
            FormXObject normalAppearance;
            RectangleF  box = org.pdfclown.objects.Rectangle.Wrap(BaseDataObject[PdfName.Rect]).ToRectangleF();
            {
                AppearanceStates normalAppearances = Appearance.Normal;
                normalAppearance = normalAppearances[null];
                if (normalAppearance != null)
                {
                    normalAppearance.Box = box;
                    normalAppearance.BaseDataObject.Body.SetLength(0);
                }
                else
                {
                    normalAppearances[null] = normalAppearance = new FormXObject(Document, box);
                }
            }

            PrimitiveComposer composer = new PrimitiveComposer(normalAppearance);

            {
                float          yOffset    = box.Height - Page.Box.Height;
                MarkupTypeEnum markupType = MarkupType;
                switch (markupType)
                {
                case MarkupTypeEnum.Highlight:
                {
                    ExtGState defaultExtGState;
                    {
                        ExtGStateResources extGStates = normalAppearance.Resources.ExtGStates;
                        defaultExtGState = extGStates[HighlightExtGStateName];
                        if (defaultExtGState == null)
                        {
                            if (extGStates.Count > 0)
                            {
                                extGStates.Clear();
                            }

                            extGStates[HighlightExtGStateName] = defaultExtGState = new ExtGState(Document);
                            defaultExtGState.AlphaShape        = false;
                            defaultExtGState.BlendMode         = new List <BlendModeEnum>(new BlendModeEnum[] { BlendModeEnum.Multiply });
                        }
                    }

                    composer.ApplyState(defaultExtGState);
                    composer.SetFillColor(Color);
                    {
                        foreach (Quad markupBox in MarkupBoxes)
                        {
                            PointF[] points          = markupBox.Points;
                            float    markupBoxHeight = points[3].Y - points[0].Y;
                            float    markupBoxMargin = GetMarkupBoxMargin(markupBoxHeight);
                            composer.DrawCurve(
                                new PointF(points[3].X, points[3].Y + yOffset),
                                new PointF(points[0].X, points[0].Y + yOffset),
                                new PointF(points[3].X - markupBoxMargin, points[3].Y - markupBoxMargin + yOffset),
                                new PointF(points[0].X - markupBoxMargin, points[0].Y + markupBoxMargin + yOffset)
                                );
                            composer.DrawLine(
                                new PointF(points[1].X, points[1].Y + yOffset)
                                );
                            composer.DrawCurve(
                                new PointF(points[2].X, points[2].Y + yOffset),
                                new PointF(points[1].X + markupBoxMargin, points[1].Y + markupBoxMargin + yOffset),
                                new PointF(points[2].X + markupBoxMargin, points[2].Y - markupBoxMargin + yOffset)
                                );
                            composer.Fill();
                        }
                    }
                }
                break;

                case MarkupTypeEnum.Squiggly:
                {
                    composer.SetStrokeColor(Color);
                    composer.SetLineCap(LineCapEnum.Round);
                    composer.SetLineJoin(LineJoinEnum.Round);
                    {
                        foreach (Quad markupBox in MarkupBoxes)
                        {
                            PointF[] points          = markupBox.Points;
                            float    markupBoxHeight = points[3].Y - points[0].Y;
                            float    lineWidth       = markupBoxHeight * .05f;
                            float    step            = markupBoxHeight * .125f;
                            float    boxXOffset      = points[3].X;
                            float    boxYOffset      = points[3].Y + yOffset - lineWidth;
                            bool     phase           = false;
                            composer.SetLineWidth(lineWidth);
                            for (float x = 0, xEnd = points[2].X - boxXOffset; x < xEnd || !phase; x += step)
                            {
                                PointF point = new PointF(x + boxXOffset, (phase ? -step : 0) + boxYOffset);
                                if (x == 0)
                                {
                                    composer.StartPath(point);
                                }
                                else
                                {
                                    composer.DrawLine(point);
                                }
                                phase = !phase;
                            }
                        }
                        composer.Stroke();
                    }
                }
                break;

                case MarkupTypeEnum.StrikeOut:
                case MarkupTypeEnum.Underline:
                {
                    composer.SetStrokeColor(Color);
                    {
                        float lineYRatio = 0;
                        switch (markupType)
                        {
                        case MarkupTypeEnum.StrikeOut:
                            lineYRatio = .5f;
                            break;

                        case MarkupTypeEnum.Underline:
                            lineYRatio = .9f;
                            break;

                        default:
                            throw new NotImplementedException();
                        }
                        foreach (Quad markupBox in MarkupBoxes)
                        {
                            PointF[] points          = markupBox.Points;
                            float    markupBoxHeight = points[3].Y - points[0].Y;
                            float    boxYOffset      = markupBoxHeight * lineYRatio + yOffset;
                            composer.SetLineWidth(markupBoxHeight * .065);
                            composer.DrawLine(
                                new PointF(points[3].X, points[0].Y + boxYOffset),
                                new PointF(points[2].X, points[1].Y + boxYOffset)
                                );
                        }
                        composer.Stroke();
                    }
                }
                break;

                default:
                    throw new NotImplementedException();
                }
            }
            composer.Flush();
        }
Exemple #5
0
        /*
          TODO: refresh should happen just before serialization, on document event (e.g. OnWrite())
        */
        private void RefreshAppearance(
      )
        {
            FormXObject normalAppearance;
              RectangleF box = org.pdfclown.objects.Rectangle.Wrap(BaseDataObject[PdfName.Rect]).ToRectangleF();
              {
            AppearanceStates normalAppearances = Appearance.Normal;
            normalAppearance = normalAppearances[null];
            if(normalAppearance != null)
            {
              normalAppearance.Box = box;
              normalAppearance.BaseDataObject.Body.SetLength(0);
            }
            else
            {normalAppearances[null] = normalAppearance = new FormXObject(Document, box);}
              }

              PrimitiveComposer composer = new PrimitiveComposer(normalAppearance);
              {
            float yOffset = box.Height - Page.Box.Height;
            MarkupTypeEnum markupType = MarkupType;
            switch(markupType)
            {
              case MarkupTypeEnum.Highlight:
              {
            ExtGState defaultExtGState;
            {
              ExtGStateResources extGStates = normalAppearance.Resources.ExtGStates;
              defaultExtGState = extGStates[HighlightExtGStateName];
              if(defaultExtGState == null)
              {
                if(extGStates.Count > 0)
                {extGStates.Clear();}

                extGStates[HighlightExtGStateName] = defaultExtGState = new ExtGState(Document);
                defaultExtGState.AlphaShape = false;
                defaultExtGState.BlendMode = new List<BlendModeEnum>(new BlendModeEnum[]{BlendModeEnum.Multiply});
              }
            }

            composer.ApplyState(defaultExtGState);
            composer.SetFillColor(Color);
            {
              foreach(Quad markupBox in MarkupBoxes)
              {
                PointF[] points = markupBox.Points;
                float markupBoxHeight = points[3].Y - points[0].Y;
                float markupBoxMargin = GetMarkupBoxMargin(markupBoxHeight);
                composer.DrawCurve(
                  new PointF(points[3].X, points[3].Y + yOffset),
                  new PointF(points[0].X, points[0].Y + yOffset),
                  new PointF(points[3].X - markupBoxMargin, points[3].Y - markupBoxMargin + yOffset),
                  new PointF(points[0].X - markupBoxMargin, points[0].Y + markupBoxMargin + yOffset)
                  );
                composer.DrawLine(
                  new PointF(points[1].X, points[1].Y + yOffset)
                  );
                composer.DrawCurve(
                  new PointF(points[2].X, points[2].Y + yOffset),
                  new PointF(points[1].X + markupBoxMargin, points[1].Y + markupBoxMargin + yOffset),
                  new PointF(points[2].X + markupBoxMargin, points[2].Y - markupBoxMargin + yOffset)
                  );
                composer.Fill();
              }
            }
              }
            break;
              case MarkupTypeEnum.Squiggly:
              {
            composer.SetStrokeColor(Color);
            composer.SetLineCap(LineCapEnum.Round);
            composer.SetLineJoin(LineJoinEnum.Round);
            {
              foreach(Quad markupBox in MarkupBoxes)
              {
                PointF[] points = markupBox.Points;
                float markupBoxHeight = points[3].Y - points[0].Y;
                float lineWidth = markupBoxHeight * .02f;
                float step = markupBoxHeight * .125f;
                float boxXOffset = points[3].X;
                float boxYOffset = points[3].Y + yOffset - lineWidth;
                bool phase = false;
                composer.SetLineWidth(lineWidth);
                for(float x = 0, xEnd = points[2].X - boxXOffset; x < xEnd || !phase; x += step)
                {
                  PointF point = new PointF(x + boxXOffset, (phase ? -step : 0) + boxYOffset);
                  if(x == 0)
                  {composer.StartPath(point);}
                  else
                  {composer.DrawLine(point);}
                  phase = !phase;
                }
              }
              composer.Stroke();
            }
              }
            break;
              case MarkupTypeEnum.StrikeOut:
              case MarkupTypeEnum.Underline:
              {
            composer.SetStrokeColor(Color);
            {
              float lineYRatio = 0;
              switch(markupType)
              {
                case MarkupTypeEnum.StrikeOut:
                  lineYRatio = .575f;
                  break;
                case MarkupTypeEnum.Underline:
                  lineYRatio = .85f;
                  break;
                default:
                  throw new NotImplementedException();
              }
              foreach(Quad markupBox in MarkupBoxes)
              {
                PointF[] points = markupBox.Points;
                float markupBoxHeight = points[3].Y - points[0].Y;
                float boxYOffset = markupBoxHeight * lineYRatio + yOffset;
                composer.SetLineWidth(markupBoxHeight * .065);
                composer.DrawLine(
                  new PointF(points[3].X, points[0].Y + boxYOffset),
                  new PointF(points[2].X, points[1].Y + boxYOffset)
                  );
              }
              composer.Stroke();
            }
              }
            break;
              default:
            throw new NotImplementedException();
            }
              }
              composer.Flush();
        }
Exemple #6
0
        public override ContentObject ToInlineObject(
      PrimitiveComposer composer
      )
        {
            ContentObject barcodeObject = composer.BeginLocalState();
              {
            fonts::Font font = new fonts::StandardType1Font(
              composer.Scanner.Contents.Document,
              fonts::StandardType1Font.FamilyEnum.Helvetica,
              false,
              false
              );
            double fontSize = (DigitGlyphWidth / font.GetWidth(code.Substring(0,1), 1));

            // 1. Bars.
            {
              double elementX = DigitWidth;
              int[] elementWidths = GetElementWidths();

              double guardBarIndentY = DigitHeight / 2;
              bool isBar = true;
              for(
            int elementIndex = 0;
            elementIndex < elementWidths.Length;
            elementIndex++
            )
              {
            double elementWidth = elementWidths[elementIndex];
            // Dark element?
            /*
              NOTE: EAN symbol elements alternate bars to spaces.
            */
            if(isBar)
            {
              composer.DrawRectangle(
                new RectangleF(
                  (float)elementX,
                  0,
                  (float)elementWidth,
                  (float)(BarHeight + (
                    // Guard bar?
                    Array.BinarySearch<int>(GuardBarIndexes, elementIndex) >= 0
                      ? guardBarIndentY // Guard bar.
                      : 0 // Symbol character.
                    ))
                  )
                );
            }

            elementX += elementWidth;
            isBar = !isBar;
              }
              composer.Fill();
            }

            // 2. Digits.
            {
              composer.SetFont(font,fontSize);
              double digitY = BarHeight + (DigitHeight - (font.GetAscent(fontSize))) / 2;
              // Showing the digits...
              for(
            int digitIndex = 0;
            digitIndex < 13;
            digitIndex++
            )
              {
            string digit = code.Substring(digitIndex, 1);
            double pX = DigitGlyphXs[digitIndex] // Digit position.
              - font.GetWidth(digit,fontSize) / 2; // Centering.
            // Show the current digit!
            composer.ShowText(
              digit,
              new PointF((float)pX,(float)digitY)
              );
              }
            }
            composer.End();
              }
              return barcodeObject;
        }
Exemple #7
0
        private void BuildSimpleTextPage(
            Document document
            )
        {
            // 1. Add the page to the document!
              Page page = new Page(document); // Instantiates the page inside the document context.
              document.Pages.Add(page); // Puts the page in the pages collection.

              SizeF pageSize = page.Size;

              // 2. Create a content composer for the page!
              PrimitiveComposer composer = new PrimitiveComposer(page);
              // 3. Inserting contents...
              // Set the font to use!
              composer.SetFont(
            new fonts::StandardType1Font(
              document,
              fonts::StandardType1Font.FamilyEnum.Courier,
              true,
              false
              ),
            32
            );

              XAlignmentEnum[] xAlignments = (XAlignmentEnum[])Enum.GetValues(typeof(XAlignmentEnum));
              YAlignmentEnum[] yAlignments = (YAlignmentEnum[])Enum.GetValues(typeof(YAlignmentEnum));
              int step = (int)(pageSize.Height) / ((xAlignments.Length-1) * yAlignments.Length+1);

              BlockComposer blockComposer = new BlockComposer(composer);
              RectangleF frame = new RectangleF(
            30,
            0,
            pageSize.Width-60,
            step/2
            );
              blockComposer.Begin(frame,XAlignmentEnum.Center,YAlignmentEnum.Middle);
              blockComposer.ShowText("Simple alignment");
              blockComposer.End();

              frame = new RectangleF(
            30,
            pageSize.Height-step/2,
            pageSize.Width-60,
            step/2 -10
            );
              blockComposer.Begin(frame,XAlignmentEnum.Left,YAlignmentEnum.Bottom);
              composer.SetFont(composer.State.Font,10);
              blockComposer.ShowText(
            "NOTE: showText(...) methods return the actual bounding box of the text shown.\n"
              + "NOTE: The rotation parameter can be freely defined as a floating point value."
            );
              blockComposer.End();

              composer.SetFont(composer.State.Font,12);
              int x = 30;
              int y = step;
              int alignmentIndex = 0;
              foreach(XAlignmentEnum xAlignment
            in (XAlignmentEnum[])Enum.GetValues(typeof(XAlignmentEnum)))
              {
            /*
              NOTE: As text shown through PrimitiveComposer has no bounding box constraining its extension,
              applying the justified alignment has no effect (it degrades to center alignment);
              in order to get such an effect, use BlockComposer instead.
            */
            if(xAlignment.Equals(XAlignmentEnum.Justify))
              continue;

            foreach(YAlignmentEnum yAlignment
              in (YAlignmentEnum[])Enum.GetValues(typeof(YAlignmentEnum)))
            {
              if(alignmentIndex % 2 == 0)
              {
            composer.BeginLocalState();
            composer.SetFillColor(BackColor);
            composer.DrawRectangle(
              new RectangleF(
                0,
                y-step/2,
                pageSize.Width,
                step
                )
              );
            composer.Fill();
            composer.End();
              }

              composer.ShowText(
            xAlignment + " " + yAlignment + ":",
            new PointF(x,y),
            XAlignmentEnum.Left,
            YAlignmentEnum.Middle,
            0
            );

              y+=step;
              alignmentIndex++;
            }
              }

              float rotationStep = 0;
              float rotation = 0;
              for(
            int columnIndex = 0;
            columnIndex < 2;
            columnIndex++
            )
              {
            switch(columnIndex)
            {
              case 0:
            x = 200;
            rotationStep = 0;
            break;
              case 1:
            x = (int)pageSize.Width / 2 + 100;
            rotationStep = 360 / ((xAlignments.Length-1) * yAlignments.Length-1);
            break;
            }
            y = step;
            rotation = 0;
            foreach(XAlignmentEnum xAlignment
              in (XAlignmentEnum[])Enum.GetValues(typeof(XAlignmentEnum)))
            {
              /*
            NOTE: As text shown through PrimitiveComposer has no bounding box constraining its extension,
            applying the justified alignment has no effect (it degrades to center alignment);
            in order to get such an effect, use BlockComposer instead.
              */
              if(xAlignment.Equals(XAlignmentEnum.Justify))
            continue;

              foreach(YAlignmentEnum yAlignment
            in (YAlignmentEnum[])Enum.GetValues(typeof(YAlignmentEnum)))
              {
            float startArcAngle = 0;
            switch(xAlignment)
            {
              case XAlignmentEnum.Left:
                // OK -- NOOP.
                break;
              case XAlignmentEnum.Right:
              case XAlignmentEnum.Center:
                startArcAngle = 180;
                break;
            }

            composer.DrawArc(
              new RectangleF(
                x-10,
                y-10,
                20,
                20
                ),
              startArcAngle,
              startArcAngle+rotation
              );

            DrawText(
              composer,
              "PDF Clown",
              new PointF(x,y),
              xAlignment,
              yAlignment,
              rotation
              );
            y+=step;
            rotation+=rotationStep;
              }
            }
              }

              // 4. Flush the contents into the page!
              composer.Flush();
        }
        private FormXObject BuildTemplate(
            Document document,
            DateTime creationDate
            )
        {
            // Create a template (form)!
              FormXObject template = new FormXObject(document, document.PageSize.Value);
              SizeF templateSize = template.Size;

              // Get form content stream!
              PrimitiveComposer composer = new PrimitiveComposer(template);

              // Showing the header image inside the common content stream...
              // Instantiate a jpeg image object!
              entities::Image image = entities::Image.Get(GetResourcePath("images" + Path.DirectorySeparatorChar + "mountains.jpg")); // Abstract image (entity).
              // Show the image inside the common content stream!
              composer.ShowXObject(
            image.ToXObject(document),
            new PointF(0,0),
            new SizeF(templateSize.Width - 50, 125)
            );

              // Showing the 'PDFClown' label inside the common content stream...
              composer.BeginLocalState();
              composer.SetFillColor(new colorSpaces::DeviceRGBColor(115f / 255, 164f / 255, 232f / 255));
              // Set the font to use!
              composer.SetFont(
            new fonts::StandardType1Font(
              document,
              fonts::StandardType1Font.FamilyEnum.Times,
              true,
              false
              ),
            120
            );
              // Show the text!
              composer.ShowText(
            "PDFClown",
            new PointF(
              0,
              templateSize.Height - (float)composer.State.Font.GetAscent(composer.State.FontSize)
              )
            );

              // Drawing the side rectangle...
              composer.DrawRectangle(
            new RectangleF(
              (float)templateSize.Width - 50,
              0,
              50,
              (float)templateSize.Height
              )
            );
              composer.Fill();
              composer.End();

              // Showing the side text inside the common content stream...
              composer.BeginLocalState();
              {
            composer.SetFont(
              new fonts::StandardType1Font(
            document,
            fonts::StandardType1Font.FamilyEnum.Helvetica,
            false,
            false
            ),
              8
              );
            composer.SetFillColor(colorSpaces::DeviceRGBColor.White);
            composer.BeginLocalState();
            {
              composer.Rotate(
            90,
            new PointF(
              templateSize.Width - 50,
              templateSize.Height - 25
              )
            );
              BlockComposer blockComposer = new BlockComposer(composer);
              blockComposer.Begin(
            new RectangleF(0,0,300,50),
            XAlignmentEnum.Left,
            YAlignmentEnum.Middle
            );
              {
            blockComposer.ShowText("Generated by PDF Clown on " + creationDate);
            blockComposer.ShowBreak();
            blockComposer.ShowText("For more info, visit http://www.pdfclown.org");
              }
              blockComposer.End();
            }
            composer.End();
              }
              composer.End();

              composer.Flush();

              return template;
        }