Exemplo n.º 1
0
        ////////////////////////////////////////////////////////////////////
        // Draw rectangle with rounded corners and filled with brick pattern
        ////////////////////////////////////////////////////////////////////

        private void DrawBrickPattern()
        {
            // Define brick tilling pattern resource
            // Arguments: PdfDocument class, Scale factor (0.25), Stroking color (lines between bricks), Nonstroking color (brick)
            // Return value: tilling pattern resource
            PdfTilingPattern BrickPattern = PdfTilingPattern.SetBrickPattern(Document, 0.25, Color.LightYellow, Color.SandyBrown);

            // save graphics state
            Contents.SaveGraphicsState();

            // set outline width 0.04"
            Contents.SetLineWidth(0.04);

            // set outline color to purple
            Contents.SetColorStroking(Color.Purple);

            // set fill pattern to brick
            Contents.SetPatternNonStroking(BrickPattern);

            // draw rounded rectangle filled with brick pattern
            Contents.DrawRoundedRectangle(1.1, 5.0, 1.4, 1.5, 0.2, PaintOp.CloseFillStroke);

            // restore graphics sate
            Contents.RestoreGraphicsState();
            return;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Builds a PdfTilingPattern pattern from a visual brush.
        /// </summary>
        public static PdfTilingPattern BuildFromVisualBrush(DocumentRenderingContext context, VisualBrush brush, XMatrix transform)
        {
            TilingPatternBuilder builder    = new TilingPatternBuilder(context);
            PdfTilingPattern     pdfPattern = builder.BuildPattern(brush, transform);

            return(pdfPattern);
        }
Exemplo n.º 3
0
        PdfTilingPattern BuildPattern(ImageBrush brush, XMatrix transform)
        {
            // Bounding box lays always at (0,0)
            XRect   bbox   = new XRect(0, 0, brush.Viewport.Width, brush.Viewport.Height);
            XMatrix matrix = transform;

            matrix.Prepend(new XMatrix(1, 0, 0, 1, brush.Viewport.X, brush.Viewport.Y));
            if (brush.Transform != null)
            {
                matrix.Prepend(new XMatrix(brush.Transform.Matrix.m11, brush.Transform.Matrix.m12, brush.Transform.Matrix.m21,
                                           brush.Transform.Matrix.m22, brush.Transform.Matrix.offsetX, brush.Transform.Matrix.offsetY));
            }

            // HACK by [email protected]
            // Avoid extra thin lines at the right and at the bottom of original image
            double xStep = brush.Viewport.Width + 1;
            double yStep = brush.Viewport.Height + 1;

            PdfTilingPattern pattern = Context.PdfDocument.Internals.CreateIndirectObject <PdfTilingPattern>();

            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PatternType, 1); // Tiling
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PaintType, 1);   // Color
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.TilingType, 3);  // Constant spacing and faster tiling
            pattern.Elements.SetMatrix(PdfTilingPattern.Keys.Matrix, matrix);
            pattern.Elements.SetRectangle(PdfTilingPattern.Keys.BBox, new PdfRectangle(bbox));
            pattern.Elements.SetReal(PdfTilingPattern.Keys.XStep, xStep);
            pattern.Elements.SetReal(PdfTilingPattern.Keys.YStep, yStep);

            // Set extended graphic state like Acrobat do
            PdfExtGState pdfExtGState = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();

            pdfExtGState.SetDefault1();

            PdfFormXObject pdfForm = BuildForm(brush);

            PdfContentWriter writer = new PdfContentWriter(Context, pattern);

            writer.BeginContentRaw();

            // Acrobat 8 clips to bounding box, so do we
            //writer.WriteClip(bbox);

            XMatrix transformation = new XMatrix();
            double  dx             = brush.Viewport.Width / brush.Viewbox.Width * 96 / pdfForm.DpiX;
            double  dy             = brush.Viewport.Height / brush.Viewbox.Height * 96 / pdfForm.DpiY;

            transformation = new XMatrix(dx, 0, 0, dy, 0, 0);
            writer.WriteMatrix(transformation);
            writer.WriteGraphicsState(pdfExtGState);

            string name = writer.Resources.AddForm(pdfForm);

            writer.WriteLiteral(name + " Do\n");

            writer.EndContent();

            return(pattern);
        }
Exemplo n.º 4
0
        private static void fill(PdfTilingPattern pattern)
        {
            PdfCanvas canvas = pattern.Canvas;
            PdfColor  red    = new PdfRgbColor(255, 0, 0);

            canvas.Brush.Color = red;
            canvas.Pen.Color   = red;
            canvas.AppendCircle(new PointF(2, 2), 2);
            canvas.FillAndStrokePath(PdfFillMode.Winding);
        }
Exemplo n.º 5
0
        private static void drawUncoloredPattern(PdfDocument pdf)
        {
            PdfTilingPattern pattern = pdf.AddUncoloredPattern(5, 5, new PdfRgbColorSpace());

            fill(pattern);

            PdfCanvas canvas = pdf.GetPage(0).Canvas;

            canvas.Brush.Pattern = pattern;
            canvas.Brush.Color   = new PdfRgbColor(0, 255, 0);
            canvas.DrawString(new PointF(50, 150), "Uncolored Pattern colored green");
        }
Exemplo n.º 6
0
        private static void drawColoredPattern(PdfDocument pdf)
        {
            PdfTilingPattern pattern = pdf.AddColoredPattern(5, 5);

            fill(pattern);

            PdfCanvas canvas = pdf.GetPage(0).Canvas;

            canvas.Brush.Pattern = pattern;
            canvas.DrawString(new PointF(50, 50), 0, "Pattern-filled text");
            canvas.DrawCircle(new PointF(0, 0), 20, PdfDrawMode.FillAndStroke);
        }
        ////////////////////////////////////////////////////////////////////
        // Define Tiling Pattern Resource
        ////////////////////////////////////////////////////////////////////

        private void DefineTilingPatternResource
        (
            PdfDocument Document
        )
        {
            // create empty tiling pattern
            WaterMark = new PdfTilingPattern(Document);

            // the pattern will be PdfFileWriter laied out in brick pattern
            String Mark = "PdfFileWriter";

            // text width and height for Arial bold size 18 points
            Double FontSize   = 18.0;
            Double TextWidth  = ArialBold.TextWidth(FontSize, Mark);
            Double TextHeight = ArialBold.LineSpacing(FontSize);

            // text base line
            Double BaseLine = ArialBold.DescentPlusLeading(FontSize);

            // the overall pattern box (we add text height value as left and right text margin)
            Double BoxWidth  = TextWidth + 2 * TextHeight;
            Double BoxHeight = 4 * TextHeight;

            WaterMark.SetTileBox(BoxWidth, BoxHeight);

            // save graphics state
            WaterMark.SaveGraphicsState();

            // fill the pattern box with background light blue color
            WaterMark.SetColorNonStroking(Color.FromArgb(230, 244, 255));
            WaterMark.DrawRectangle(0, 0, BoxWidth, BoxHeight, PaintOp.Fill);

            // set fill color for water mark text to white
            WaterMark.SetColorNonStroking(Color.White);

            // draw PdfFileWriter at the bottom center of the box
            WaterMark.DrawText(ArialBold, FontSize, BoxWidth / 2, BaseLine, TextJustify.Center, Mark);

            // adjust base line upward by half height
            BaseLine += BoxHeight / 2;

            // draw the right half of PdfFileWriter shifted left by half width
            WaterMark.DrawText(ArialBold, FontSize, 0.0, BaseLine, TextJustify.Center, Mark);

            // draw the left half of PdfFileWriter shifted right by half width
            WaterMark.DrawText(ArialBold, FontSize, BoxWidth, BaseLine, TextJustify.Center, Mark);

            // restore graphics state
            WaterMark.RestoreGraphicsState();
            return;
        }
Exemplo n.º 8
0
        PdfTilingPattern BuildPattern(ImageBrush brush, XMatrix transform)
        {
            // Bounding box lays always at (0,0)
            XRect bbox = new XRect(0, 0, brush.Viewport.Width, brush.Viewport.Height);

#if true
            XMatrix matrix = transform;
            matrix.Prepend(new XMatrix(1, 0, 0, 1, brush.Viewport.X, brush.Viewport.Y));
            if (brush.Transform != null)
            {
                matrix.Prepend(new XMatrix(brush.Transform.Matrix.m11, brush.Transform.Matrix.m12, brush.Transform.Matrix.m21,
                                           brush.Transform.Matrix.m22, brush.Transform.Matrix.offsetX, brush.Transform.Matrix.offsetY));
            }
#else
            double  c      = 1;
            XMatrix matrix = new XMatrix(1 * c, 0, 0, 1 * c, brush.Viewport.X * c, brush.Viewport.Y * c); // HACK: 480
            XMatrix t      = transform;
            //t.Invert();
            t.Prepend(matrix);
            //t.TranslateAppend(brush.Viewport.X , brush.Viewport.Y);
            //matrix.Append(t);
            matrix = t;
#endif
            double xStep = brush.Viewport.Width;
            double yStep = brush.Viewport.Height;

            // PdfTilingPattern
            //<<
            //  /BBox [0 0 240 120]
            //  /Length 74
            //  /Matrix [0.75 0 0 -0.75 0 480]
            //  /PaintType 1
            //  /PatternType 1
            //  /Resources
            //  <<
            //    /ExtGState
            //    <<
            //      /GS0 10 0 R
            //    >>
            //    /XObject
            //    <<
            //      /Fm0 17 0 R
            //    >>
            //  >>
            //  /TilingType 3
            //  /Type /Pattern
            //  /XStep 480
            //  /YStep 640
            //>>
            //stream
            //  q
            //  0 0 240 120 re
            //  W n
            //  q
            //    2.3999939 0 0 1.1999969 0 0 cm
            //    /GS0 gs
            //    /Fm0 Do
            //  Q
            //Q
            //endstream
            PdfTilingPattern pattern = Context.PdfDocument.Internals.CreateIndirectObject <PdfTilingPattern>();
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PatternType, 1); // Tiling
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PaintType, 1);   // Color
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.TilingType, 3);  // Constant spacing and faster tiling
            pattern.Elements.SetMatrix(PdfTilingPattern.Keys.Matrix, matrix);
            pattern.Elements.SetRectangle(PdfTilingPattern.Keys.BBox, new PdfRectangle(bbox));
            pattern.Elements.SetReal(PdfTilingPattern.Keys.XStep, xStep);
            pattern.Elements.SetReal(PdfTilingPattern.Keys.YStep, yStep);

            // Set extended graphic state like Acrobat do
            PdfExtGState pdfExtGState = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();
            pdfExtGState.SetDefault1();

            PdfFormXObject pdfForm = BuildForm(brush);
            //XRect viewBoxForm = new XRect(0, 0, 640, 480);

            PdfContentWriter writer = new PdfContentWriter(Context, pattern);
            writer.BeginContentRaw();

            // Acrobat 8 clips to bounding box, so do we
            //writer.WriteClip(bbox);

            XMatrix transformation = new XMatrix();
            double  dx             = brush.Viewport.Width / brush.Viewbox.Width * 96 / pdfForm.DpiX;
            double  dy             = brush.Viewport.Height / brush.Viewbox.Height * 96 / pdfForm.DpiY;
            transformation = new XMatrix(dx, 0, 0, dy, 0, 0);
            writer.WriteMatrix(transformation);
            writer.WriteGraphicsState(pdfExtGState);

            string name = writer.Resources.AddForm(pdfForm);
            writer.WriteLiteral(name + " Do\n");

            writer.EndContent();

            return(pattern);
        }
        PdfTilingPattern BuildPattern(VisualBrush brush, XMatrix transform)
        {
            // Bounding box lays always at (0,0)
            XRect bbox = new XRect(0, 0, brush.Viewport.Width, brush.Viewport.Height);

            XMatrix matrix = transform;

            matrix.Prepend(new XMatrix(1, 0, 0, 1, brush.Viewport.X, brush.Viewport.Y));
            if (brush.Transform != null)
            {
                matrix.Prepend(new XMatrix(brush.Transform.Value.M11, brush.Transform.Value.M12,
                                           brush.Transform.Value.M21, brush.Transform.Value.M22,
                                           brush.Transform.Value.OffsetX, brush.Transform.Value.OffsetY));
            }

            // Set X Step beyond the viewport if tilemode is set to none since
            // there is no other easy way to turn off tiling - NPJ
            double xStep = brush.Viewport.Width * (brush.TileMode == TileMode.None ? 2 : 1);
            double yStep = brush.Viewport.Height * (brush.TileMode == TileMode.None ? 2 : 1);

            // PdfTilingPattern
            //<<
            //  /BBox [0 0 240 120]
            //  /Length 74
            //  /Matrix [0.75 0 0 -0.75 0 480]
            //  /PaintType 1
            //  /PatternType 1
            //  /Resources
            //  <<
            //    /ExtGState
            //    <<
            //      /GS0 10 0 R
            //    >>
            //    /XObject
            //    <<
            //      /Fm0 17 0 R
            //    >>
            //  >>
            //  /TilingType 3
            //  /Type /Pattern
            //  /XStep 480
            //  /YStep 640
            //>>
            //stream
            //  q
            //  0 0 240 120 re
            //  W n
            //  q
            //    2.3999939 0 0 1.1999969 0 0 cm
            //    /GS0 gs
            //    /Fm0 Do
            //  Q
            //Q
            //endstream
            var pattern = new PdfTilingPattern(Context.PdfDocument);

            Context.PdfDocument.Internals.AddObject(pattern);
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PatternType, 1); // Tiling
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PaintType, 1);   // Color
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.TilingType, 3);  // Constant spacing and faster tiling
            pattern.Elements.SetMatrix(PdfTilingPattern.Keys.Matrix, matrix);
            pattern.Elements.SetRectangle(PdfTilingPattern.Keys.BBox, new PdfRectangle(bbox));
            pattern.Elements.SetReal(PdfTilingPattern.Keys.XStep, xStep);
            pattern.Elements.SetReal(PdfTilingPattern.Keys.YStep, yStep);

            // Set extended graphic state like Acrobat do
            var pdfExtGState = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();

            pdfExtGState.SetDefault1();

            var pdfForm = BuildForm(brush);

            var writer = new PdfContentWriter(Context, pattern);

            writer.BeginContentRaw();

            // Acrobat 8 clips to bounding box, so do we
            //writer.WriteClip(bbox);

            XMatrix transformation = new XMatrix();
            double  dx             = brush.Viewport.Width / brush.Viewbox.Width * 96 / pdfForm.DpiX;
            double  dy             = brush.Viewport.Height / brush.Viewbox.Height * 96 / pdfForm.DpiY;

            transformation = new XMatrix(dx, 0, 0, dy, 0, 0);
            writer.WriteMatrix(transformation);
            writer.WriteGraphicsState(pdfExtGState);

            string name = writer.Resources.AddForm(pdfForm);

            writer.WriteLiteral(name + " Do\n");

            writer.EndContent();

            return(pattern);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Writes a Path to the content stream.
        /// </summary>
        private void WritePath(Path path)
        {
            if (WriteSingleLineStrokeWithSpecialCaps(path))
            {
                return;
            }

            WriteSaveState("begin Path", path.Name);

            // Transform also affects clipping and opacity mask
            if (path.RenderTransform != null && this.renderMode == RenderMode.Default)
            {
                MultiplyTransform(path.RenderTransform);
                WriteRenderTransform(path.RenderTransform);
            }

            if (path.Clip != null && this.renderMode == RenderMode.Default)
            {
                WriteClip(path.Clip);
            }

            if (path.Opacity < 1)
            {
                MultiplyOpacity(path.Opacity);
            }

            if (path.OpacityMask != null)
            {
                WriteOpacityMask(path.OpacityMask);
            }

            if (path.Fill == null)
            {
                if (path.Stroke != null)
                {
                    WriteStrokeGeometry(path);
                }
                else
                {
                    Debug.Assert(false, "??? Path with neither Stroke nor Fill encountered.");
                }
            }
            else
            {
                SolidColorBrush     sBrush;
                LinearGradientBrush lgBrush;
                RadialGradientBrush rgBrush;
                ImageBrush          iBrush;
                VisualBrush         vBrush;
                if ((sBrush = path.Fill as SolidColorBrush) != null)
                {
                    Color  color   = sBrush.Color;
                    double opacity = Opacity * color.ScA;
                    if (opacity < 1)
                    {
                        RealizeFillOpacity(opacity);
                    }

                    WriteRgb(color, " rg\n");

                    if (path.Stroke != null)
                    {
                        RealizeStroke(path);
                    }

                    WriteGeometry(path.Data);
                    WritePathFillStroke(path);
                }
                else if ((lgBrush = path.Fill as LinearGradientBrush) != null)
                {
                    // TODO: For better visual compatibility use a Shading Pattern if Opacity is not 1 and
                    // the Stroke Style is not solid. Acrobat 8 ignores this case.

                    PdfExtGState xgState = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();
                    xgState.SetDefault1();

                    double opacity = Opacity * lgBrush.Opacity;;
                    if (opacity < 1)
                    {
                        xgState.StrokeAlpha    = opacity;
                        xgState.NonStrokeAlpha = opacity;
                    }
                    RealizeExtGState(xgState);

                    // 1st draw fill
                    if (lgBrush.GradientStops.HasTransparency)
                    {
                        // Create a FormXObject with a soft mask
                        PdfFormXObject form   = LinearShadingBuilder.BuildFormFromLinearGradientBrush(Context, lgBrush, path.Data);
                        string         foName = Resources.AddForm(form);
                        WriteLiteral(foName + " Do\n");
                    }
                    else
                    {
                        // Create just a shading
                        PdfShading shading = LinearShadingBuilder.BuildShadingFromLinearGradientBrush(Context, lgBrush);
                        string     shName  = Resources.AddShading(shading);
                        WriteLiteral("q\n");
                        WriteClip(path.Data);
                        WriteLiteral("BX " + shName + " sh EX Q\n");
                    }

                    // 2nd draw stroke
                    if (path.Stroke != null)
                    {
                        WriteStrokeGeometry(path);
                    }
                }
                else if ((rgBrush = path.Fill as RadialGradientBrush) != null)
                {
                    PdfExtGState xgState = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();
                    xgState.SetDefault1();

                    double avGradientOpacity = rgBrush.GradientStops.GetAverageAlpha(); // HACK
                    double opacity           = Opacity * rgBrush.Opacity * avGradientOpacity;
                    if (opacity < 1)
                    {
                        xgState.StrokeAlpha    = opacity;
                        xgState.NonStrokeAlpha = opacity;
                    }
                    //RealizeExtGState(xgState);

                    XRect boundingBox = path.Data.GetBoundingBox();
                    // Always creates a pattern, because the background must be filled
                    PdfShadingPattern pattern = RadialShadingBuilder.BuildFromRadialGradientBrush(Context, rgBrush, boundingBox, Transform);
                    string            paName  = Resources.AddPattern(pattern);

                    // stream
                    // /CS0 cs /P0 scn
                    // /GS0 gs
                    // 0 480 180 -90 re
                    // f*
                    // endstream
                    // endobj
                    WriteLiteral("/Pattern cs " + paName + " scn\n");
                    // move to here: RealizeExtGState(xgState);
                    RealizeExtGState(xgState);
                    WriteGeometry(path.Data);
                    if (path.Data.FillRule == FillRule.NonZero) // NonZero means Winding
                    {
                        WriteLiteral("f\n");
                    }
                    else
                    {
                        WriteLiteral("f*\n");
                    }

                    // 2nd draw stroke
                    if (path.Stroke != null)
                    {
                        WriteStrokeGeometry(path);
                    }
                }
                else if ((iBrush = path.Fill as ImageBrush) != null)
                {
                    PdfExtGState xgState = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();
                    xgState.SetDefault1();

                    double opacity = Opacity * iBrush.Opacity;
                    if (opacity <= 1)
                    {
                        xgState.StrokeAlpha    = opacity;
                        xgState.NonStrokeAlpha = opacity;
                    }
                    RealizeExtGState(xgState);

                    // 1st draw fill
                    PdfTilingPattern pattern = TilingPatternBuilder.BuildFromImageBrush(Context, iBrush, Transform);
                    string           name    = Resources.AddPattern(pattern);

                    WriteLiteral("/Pattern cs " + name + " scn\n");
                    WriteGeometry(path.Data);
                    WritePathFillStroke(path);

                    // 2nd draw stroke
                    if (path.Stroke != null)
                    {
                        WriteStrokeGeometry(path);
                    }
                }
                else if ((vBrush = path.Fill as VisualBrush) != null)
                {
                    PdfExtGState xgState = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();
                    xgState.SetDefault1();

                    double opacity = Opacity * vBrush.Opacity;
                    if (opacity < 1)
                    {
                        xgState.StrokeAlpha    = opacity;
                        xgState.NonStrokeAlpha = opacity;
                    }
                    RealizeExtGState(xgState);

                    // 1st draw fill
                    PdfTilingPattern pattern = TilingPatternBuilder.BuildFromVisualBrush(Context, vBrush, Transform);
                    string           name    = Resources.AddPattern(pattern);

                    WriteLiteral("/Pattern cs " + name + " scn\n");
                    WriteGeometry(path.Data);
                    WritePathFillStroke(path);

                    // 2nd draw stroke
                    if (path.Stroke != null)
                    {
                        WriteStrokeGeometry(path);
                    }
                }
                else
                {
                    Debug.Assert(false, "Unknown brush type encountered.");
                }
            }
            WriteRestoreState("end Path", path.Name);
        }
Exemplo n.º 11
0
        PdfTilingPattern BuildPattern(ImageBrush brush, XMatrix transform)
        {
            // Bounding box repects viewbox
            //XRect bbox = new XRect(brush.Viewbox.X, brush.Viewbox.Y, brush.Viewbox.Width, brush.Viewbox.Height);
            // double scalex = brush.Viewport.Width / brush.Viewbox.Width * 96 / pdfForm.DpiX;
            //BitmapImage src = new BitmapImage();
            //BitmapSource cropbrush = BitmapSource.Create()
            //CroppedBitmap cropbrush = new CroppedBitmap((BitmapSource)brush.ImageSource, new System.Windows.Int32Rect((int)brush.Viewbox.X, (int)brush.Viewbox.Y, (int)brush.Viewbox.Width, (int)brush.Viewbox.Height));
            //using (var fileStream = new System.IO.FileStream("c:\\fullimage.png", System.IO.FileMode.Create))
            //{
            //    BitmapEncoder encoder = new PngBitmapEncoder();
            //    encoder.Frames.Add(BitmapFrame.Create((BitmapSource)brush.ImageSource));
            //    encoder.Save(fileStream);
            //}
            double scaledpix = ((BitmapSource)brush.ImageSource).DpiX;
            double scaledpiy = ((BitmapSource)brush.ImageSource).DpiY;

            if (brush.Viewbox.X > 0 || brush.Viewbox.Y > 0)
            {
                CroppedBitmap cropbrush = new CroppedBitmap((BitmapSource)brush.ImageSource, new System.Windows.Int32Rect((int)Math.Round((brush.Viewbox.X / 96) * scaledpix), (int)Math.Round((brush.Viewbox.Y / 96) * scaledpiy), (int)Math.Round((brush.Viewbox.Width / 96) * scaledpiy), (int)Math.Round((brush.Viewbox.Height / 96) * scaledpiy)));
                //cropbrush.DpiX = scaledpix;
                //cropbrush.DpiY = scaledpiy;
                brush.ImageSource = cropbrush;
                //brush.Viewport = new System.Windows.Rect(0, 0, brush.Viewport.Width, brush.Viewport.Height);
                //brush.Viewbox = new System.Windows.Rect(0, 0, ((Math.Round((brush.Viewbox.Width / 96) * scaledpiy)) / scaledpiy * 96) , brush.Viewbox.Height);
                brush.Viewbox = new System.Windows.Rect(0, 0, brush.Viewbox.Width, brush.Viewbox.Height);
            }

            //brush = new ImageBrush(cropbrush);

            //BitmapSource
            //BitmapSource. cropbrushbitmap = new BitmapSource(cropbrush);


            //using (var fileStream = new System.IO.FileStream("c:\\cropimage.png", System.IO.FileMode.Create))
            //{
            //   BitmapEncoder encoder = new PngBitmapEncoder();
            //   encoder.Frames.Add(BitmapFrame.Create(cropbrush));
            //   encoder.Save(fileStream);
            //}

            //XRect bbox = new XRect(brush.Viewport.X - brush.Viewbox.X, brush.Viewport.Y - brush.Viewbox.Y, brush.Viewbox.Width, brush.Viewbox.Height);
            //XRect bbox = new XRect((brush.Viewbox.X / 96) * scaledpix, (brush.Viewbox.Y / 96) * scaledpiy, (brush.Viewbox.Width / 96) * scaledpix, (brush.Viewbox.Height / 96) * scaledpiy);
            //XRect bbox = new XRect(0, 0, (brush.Viewport.Width / 96) * scaledpix, (brush.Viewport.Height / 96) * scaledpiy);
            XRect bbox = new XRect(0, 0, brush.Viewport.Width, brush.Viewport.Height);

#if true
            XMatrix matrix = transform;
//this only needs to be a translate and to offset the viewbox viewport difference
            matrix.TranslatePrepend(brush.Viewport.X, brush.Viewport.Y);
            //matrix.TranslatePrepend((brush.Viewport.X - brush.Viewbox.X)+2, (brush.Viewport.Y - brush.Viewbox.Y)+2);

            if (brush.Transform != null)
            {
                matrix.Prepend(new XMatrix(brush.Transform.Value.M11, brush.Transform.Value.M12, brush.Transform.Value.M21,
                                           brush.Transform.Value.M22, brush.Transform.Value.OffsetX,
                                           brush.Transform.Value.OffsetY));
            }
#else
            double  c      = 1;
            XMatrix matrix = new XMatrix(1 * c, 0, 0, 1 * c, brush.Viewport.X * c, brush.Viewport.Y * c); // HACK: 480
            XMatrix t      = transform;
            //t.Invert();
            t.Prepend(matrix);
            //t.TranslateAppend(brush.Viewport.X , brush.Viewport.Y);
            //matrix.Append(t);
            matrix = t;
#endif
            double xStep = brush.Viewport.Width + 1;  // (brush.Viewbox.Width / 96) * scaledpix; //* (brush.TileMode == TileMode.None ? 2 : 1);
            double yStep = brush.Viewport.Height + 1; // (brush.Viewbox.Height / 96) * scaledpiy; //* (brush.TileMode == TileMode.None ? 2 : 1);


            // PdfTilingPattern
            //<<
            //  /BBox [0 0 240 120]
            //  /Length 74
            //  /Matrix [0.75 0 0 -0.75 0 480]
            //  /PaintType 1
            //  /PatternType 1
            //  /Resources
            //  <<
            //    /ExtGState
            //    <<
            //      /GS0 10 0 R
            //    >>
            //    /XObject
            //    <<
            //      /Fm0 17 0 R
            //    >>
            //  >>
            //  /TilingType 3
            //  /Type /Pattern
            //  /XStep 480
            //  /YStep 640
            //>>
            //stream
            //  q
            //  0 0 240 120 re
            //  W n
            //  q
            //    2.3999939 0 0 1.1999969 0 0 cm
            //    /GS0 gs
            //    /Fm0 Do
            //  Q
            //Q
            //endstream
            PdfTilingPattern pattern = Context.PdfDocument.Internals.CreateIndirectObject <PdfTilingPattern>();
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PatternType, 1); // Tiling
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PaintType, 1);   // Color
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.TilingType, 3);  // Constant spacing and faster tiling
            pattern.Elements.SetMatrix(PdfTilingPattern.Keys.Matrix, matrix);
            pattern.Elements.SetRectangle(PdfTilingPattern.Keys.BBox, new PdfRectangle(bbox));
            pattern.Elements.SetReal(PdfTilingPattern.Keys.XStep, xStep);
            pattern.Elements.SetReal(PdfTilingPattern.Keys.YStep, yStep);

            // Set extended graphic state like Acrobat do
            PdfExtGState pdfExtGState = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();
            pdfExtGState.SetDefault1();

            PdfFormXObject pdfForm = BuildForm(brush);
            //XRect viewBoxForm = new XRect(0, 0, 640, 480);

            PdfContentWriter writer = new PdfContentWriter(Context, pattern);
            writer.BeginContentRaw();

            // Acrobat 8 clips to bounding box, so do we
            //writer.WriteClip(bbox);

            XMatrix transformation = new XMatrix();
            //double dx = brush.Viewport.Width / brush.Viewbox.Width * 96 / pdfForm.DpiX;
            //double dy = brush.Viewport.Height / brush.Viewbox.Height * 96 / pdfForm.DpiY;

            double dx = brush.Viewport.Width / brush.Viewbox.Width * 96 / pdfForm.DpiX;
            double dy = brush.Viewport.Height / brush.Viewbox.Height * 96 / pdfForm.DpiY;
            transformation = new XMatrix(dx, 0, 0, dy, 0, 0);
            writer.WriteMatrix(transformation);
            writer.WriteGraphicsState(pdfExtGState);

            string name = writer.Resources.AddForm(pdfForm);
            writer.WriteLiteral(name + " Do\n");

            writer.EndContent();

            return(pattern);
        }