//////////////////////////////////////////////////////////////////// // 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; }
/// <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); }
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); }
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); }
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"); }
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; }
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); }
/// <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); }
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); }