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); }
public void RealizeBrush(XBrush brush, PdfColorMode colorMode, int renderingMode, double fontEmSize, bool isForPen = false) { // Rendering mode 2 is used for bold simulation. // Reference: TABLE 5.3 Text rendering modes / Page 402 XSolidBrush solidBrush = brush as XSolidBrush; if (solidBrush != null) { XColor color = solidBrush.Color; bool overPrint = solidBrush.Overprint; if (renderingMode == 0) { RealizeFillColor(color, overPrint, colorMode); } else if (renderingMode == 2) { // Come here in case of bold simulation. RealizeFillColor(color, false, colorMode); //color = XColors.Green; RealizePen(new XPen(color, fontEmSize * Const.BoldEmphasis), colorMode); } else { throw new InvalidOperationException("Only rendering modes 0 and 2 are currently supported."); } } else { if (renderingMode != 0) { throw new InvalidOperationException("Rendering modes other than 0 can only be used with solid color brushes."); } if (brush is XBaseGradientBrush gradientBrush) { Debug.Assert(UnrealizedCtm.IsIdentity, "Must realize ctm first."); XMatrix matrix = _renderer.DefaultViewMatrix; matrix.Prepend(EffectiveCtm); PdfShadingPattern pattern = new PdfShadingPattern(_renderer.Owner); pattern.SetupFromBrush(gradientBrush, matrix, _renderer); string name = _renderer.Resources.AddPattern(pattern); if (isForPen) { _renderer.AppendFormatString("/Pattern CS\n", name); _renderer.AppendFormatString("{0} SCN\n", name); } else { _renderer.AppendFormatString("/Pattern cs\n", name); _renderer.AppendFormatString("{0} scn\n", name); } // Invalidate fill color. _realizedFillColor = XColor.Empty; } } }
public void RealizeBrush(XBrush brush, PdfColorMode colorMode) { if (brush is XSolidBrush) { XColor color = ((XSolidBrush)brush).Color; color = ColorSpaceHelper.EnsureColorMode(colorMode, color); if (colorMode != PdfColorMode.Cmyk) { if (this.realizedFillColor.Rgb != color.Rgb) { this.renderer.Append(PdfEncoders.ToString(color, PdfColorMode.Rgb)); this.renderer.Append(" rg\n"); } } else { if (!ColorSpaceHelper.IsEqualCmyk(this.realizedFillColor, color)) { this.renderer.Append(PdfEncoders.ToString(color, PdfColorMode.Cmyk)); this.renderer.Append(" k\n"); } } if (this.renderer.Owner.Version >= 14 && this.realizedFillColor.A != color.A) { PdfExtGState extGState = this.renderer.Owner.ExtGStateTable.GetExtGStateNonStroke(color.A); string gs = this.renderer.Resources.AddExtGState(extGState); this.renderer.AppendFormat("{0} gs\n", gs); // Must create transparany group if (this.renderer.page != null && color.A < 1) { this.renderer.page.transparencyUsed = true; } } this.realizedFillColor = color; } else if (brush is XLinearGradientBrush) { XMatrix matrix = this.renderer.defaultViewMatrix; matrix.Prepend(this.Transform); PdfShadingPattern pattern = new PdfShadingPattern(this.renderer.Owner); pattern.SetupFromBrush((XLinearGradientBrush)brush, matrix); string name = this.renderer.Resources.AddPattern(pattern); this.renderer.AppendFormat("/Pattern cs\n", name); this.renderer.AppendFormat("{0} scn\n", name); // Invalidate fill color this.realizedFillColor = XColor.Empty; } }
/// <summary> /// Realizes the CTM. /// </summary> public void RealizeCtm() { if (MustRealizeCtm) { Debug.Assert(!unrealizedCtm.IsIdentity, "mrCtm is unnecessarily set."); double[] matrix = unrealizedCtm.GetElements(); // Up to six decimal digits to prevent round up problems renderer.AppendFormat("{0:0.######} {1:0.######} {2:0.######} {3:0.######} {4:0.######} {5:0.######} cm\n", matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); realizedCtm.Prepend(unrealizedCtm); unrealizedCtm = new XMatrix(); //XMatrix.Identity; MustRealizeCtm = false; } }
///// <summary> ///// The world transform in PDF world space. ///// </summary> //public XMatrix EffectiveCtm //{ // get // { // //if (MustRealizeCtm) // if (!UnrealizedCtm.IsIdentity) // { // XMatrix matrix = RealizedCtm; // matrix.Prepend(UnrealizedCtm); // return matrix; // } // return RealizedCtm; // } // //set // //{ // // XMatrix matrix = realizedCtm; // // matrix.Invert(); // // matrix.Prepend(value); // // unrealizedCtm = matrix; // // MustRealizeCtm = !unrealizedCtm.IsIdentity; // //} //} public void AddTransform(XMatrix value, XMatrixOrder matrixOrder) { // TODO: User matrixOrder //#if DEBUG // if (matrixOrder == XMatrixOrder.Append) // throw new NotImplementedException("XMatrixOrder.Append"); //#endif XMatrix transform = value; if (_renderer.Gfx.PageDirection == XPageDirection.Downwards) { // Take chirality into account and // invert the direction of rotation. transform.M12 = -value.M12; transform.M21 = -value.M21; } UnrealizedCtm.Prepend(transform); WorldTransform.Prepend(value); }
/// <summary> /// Realizes the CTM. /// </summary> public void RealizeCtm() { //if (MustRealizeCtm) if (!UnrealizedCtm.IsIdentity) { Debug.Assert(!UnrealizedCtm.IsIdentity, "mrCtm is unnecessarily set."); const string format = Config.SignificantFigures7; double[] matrix = UnrealizedCtm.GetElements(); // Use up to six decimal digits to prevent round up problems. _renderer.AppendFormatArgs("{0:" + format + "} {1:" + format + "} {2:" + format + "} {3:" + format + "} {4:" + format + "} {5:" + format + "} cm\n", matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); RealizedCtm.Prepend(UnrealizedCtm); UnrealizedCtm = new XMatrix(); EffectiveCtm = RealizedCtm; InverseEffectiveCtm = EffectiveCtm; InverseEffectiveCtm.Invert(); } }
public void Prepend(AbstractMatrix m) { matrix.Prepend(m.matrix); }
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); }
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); }