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); }
void RealizeVisualBrush(VisualBrush brush, ref XForm xform) { //Debug.Assert(xform != null); xform = new XForm(this.writer.Owner, new XRect(brush.Viewbox.X * 3 / 4, brush.Viewbox.Y * 3 / 4, brush.Viewbox.Width * 3 / 4, brush.Viewbox.Height * 3 / 4)); Visual visual = brush.Visual; PdfContentWriter formWriter = new PdfContentWriter(this.writer.Context, xform, RenderMode.Default); //formWriter.Size = brush.Viewport.Size; formWriter.BeginContent(false); formWriter.WriteElement(visual); formWriter.EndContent(); }
void RealizeVisualBrush(VisualBrush brush, ref XForm xform) { //Debug.Assert(xform != null); xform = new XForm(writer.Owner, new XRect(brush.Viewbox.X * 3 / 4, brush.Viewbox.Y * 3 / 4, brush.Viewbox.Width * 3 / 4, brush.Viewbox.Height * 3 / 4)); Visual visual = brush.Visual; PdfContentWriter formWriter = new PdfContentWriter(writer.Context, xform, RenderMode.Default); //formWriter.Size = brush.Viewport.Size; formWriter.BeginContent(false); formWriter.WriteElement(visual); formWriter.EndContent(); }
/// <summary> /// Creates an XForm from an image brush. /// </summary> public static XForm FromImageBrush(DocumentRenderingContext context, ImageBrush brush) { XPImage xpImage = ImageBuilder.FromImageBrush(context, brush); XImage ximage = xpImage.XImage; double width = ximage.PixelWidth; double height = ximage.PixelHeight; // view box in point // XRect box = new XRect(brush.Viewbox.X * 0.75, brush.Viewbox.Y * 0.75, brush.Viewbox.Width * 0.75, brush.Viewbox.Height * 0.75); XRect box = new XRect(0, 0, width, height); XForm xform = new XForm(context.PdfDocument, box); PdfContentWriter formWriter = new PdfContentWriter(context, xform, RenderMode.Default); Debug.Assert(ximage != null); PdfFormXObject pdfForm = xform.PdfForm; pdfForm.Elements.SetMatrix(PdfFormXObject.Keys.Matrix, new XMatrix()); //formWriter.Size = brush.Viewport.Size; formWriter.BeginContentRaw(); string imageID = formWriter.Resources.AddImage(new PdfImage(context.PdfDocument, ximage)); XMatrix matrix = new XMatrix(); double scaleX = brush.Viewport.Width / brush.Viewbox.Width * 4 / 3 * ximage.PointWidth; double scaleY = brush.Viewport.Height / brush.Viewbox.Height * 4 / 3 * ximage.PointHeight; matrix.TranslatePrepend(-brush.Viewbox.X, -brush.Viewbox.Y); matrix.ScalePrepend(scaleX, scaleY); matrix.TranslatePrepend(brush.Viewport.X / scaleX, brush.Viewport.Y / scaleY); matrix = new XMatrix(width, 0, 0, -height, 0, height); formWriter.WriteLiteral("q\n"); // TODO:WriteClip(path.Data); //formWriter.WriteLiteral("{0:0.###} 0 0 -{1:0.###} {2:0.###} {3:0.###} cm 100 Tz {4} Do Q\n", // matrix.M11, matrix.M22, matrix.OffsetX, matrix.OffsetY + brush.Viewport.Height, imageID); formWriter.WriteMatrix(matrix); formWriter.WriteLiteral(imageID + " Do Q\n"); formWriter.EndContent(); return(xform); }
/// <summary> /// Creates an XForm from an image brush. /// </summary> public static XForm FromImageBrush(DocumentRenderingContext context, ImageBrush brush) { XPImage xpImage = ImageBuilder.FromImageBrush(context, brush); XImage ximage = xpImage.XImage; double width = ximage.PixelWidth; double height = ximage.PixelHeight; // view box in point // XRect box = new XRect(brush.Viewbox.X * 0.75, brush.Viewbox.Y * 0.75, brush.Viewbox.Width * 0.75, brush.Viewbox.Height * 0.75); XRect box = new XRect(0, 0, width, height); XForm xform = new XForm(context.PdfDocument, box); PdfContentWriter formWriter = new PdfContentWriter(context, xform, RenderMode.Default); Debug.Assert(ximage != null); PdfFormXObject pdfForm = xform.PdfForm; pdfForm.Elements.SetMatrix(PdfFormXObject.Keys.Matrix, new XMatrix()); //formWriter.Size = brush.Viewport.Size; formWriter.BeginContentRaw(); string imageID = formWriter.Resources.AddImage(new PdfImage(context.PdfDocument, ximage)); XMatrix matrix = new XMatrix(); double scaleX = brush.Viewport.Width / brush.Viewbox.Width * 4 / 3 * ximage.PointWidth; double scaleY = brush.Viewport.Height / brush.Viewbox.Height * 4 / 3 * ximage.PointHeight; matrix.TranslatePrepend(-brush.Viewbox.X, -brush.Viewbox.Y); matrix.ScalePrepend(scaleX, scaleY); matrix.TranslatePrepend(brush.Viewport.X / scaleX, brush.Viewport.Y / scaleY); matrix = new XMatrix(width, 0, 0, -height, 0, height); formWriter.WriteLiteral("q\n"); // TODO:WriteClip(path.Data); //formWriter.WriteLiteral("{0:0.###} 0 0 -{1:0.###} {2:0.###} {3:0.###} cm 100 Tz {4} Do Q\n", // matrix.M11, matrix.M22, matrix.OffsetX, matrix.OffsetY + brush.Viewport.Height, imageID); formWriter.WriteMatrix(matrix); formWriter.WriteLiteral(imageID + " Do Q\n"); formWriter.EndContent(); return xform; }
/// <summary> /// Creates an XForm from a visual brush. /// </summary> public static XForm FromVisualBrush(DocumentRenderingContext context, VisualBrush brush) { //XPImage xpImage = ImageBuilder.FromImageBrush(context, brush); //XImage ximage = xpImage.XImage; double width = brush.Viewport.Width; double height = brush.Viewport.Height; // view box in point // XRect box = new XRect(brush.Viewbox.X * 0.75, brush.Viewbox.Y * 0.75, brush.Viewbox.Width * 0.75, brush.Viewbox.Height * 0.75); XRect box = new XRect(0, 0, width, height); XForm xform = new XForm(context.PdfDocument, box); PdfContentWriter formWriter = new PdfContentWriter(context, xform, RenderMode.Default); PdfFormXObject pdfForm = xform.PdfForm; pdfForm.Elements.SetMatrix(PdfFormXObject.Keys.Matrix, new XMatrix()); //formWriter.Size = brush.Viewport.Size; formWriter.BeginContent(false); formWriter.WriteElement(brush.Visual); formWriter.EndContent(); return(xform); }
internal void RenderPage(PdfPage page, FixedPage fixedPage) { this.page = page; context = new DocumentRenderingContext(page.Owner); //this.page.Width = fixedPage.Width; //this.page.Height = fixedPage.Height; //this.gsStack = new GraphicsStateStack(this); PdfContent content = null; //switch (options) //{ // case XGraphicsPdfPageOptions.Replace: // page.Contents.Elements.Clear(); // goto case XGraphicsPdfPageOptions.Append; // case XGraphicsPdfPageOptions.Prepend: // content = page.Contents.PrependContent(); // break; // case XGraphicsPdfPageOptions.Append: content = page.Contents.AppendContent(); // break; //} page.RenderContent = content; writer = new PdfContentWriter(context, this.page); //Initialize(); writer.BeginContent(false); writer.WriteElements(fixedPage.Content); writer.EndContent(); }
/// <summary> /// Creates an XForm from a visual brush. /// </summary> public static XForm FromVisualBrush(DocumentRenderingContext context, VisualBrush brush) { //XPImage xpImage = ImageBuilder.FromImageBrush(context, brush); //XImage ximage = xpImage.XImage; double width = brush.Viewport.Width; double height = brush.Viewport.Height; // view box in point // XRect box = new XRect(brush.Viewbox.X * 0.75, brush.Viewbox.Y * 0.75, brush.Viewbox.Width * 0.75, brush.Viewbox.Height * 0.75); XRect box = new XRect(0, 0, width, height); XForm xform = new XForm(context.PdfDocument, box); PdfContentWriter formWriter = new PdfContentWriter(context, xform, RenderMode.Default); PdfFormXObject pdfForm = xform.PdfForm; pdfForm.Elements.SetMatrix(PdfFormXObject.Keys.Matrix, new XMatrix()); //formWriter.Size = brush.Viewport.Size; formWriter.BeginContent(false); formWriter.WriteElement(brush.Visual); formWriter.EndContent(); return xform; }
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> /// Builds the soft mask. /// </summary> PdfSoftMask BuildSoftMask(RadialGradientBrush brush) { Debug.Assert(brush.GradientStops.HasTransparency); XRect viewBox = new XRect(0, 0, 360, 480); // HACK //XForm xform = new XForm(Context.PdfDocument, viewBox); PdfFormXObject form = Context.PdfDocument.Internals.CreateIndirectObject<PdfFormXObject>(); #if DEBUG if (DevHelper.RenderComments) form.Elements.SetString("/@comment", "This is the Form XObject of the soft mask"); #endif form.Elements.SetRectangle(PdfFormXObject.Keys.BBox, new PdfRectangle(viewBox)); // Transparency group of mask form //<< // /CS /DeviceGray // /I false // /K false // /S /Transparency // /Type /Group //>> PdfTransparencyGroupAttributes tgAttributes = Context.PdfDocument.Internals.CreateIndirectObject<PdfTransparencyGroupAttributes>(); tgAttributes.Elements.SetName(PdfTransparencyGroupAttributes.Keys.CS, "/DeviceGray"); tgAttributes.Elements.SetBoolean(PdfTransparencyGroupAttributes.Keys.I, false); tgAttributes.Elements.SetBoolean(PdfTransparencyGroupAttributes.Keys.K, false); // ExtGState of mask form //<< // /AIS false // /BM /Normal // /ca 1 // /CA 1 // /op false // /OP false // /OPM 1 // /SA true // /SMask /None // /Type /ExtGState //>> PdfExtGState pdfStateMaskFrom = Context.PdfDocument.Internals.CreateIndirectObject<PdfExtGState>(); pdfStateMaskFrom.SetDefault1(); // Shading of mask form PdfShading shadingFrom = BuildShadingForSoftMask(brush); ////// Set reference to transparency group attributes ////pdfForm.Elements.SetObject(PdfFormXObject.Keys.Group, tgAttributes); ////pdfForm.Elements[PdfFormXObject.Keys.Matrix] = new PdfLiteral("[1.001 0 0 1.001 0.001 0.001]"); // Soft mask //<< // /G 21 0 R % form // /S /Luminosity // /Type /Mask //>> PdfSoftMask softmask = Context.PdfDocument.Internals.CreateIndirectObject<PdfSoftMask>(); // new PdfSoftMask(this.writer.Owner); //extGState.Elements.SetReference(PdfExtGState.Keys.SMask, softmask); //this.writer.Owner.Internals.AddObject(softmask); #if DEBUG if (DevHelper.RenderComments) softmask.Elements.SetString("/@comment", "This is the soft mask"); #endif softmask.Elements.SetName(PdfSoftMask.Keys.S, "/Luminosity"); softmask.Elements.SetReference(PdfSoftMask.Keys.G, form); // Create content of mask form //<< // /BBox [200.118 369.142 582.795 -141.094] // /Group 16 0 R // /Length 121 // /Matrix [1 0 0 1 0 0] // /Resources // << // /ExtGState // << // /GS0 20 0 R // >> // /Shading // << // /Sh0 19 0 R // >> // >> // /Subtype /Form //>> //stream // q // 200.118 369.142 382.677 -510.236 re // W n // q // 0 g // 1 i // GS0 gs // 0.75 0 0 -0.75 200.1181183 369.1417236 cm // BX /Sh0 sh EX Q // Q //endstream form.Elements.SetReference(PdfFormXObject.Keys.Group, tgAttributes); PdfContentWriter writer = new PdfContentWriter(Context, form); writer.BeginContentRaw(); // Acrobat 8 clips to bounding box, so we should do // why 0 480 360 -480 re ?? //writer.WriteClip(bbox); //writer.WriteGraphicsState(extGState); writer.WriteLiteral("1 i 0 g\n"); writer.WriteLiteral(writer.Resources.AddExtGState(pdfStateMaskFrom) + " gs\n"); XMatrix transform = new XMatrix(); //(brush.Viewport.Width / viewBoxForm.width, 0, 0, brush.Viewport.Height / viewBoxForm.height, 0, 0); writer.WriteMatrix(transform); writer.WriteLiteral("BX " + writer.Resources.AddShading(shadingFrom) + " sh EX\n"); writer.EndContent(); return softmask; }
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); }
/// <summary> /// Builds a PdfFormXObject from the specified brush. /// // If a gradient contains transparency, a soft mask is created an added to the specified graphic state. /// </summary> PdfFormXObject BuildForm(RadialGradientBrush brush, PathGeometry geometry) { PdfFormXObject pdfForm = Context.PdfDocument.Internals.CreateIndirectObject<PdfFormXObject>(); // HACK pdfForm.Elements.SetRectangle(PdfFormXObject.Keys.BBox, new PdfRectangle(0, 640, 480, 0)); // Transparency group of the form //<< // /I true // /K false // /S /Transparency // /Type /Group //>> PdfTransparencyGroupAttributes tgPrimaryForm = Context.PdfDocument.Internals.CreateIndirectObject<PdfTransparencyGroupAttributes>(); // not set by Acrobat: tgAttributes.Elements.SetName(PdfTransparencyGroupAttributes.Keys.CS, "/DeviceRGB"); tgPrimaryForm.Elements.SetBoolean(PdfTransparencyGroupAttributes.Keys.I, true); tgPrimaryForm.Elements.SetBoolean(PdfTransparencyGroupAttributes.Keys.K, false); pdfForm.Elements.SetReference(PdfFormXObject.Keys.Group, tgPrimaryForm); // Shading PdfShading shading = BuildShading(brush, 1, 1); // ExtGState //<< // /AIS false // /BM /Normal // /ca 1 // /CA 1 // /op false // /OP false // /OPM 1 // /SA true // /SMask 22 0 R // /Type /ExtGState //>> PdfExtGState pdfExtGState = Context.PdfDocument.Internals.CreateIndirectObject<PdfExtGState>(); pdfExtGState.SetDefault1(); // Soft mask PdfSoftMask softmask = BuildSoftMask(brush); pdfExtGState.Elements.SetReference(PdfExtGState.Keys.SMask, softmask); // PdfFormXObject //<< // /BBox [200.118 369.142 582.795 -141.094] // /Group 11 0 R // /Length 117 // /Matrix [1 0 0 1 0 0] // /Resources // << // /ColorSpace // << // /CS0 8 0 R // >> // /ExtGState // << // /GS0 23 0 R // >> // /Shading // << // /Sh0 14 0 R // >> // >> // /Subtype /Form //>> //stream //q //203.868 365.392 157.5 -97.5 re //W* n //q //0 g //1 i ///GS0 gs //0.75 0 0 -0.75 200.1181183 369.1417236 cm //BX /Sh0 sh EX Q //Q //endstream PdfContentWriter writer = new PdfContentWriter(Context, pdfForm); writer.BeginContentRaw(); // Acrobat 8 clips to bounding box, so we should do writer.WriteClip(geometry); //writer.WriteGraphicsState(extGState); //writer.WriteLiteral("0 g\n"); writer.WriteLiteral(writer.Resources.AddExtGState(pdfExtGState) + " gs\n"); XMatrix transform = new XMatrix(); //(brush.Viewport.Width / viewBoxForm.width, 0, 0, brush.Viewport.Height / viewBoxForm.height, 0, 0); writer.WriteMatrix(transform); writer.WriteLiteral("BX " + writer.Resources.AddShading(shading) + " sh EX\n"); writer.EndContent(); return pdfForm; }
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; }
/// <summary> /// Builds a PdfFormXObject from the specified brush. /// </summary> PdfFormXObject BuildForm(ImageBrush brush) { //<< // /BBox [0 100 100 0] // /Length 65 // /Matrix [1 0 0 1 0 0] // /Resources // << // /ColorSpace // << // /CS0 15 0 R // >> // /ExtGState // << // /GS0 10 0 R // >> // /ProcSet [/PDF /ImageC /ImageI] // /XObject // << // /Im0 16 0 R // >> // >> // /Subtype /Form //>> //stream // q // 0 0 100 100 re // W n // q // /GS0 gs // 100 0 0 -100 0 100 cm // /Im0 Do // Q //Q //endstream PdfFormXObject pdfForm = Context.PdfDocument.Internals.CreateIndirectObject<PdfFormXObject>(); XPImage xpImage = ImageBuilder.FromImageBrush(Context, brush); XImage ximage = xpImage.XImage; ximage.Interpolate = false; double width = ximage.PixelWidth; double height = ximage.PixelHeight; pdfForm.DpiX = ximage.HorizontalResolution; pdfForm.DpiY = ximage.VerticalResolution; // view box in point // XRect box = new XRect(brush.Viewbox.X * 0.75, brush.Viewbox.Y * 0.75, brush.Viewbox.Width * 0.75, brush.Viewbox.Height * 0.75); XRect box = new XRect(0, 0, width, height); pdfForm.Elements.SetRectangle(PdfFormXObject.Keys.BBox, new PdfRectangle(0, height, width, 0)); pdfForm.Elements.SetMatrix(PdfFormXObject.Keys.Matrix, new XMatrix()); PdfContentWriter writer = new PdfContentWriter(Context, pdfForm); Debug.Assert(ximage != null); //PdfFormXObject pdfForm = xform.PdfForm; pdfForm.Elements.SetMatrix(PdfFormXObject.Keys.Matrix, new XMatrix()); //formWriter.Size = brush.Viewport.Size; writer.BeginContentRaw(); string imageID = writer.Resources.AddImage(new PdfImage(Context.PdfDocument, ximage)); XMatrix matrix = new XMatrix(); //double scaleX = brush.Viewport.Width / brush.Viewbox.Width * 4 / 3 * ximage.PointWidth; //double scaleY = brush.Viewport.Height / brush.Viewbox.Height * 4 / 3 * ximage.PointHeight; //matrix.TranslatePrepend(-brush.Viewbox.X, -brush.Viewbox.Y); //matrix.ScalePrepend(scaleX, scaleY); //matrix.TranslatePrepend(brush.Viewport.X / scaleX, brush.Viewport.Y / scaleY); //double scaleX = 96 / ximage.HorizontalResolution; //double scaleY = 96 / ximage.VerticalResolution; //width *= scaleX; //height *= scaleY; matrix = new XMatrix(width, 0, 0, -height, 0, height); writer.WriteLiteral("q\n"); // TODO:WriteClip(path.Data); //formWriter.WriteLiteral("{0:0.###} 0 0 -{1:0.###} {2:0.###} {3:0.###} cm 100 Tz {4} Do Q\n", // matrix.M11, matrix.M22, matrix.OffsetX, matrix.OffsetY + brush.Viewport.Height, imageID); writer.WriteMatrix(matrix); writer.WriteLiteral(imageID + " Do Q\n"); #if DEBUG if (DevHelper.BorderPatterns) writer.WriteLiteral("1 1 1 rg 0 0 m {0:0.###} 0 l {0:0.###} {1:0.###} l 0 {1:0.###} l h s\n", width, height); #endif writer.EndContent(); return pdfForm; }
/// <summary> /// Builds a PdfFormXObject from the specified brush. /// </summary> PdfFormXObject BuildForm(ImageBrush brush) { //<< // /BBox [0 100 100 0] // /Length 65 // /Matrix [1 0 0 1 0 0] // /Resources // << // /ColorSpace // << // /CS0 15 0 R // >> // /ExtGState // << // /GS0 10 0 R // >> // /ProcSet [/PDF /ImageC /ImageI] // /XObject // << // /Im0 16 0 R // >> // >> // /Subtype /Form //>> //stream // q // 0 0 100 100 re // W n // q // /GS0 gs // 100 0 0 -100 0 100 cm // /Im0 Do // Q //Q //endstream PdfFormXObject pdfForm = Context.PdfDocument.Internals.CreateIndirectObject <PdfFormXObject>(); XPImage xpImage = ImageBuilder.FromImageBrush(Context, brush); XImage ximage = xpImage.XImage; ximage.Interpolate = false; double width = ximage.PixelWidth; double height = ximage.PixelHeight; pdfForm.DpiX = ximage.HorizontalResolution; pdfForm.DpiY = ximage.VerticalResolution; // view box in point // XRect box = new XRect(brush.Viewbox.X * 0.75, brush.Viewbox.Y * 0.75, brush.Viewbox.Width * 0.75, brush.Viewbox.Height * 0.75); XRect box = new XRect(0, 0, width, height); pdfForm.Elements.SetRectangle(PdfFormXObject.Keys.BBox, new PdfRectangle(0, height, width, 0)); pdfForm.Elements.SetMatrix(PdfFormXObject.Keys.Matrix, new XMatrix()); PdfContentWriter writer = new PdfContentWriter(Context, pdfForm); Debug.Assert(ximage != null); //PdfFormXObject pdfForm = xform.PdfForm; pdfForm.Elements.SetMatrix(PdfFormXObject.Keys.Matrix, new XMatrix()); //formWriter.Size = brush.Viewport.Size; writer.BeginContentRaw(); string imageID = writer.Resources.AddImage(new PdfImage(Context.PdfDocument, ximage)); XMatrix matrix = new XMatrix(); //double scaleX = brush.Viewport.Width / brush.Viewbox.Width * 4 / 3 * ximage.PointWidth; //double scaleY = brush.Viewport.Height / brush.Viewbox.Height * 4 / 3 * ximage.PointHeight; //matrix.TranslatePrepend(-brush.Viewbox.X, -brush.Viewbox.Y); //matrix.ScalePrepend(scaleX, scaleY); //matrix.TranslatePrepend(brush.Viewport.X / scaleX, brush.Viewport.Y / scaleY); //double scaleX = 96 / ximage.HorizontalResolution; //double scaleY = 96 / ximage.VerticalResolution; //width *= scaleX; //height *= scaleY; matrix = new XMatrix(width, 0, 0, -height, 0, height); writer.WriteLiteral("q\n"); // TODO:WriteClip(path.Data); //formWriter.WriteLiteral("{0:0.###} 0 0 -{1:0.###} {2:0.###} {3:0.###} cm 100 Tz {4} Do Q\n", // matrix.M11, matrix.M22, matrix.OffsetX, matrix.OffsetY + brush.Viewport.Height, imageID); writer.WriteMatrix(matrix); writer.WriteLiteral(imageID + " Do Q\n"); #if DEBUG if (DevHelper.BorderPatterns) { writer.WriteLiteral("1 1 1 rg 0 0 m {0:0.###} 0 l {0:0.###} {1:0.###} l 0 {1:0.###} l h s\n", width, height); } #endif writer.EndContent(); return(pdfForm); }
/// <summary> /// Builds a PdfFormXObject from the specified brush. /// </summary> PdfFormXObject BuildForm(VisualBrush brush) { //<< // /BBox [0 100 100 0] // /Length 65 // /Matrix [1 0 0 1 0 0] // /Resources // << // /ColorSpace // << // /CS0 15 0 R // >> // /ExtGState // << // /GS0 10 0 R // >> // /ProcSet [/PDF /ImageC /ImageI] // /XObject // << // /Im0 16 0 R // >> // >> // /Subtype /Form //>> //stream // q // 0 0 100 100 re // W n // q // /GS0 gs // 100 0 0 -100 0 100 cm // /Im0 Do // Q //Q //endstream PdfFormXObject pdfForm = Context.PdfDocument.Internals.CreateIndirectObject <PdfFormXObject>(); pdfForm.DpiX = 96; pdfForm.DpiY = 96; // view box var box = new PdfRectangle(brush.Viewbox.X, brush.Viewbox.Y + brush.Viewbox.Height - 1, brush.Viewbox.X + brush.Viewbox.Width - 1, brush.Viewbox.Y); pdfForm.Elements.SetRectangle(PdfFormXObject.Keys.BBox, box); pdfForm.Elements.SetMatrix(PdfFormXObject.Keys.Matrix, new XMatrix()); PdfContentWriter writer = new PdfContentWriter(Context, pdfForm); pdfForm.Elements.SetMatrix(PdfFormXObject.Keys.Matrix, new XMatrix()); writer.BeginContentRaw(); writer.WriteLiteral("-100 Tz\n"); writer.WriteLiteral("q\n"); writer.WriteVisual(brush.Visual); writer.WriteLiteral("Q\n"); #if DEBUG if (DevHelper.BorderPatterns) { writer.WriteLiteral("1 1 1 rg 0 0 m {0:0.###} 0 l {0:0.###} {1:0.###} l 0 {1:0.###} l h s\n", brush.Viewbox.Width, brush.Viewbox.Height); } #endif writer.EndContent(); return(pdfForm); }
PdfShadingPattern BuildPattern(RadialGradientBrush brush, XRect boundingBox, XMatrix transform) { //<< // /BBox [0 0 600 760] // /Length 123 // /Matrix [0.75 0 0 -0.75 0 480] // /PaintType 1 // /PatternType 1 // /Resources // << // /ColorSpace // << // /CS0 12 0 R // /CS1 12 0 R // >> // /ExtGState // << // /GS0 10 0 R // /GS1 16 0 R // >> // /Shading // << // /Sh0 15 0 R // >> // >> // /TilingType 3 // /Type /Pattern // /XStep 600 // /YStep 1520 //>> //stream // /CS0 cs 1 0 0 scn // 1 i // /GS0 gs // 0 0 600 759.999 re // f // q // 0 0 600 760 re // W n // q // 0 g // /GS1 gs // 1 0 0 0.5 0 0 cm // BX /Sh0 sh EX Q // Q //endstream XRect bbox = new XRect(-600,-700, 1200, 1520); // HACK XMatrix matrix = transform; //matrix.Prepend(brush.Transform.Matrix); double xStep = 600; double yStep = 1520; // HACK PdfShadingPattern pattern = Context.PdfDocument.Internals.CreateIndirectObject<PdfShadingPattern>(); 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); double dx = 2 * brush.RadiusX; double dy = 2 * brush.RadiusY; XRect brushBox = new XRect(brush.Center.X - brush.RadiusX, brush.Center.Y - brush.RadiusY, dx, dy); Debug.Assert(dx * dy > 0, "Radius is 0."); double scaleX, scaleY; if (dx > dy) { scaleX = 1; scaleY = dy / dx; } else { scaleX = dx / dy; scaleY = 1; } PdfColorMode colorMode = PdfColorMode.Rgb; PdfDictionary funcReflected; PdfDictionary funcRegular = BuildShadingFunction(brush.GradientStops, false, colorMode, true, out funcReflected); if (brush.SpreadMethod != SpreadMethod.Pad) { if (CanOptimizeForTwoColors(brush.GradientStops)) { PdfDictionary dummy; funcReflected = BuildShadingFunction(brush.GradientStops, false, colorMode, false, out dummy); } else { Context.PdfDocument.Internals.AddObject(funcRegular); } } //PdfShading shading = BuildShading(brush, scaleX, scaleY); int shadingCount = 1; if (brush.SpreadMethod != SpreadMethod.Pad) { // TODO: Calculate number of required shadings shadingCount = Convert.ToInt32(Math.Max(boundingBox.width / (2 * brush.RadiusX), boundingBox.height / (2 * brush.RadiusY)) + 1); // HACK: Rule of thumb, better than nothing shadingCount *= 2; } PdfShading[] shadings = new PdfShading[shadingCount]; // Create the shadings for (int idx = 0; idx < shadingCount; idx++) { PdfShading shading = BuildShading2(brush, scaleX, scaleY, idx, brush.SpreadMethod == SpreadMethod.Reflect && idx % 2 == 1 ? funcReflected : funcRegular); shadings[idx] = shading; } PdfContentWriter writer = new PdfContentWriter(Context, pattern); writer.BeginContentRaw(); // Fill background (even if spread method is not pad) writer.WriteLiteral("q /DeviceRGB cs\n"); //writer.WriteLiteral(PdfEncoders.ToString(clr0, colorMode) + " rg 1 i\n"); writer.WriteLiteral(PdfEncoders.ToString(brush.GradientStops[brush.GradientStops.Count - 1].Color, PdfColorMode.Rgb) + " rg 1 i\n"); writer.WriteLiteral("1 i\n"); PdfExtGState gs = Context.PdfDocument.Internals.CreateIndirectObject<PdfExtGState>(); gs.SetDefault1(); writer.WriteGraphicsState(gs); writer.WriteLiteral("0 0 600 760 re f\n"); XMatrix mat = brush.Transform.Matrix; if (!mat.IsIdentity) writer.WriteMatrix(mat); // Just work: silly loop thru shadings for (int idx = shadingCount - 1; idx >= 0; idx--) { writer.WriteLiteral("q 0 0 600 760 re W n\n"); writer.WriteLiteral("q 0 g\n"); gs = Context.PdfDocument.Internals.CreateIndirectObject<PdfExtGState>(); gs.SetDefault2(); writer.WriteGraphicsState(gs); XMatrix transformation = new XMatrix(scaleX, 0, 0, scaleY, 0, 0); writer.WriteMatrix(transformation); string shName = writer.Resources.AddShading(shadings[idx]); writer.WriteLiteral("BX " + shName + " sh EX Q Q\n"); } writer.WriteLiteral("Q\n"); writer.EndContent(); return pattern; }
/// <summary> /// Builds the soft mask. /// </summary> PdfSoftMask BuildSoftMask(RadialGradientBrush brush) { Debug.Assert(brush.GradientStops.HasTransparency); XRect viewBox = new XRect(0, 0, 360, 480); // HACK //XForm xform = new XForm(Context.PdfDocument, viewBox); PdfFormXObject form = Context.PdfDocument.Internals.CreateIndirectObject <PdfFormXObject>(); #if DEBUG if (DevHelper.RenderComments) { form.Elements.SetString("/@comment", "This is the Form XObject of the soft mask"); } #endif form.Elements.SetRectangle(PdfFormXObject.Keys.BBox, new PdfRectangle(viewBox)); // Transparency group of mask form //<< // /CS /DeviceGray // /I false // /K false // /S /Transparency // /Type /Group //>> PdfTransparencyGroupAttributes tgAttributes = Context.PdfDocument.Internals.CreateIndirectObject <PdfTransparencyGroupAttributes>(); tgAttributes.Elements.SetName(PdfTransparencyGroupAttributes.Keys.CS, "/DeviceGray"); tgAttributes.Elements.SetBoolean(PdfTransparencyGroupAttributes.Keys.I, false); tgAttributes.Elements.SetBoolean(PdfTransparencyGroupAttributes.Keys.K, false); // ExtGState of mask form //<< // /AIS false // /BM /Normal // /ca 1 // /CA 1 // /op false // /OP false // /OPM 1 // /SA true // /SMask /None // /Type /ExtGState //>> PdfExtGState pdfStateMaskFrom = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>(); pdfStateMaskFrom.SetDefault1(); // Shading of mask form PdfShading shadingFrom = BuildShadingForSoftMask(brush); ////// Set reference to transparency group attributes ////pdfForm.Elements.SetObject(PdfFormXObject.Keys.Group, tgAttributes); ////pdfForm.Elements[PdfFormXObject.Keys.Matrix] = new PdfLiteral("[1.001 0 0 1.001 0.001 0.001]"); // Soft mask //<< // /G 21 0 R % form // /S /Luminosity // /Type /Mask //>> PdfSoftMask softmask = Context.PdfDocument.Internals.CreateIndirectObject <PdfSoftMask>(); // new PdfSoftMask(this.writer.Owner); //extGState.Elements.SetReference(PdfExtGState.Keys.SMask, softmask); //this.writer.Owner.Internals.AddObject(softmask); #if DEBUG if (DevHelper.RenderComments) { softmask.Elements.SetString("/@comment", "This is the soft mask"); } #endif softmask.Elements.SetName(PdfSoftMask.Keys.S, "/Luminosity"); softmask.Elements.SetReference(PdfSoftMask.Keys.G, form); // Create content of mask form //<< // /BBox [200.118 369.142 582.795 -141.094] // /Group 16 0 R // /Length 121 // /Matrix [1 0 0 1 0 0] // /Resources // << // /ExtGState // << // /GS0 20 0 R // >> // /Shading // << // /Sh0 19 0 R // >> // >> // /Subtype /Form //>> //stream // q // 200.118 369.142 382.677 -510.236 re // W n // q // 0 g // 1 i // GS0 gs // 0.75 0 0 -0.75 200.1181183 369.1417236 cm // BX /Sh0 sh EX Q // Q //endstream form.Elements.SetReference(PdfFormXObject.Keys.Group, tgAttributes); PdfContentWriter writer = new PdfContentWriter(Context, form); writer.BeginContentRaw(); // Acrobat 8 clips to bounding box, so we should do // why 0 480 360 -480 re ?? //writer.WriteClip(bbox); //writer.WriteGraphicsState(extGState); writer.WriteLiteral("1 i 0 g\n"); writer.WriteLiteral(writer.Resources.AddExtGState(pdfStateMaskFrom) + " gs\n"); XMatrix transform = new XMatrix(); //(brush.Viewport.Width / viewBoxForm.width, 0, 0, brush.Viewport.Height / viewBoxForm.height, 0, 0); writer.WriteMatrix(transform); writer.WriteLiteral("BX " + writer.Resources.AddShading(shadingFrom) + " sh EX\n"); writer.EndContent(); return(softmask); }
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); }
/// <summary> /// Builds a PdfFormXObject from the specified brush. /// // If a gradient contains transparency, a soft mask is created an added to the specified graphic state. /// </summary> PdfFormXObject BuildForm(RadialGradientBrush brush, PathGeometry geometry) { PdfFormXObject pdfForm = Context.PdfDocument.Internals.CreateIndirectObject <PdfFormXObject>(); // HACK pdfForm.Elements.SetRectangle(PdfFormXObject.Keys.BBox, new PdfRectangle(0, 640, 480, 0)); // Transparency group of the form //<< // /I true // /K false // /S /Transparency // /Type /Group //>> PdfTransparencyGroupAttributes tgPrimaryForm = Context.PdfDocument.Internals.CreateIndirectObject <PdfTransparencyGroupAttributes>(); // not set by Acrobat: tgAttributes.Elements.SetName(PdfTransparencyGroupAttributes.Keys.CS, "/DeviceRGB"); tgPrimaryForm.Elements.SetBoolean(PdfTransparencyGroupAttributes.Keys.I, true); tgPrimaryForm.Elements.SetBoolean(PdfTransparencyGroupAttributes.Keys.K, false); pdfForm.Elements.SetReference(PdfFormXObject.Keys.Group, tgPrimaryForm); // Shading PdfShading shading = BuildShading(brush, 1, 1); // ExtGState //<< // /AIS false // /BM /Normal // /ca 1 // /CA 1 // /op false // /OP false // /OPM 1 // /SA true // /SMask 22 0 R // /Type /ExtGState //>> PdfExtGState pdfExtGState = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>(); pdfExtGState.SetDefault1(); // Soft mask PdfSoftMask softmask = BuildSoftMask(brush); pdfExtGState.Elements.SetReference(PdfExtGState.Keys.SMask, softmask); // PdfFormXObject //<< // /BBox [200.118 369.142 582.795 -141.094] // /Group 11 0 R // /Length 117 // /Matrix [1 0 0 1 0 0] // /Resources // << // /ColorSpace // << // /CS0 8 0 R // >> // /ExtGState // << // /GS0 23 0 R // >> // /Shading // << // /Sh0 14 0 R // >> // >> // /Subtype /Form //>> //stream //q //203.868 365.392 157.5 -97.5 re //W* n //q //0 g //1 i ///GS0 gs //0.75 0 0 -0.75 200.1181183 369.1417236 cm //BX /Sh0 sh EX Q //Q //endstream PdfContentWriter writer = new PdfContentWriter(Context, pdfForm); writer.BeginContentRaw(); // Acrobat 8 clips to bounding box, so we should do writer.WriteClip(geometry); //writer.WriteGraphicsState(extGState); //writer.WriteLiteral("0 g\n"); writer.WriteLiteral(writer.Resources.AddExtGState(pdfExtGState) + " gs\n"); XMatrix transform = new XMatrix(); //(brush.Viewport.Width / viewBoxForm.width, 0, 0, brush.Viewport.Height / viewBoxForm.height, 0, 0); writer.WriteMatrix(transform); writer.WriteLiteral("BX " + writer.Resources.AddShading(shading) + " sh EX\n"); writer.EndContent(); return(pdfForm); }
PdfShadingPattern BuildPattern(RadialGradientBrush brush, XRect boundingBox, XMatrix transform) { //<< // /BBox [0 0 600 760] // /Length 123 // /Matrix [0.75 0 0 -0.75 0 480] // /PaintType 1 // /PatternType 1 // /Resources // << // /ColorSpace // << // /CS0 12 0 R // /CS1 12 0 R // >> // /ExtGState // << // /GS0 10 0 R // /GS1 16 0 R // >> // /Shading // << // /Sh0 15 0 R // >> // >> // /TilingType 3 // /Type /Pattern // /XStep 600 // /YStep 1520 //>> //stream // /CS0 cs 1 0 0 scn // 1 i // /GS0 gs // 0 0 600 759.999 re // f // q // 0 0 600 760 re // W n // q // 0 g // /GS1 gs // 1 0 0 0.5 0 0 cm // BX /Sh0 sh EX Q // Q //endstream XRect bbox = new XRect(-600, -700, 1200, 1520); // HACK XMatrix matrix = transform; //matrix.Prepend(brush.Transform.Matrix); double xStep = 600; double yStep = 1520; // HACK PdfShadingPattern pattern = Context.PdfDocument.Internals.CreateIndirectObject <PdfShadingPattern>(); 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); double dx = 2 * brush.RadiusX; double dy = 2 * brush.RadiusY; XRect brushBox = new XRect(brush.Center.X - brush.RadiusX, brush.Center.Y - brush.RadiusY, dx, dy); Debug.Assert(dx * dy > 0, "Radius is 0."); double scaleX, scaleY; if (dx > dy) { scaleX = 1; scaleY = dy / dx; } else { scaleX = dx / dy; scaleY = 1; } PdfColorMode colorMode = PdfColorMode.Rgb; PdfDictionary funcReflected; PdfDictionary funcRegular = BuildShadingFunction(brush.GradientStops, false, colorMode, true, out funcReflected); if (brush.SpreadMethod != SpreadMethod.Pad) { if (CanOptimizeForTwoColors(brush.GradientStops)) { PdfDictionary dummy; funcReflected = BuildShadingFunction(brush.GradientStops, false, colorMode, false, out dummy); } else { Context.PdfDocument.Internals.AddObject(funcRegular); } } //PdfShading shading = BuildShading(brush, scaleX, scaleY); int shadingCount = 1; if (brush.SpreadMethod != SpreadMethod.Pad) { // TODO: Calculate number of required shadings shadingCount = Convert.ToInt32(Math.Max(boundingBox.Width / (2 * brush.RadiusX), boundingBox.Height / (2 * brush.RadiusY)) + 1); // HACK: Rule of thumb, better than nothing shadingCount *= 2; } PdfShading[] shadings = new PdfShading[shadingCount]; // Create the shadings for (int idx = 0; idx < shadingCount; idx++) { PdfShading shading = BuildShading2(brush, scaleX, scaleY, idx, brush.SpreadMethod == SpreadMethod.Reflect && idx % 2 == 1 ? funcReflected : funcRegular); shadings[idx] = shading; } PdfContentWriter writer = new PdfContentWriter(Context, pattern); writer.BeginContentRaw(); // Fill background (even if spread method is not pad) writer.WriteLiteral("q /DeviceRGB cs\n"); //writer.WriteLiteral(PdfEncoders.ToString(clr0, colorMode) + " rg 1 i\n"); writer.WriteLiteral(PdfEncoders.ToString(brush.GradientStops[brush.GradientStops.Count - 1].Color, PdfColorMode.Rgb) + " rg 1 i\n"); writer.WriteLiteral("1 i\n"); PdfExtGState gs = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>(); gs.SetDefault1(); writer.WriteGraphicsState(gs); writer.WriteLiteral("0 0 600 760 re f\n"); XMatrix mat = brush.Transform.Matrix; if (!mat.IsIdentity) { writer.WriteMatrix(mat); } // Just work: silly loop thru shadings for (int idx = shadingCount - 1; idx >= 0; idx--) { writer.WriteLiteral("q 0 0 600 760 re W n\n"); writer.WriteLiteral("q 0 g\n"); gs = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>(); gs.SetDefault2(); writer.WriteGraphicsState(gs); XMatrix transformation = new XMatrix(scaleX, 0, 0, scaleY, 0, 0); writer.WriteMatrix(transformation); string shName = writer.Resources.AddShading(shadings[idx]); writer.WriteLiteral("BX " + shName + " sh EX Q Q\n"); } writer.WriteLiteral("Q\n"); writer.EndContent(); return(pattern); }
/// <summary> /// Builds a PdfFormXObject from the specified brush. /// </summary> PdfFormXObject BuildForm(VisualBrush brush) { //<< // /BBox [0 100 100 0] // /Length 65 // /Matrix [1 0 0 1 0 0] // /Resources // << // /ColorSpace // << // /CS0 15 0 R // >> // /ExtGState // << // /GS0 10 0 R // >> // /ProcSet [/PDF /ImageC /ImageI] // /XObject // << // /Im0 16 0 R // >> // >> // /Subtype /Form //>> //stream // q // 0 0 100 100 re // W n // q // /GS0 gs // 100 0 0 -100 0 100 cm // /Im0 Do // Q //Q //endstream PdfFormXObject pdfForm = Context.PdfDocument.Internals.CreateIndirectObject<PdfFormXObject>(); pdfForm.DpiX = 96; pdfForm.DpiY = 96; // view box var box = new PdfRectangle(brush.Viewbox.X, brush.Viewbox.Y + brush.Viewbox.Height - 1, brush.Viewbox.X + brush.Viewbox.Width - 1, brush.Viewbox.Y); pdfForm.Elements.SetRectangle(PdfFormXObject.Keys.BBox, box); pdfForm.Elements.SetMatrix(PdfFormXObject.Keys.Matrix, new XMatrix()); PdfContentWriter writer = new PdfContentWriter(Context, pdfForm); pdfForm.Elements.SetMatrix(PdfFormXObject.Keys.Matrix, new XMatrix()); writer.BeginContentRaw(); writer.WriteLiteral("-100 Tz\n"); writer.WriteLiteral("q\n"); writer.WriteVisual(brush.Visual); writer.WriteLiteral("Q\n"); #if DEBUG if (DevHelper.BorderPatterns) writer.WriteLiteral("1 1 1 rg 0 0 m {0:0.###} 0 l {0:0.###} {1:0.###} l 0 {1:0.###} l h s\n", brush.Viewbox.Width, brush.Viewbox.Height); #endif writer.EndContent(); return pdfForm; }