/// <summary> /// Setups the shading pattern from the specified brush. /// </summary> public void SetupFromBrush(XLinearGradientBrush brush, XMatrix matrix) { if (brush == null) throw new ArgumentNullException("brush"); PdfShading shading = new PdfShading(this.document); shading.SetupFromBrush(brush); Elements[Keys.Shading] = shading; Elements[Keys.Matrix] = new PdfLiteral("[" + PdfEncoders.ToString(matrix) + "]"); }
/// <summary> /// Setups the shading pattern from the specified brush. /// </summary> internal void SetupFromBrush(XLinearGradientBrush brush, XMatrix matrix, XGraphicsPdfRenderer renderer) { if (brush == null) throw new ArgumentNullException("brush"); PdfShading shading = new PdfShading(_document); shading.SetupFromBrush(brush, renderer); Elements[Keys.Shading] = shading; //Elements[Keys.Matrix] = new PdfLiteral("[" + PdfEncoders.ToString(matrix) + "]"); Elements.SetMatrix(Keys.Matrix, matrix); }
/// <summary> /// Setups the shading pattern from the specified brush. /// </summary> internal void SetupFromBrush(XLinearGradientBrush brush, XMatrix matrix, XGraphicsPdfRenderer renderer) { if (brush == null) { throw new ArgumentNullException("brush"); } PdfShading shading = new PdfShading(_document); shading.SetupFromBrush(brush, renderer); Elements[Keys.Shading] = shading; //Elements[Keys.Matrix] = new PdfLiteral("[" + PdfEncoders.ToString(matrix) + "]"); Elements.SetMatrix(Keys.Matrix, matrix); }
/// <summary> /// Setups the shading pattern from the specified brush. /// </summary> public void SetupFromBrush(XLinearGradientBrush brush, XMatrix matrix) { if (brush == null) { throw new ArgumentNullException("brush"); } PdfShading shading = new PdfShading(this.document); shading.SetupFromBrush(brush); Elements[Keys.Shading] = shading; //Elements[Keys.Matrix] = new PdfLiteral("[" + PdfEncoders.ToString(matrix) + "]"); Elements.SetMatrix(Keys.Matrix, matrix); }
/// <summary> /// Adds the specified shading to this resource dictionary /// and returns its local resource name. /// </summary> public string AddShading(PdfShading shading) { string name; if (!_resources.TryGetValue(shading, out name)) { name = NextShadingName; _resources[shading] = name; if (shading.Reference == null) { Owner._irefTable.Add(shading); } Shadings.Elements[name] = shading.Reference; } return(name); }
/// <summary> /// Builds a PdfShading from the specified brush. If a gradient contains transparency, a soft mask is created an added to the /// specified graphic state. /// </summary> PdfShading BuildShading(LinearGradientBrush brush) { // Setup shading PdfShading shading = new PdfShading(Context.PdfDocument); #if DEBUG if (DevHelper.RenderComments) shading.Elements.SetString("/@comment", "This is the shading of a LinearGradientBrush"); #endif PdfColorMode colorMode = PdfColorMode.Rgb; //this.document.Options.ColorMode; PdfDictionary function = BuildShadingFunction(brush.GradientStops, false, colorMode); #if DEBUG if (DevHelper.RenderComments) function.Elements.SetString("/@comment", "This is the shading function of a LinearGradientBrush"); #endif shading.Elements.SetBoolean(PdfShading.Keys.AntiAlias, false); shading.Elements[PdfShading.Keys.Function] = function; shading.Elements.SetInteger(PdfShading.Keys.ShadingType, 2); // Axial shading shading.Elements.SetName(PdfShading.Keys.ColorSpace, "/DeviceRGB"); // TODO: respect ColorMode double x1 = brush.StartPoint.X; double y1 = brush.StartPoint.Y; double x2 = brush.EndPoint.X; double y2 = brush.EndPoint.Y; shading.Elements[PdfShading.Keys.Coords] = new PdfLiteral("[{0:0.####} {1:0.####} {2:0.####} {3:0.####}]", x1, y1, x2, y2); shading.Elements[PdfShading.Keys.Domain] = new PdfLiteral("[0 1]"); if (brush.SpreadMethod == SpreadMethod.Pad) shading.Elements[PdfShading.Keys.Extend] = new PdfLiteral("[true true]"); else { DevHelper.NotImplemented("SpreadMethod." + brush.SpreadMethod.ToString() + " Background painted in green."); #if DEBUG // Note from PDF reference: The background color is applied only when the shading is used as part of // a shading pattern, not when it is painted directly with the sh operator. shading.Elements[PdfShading.Keys.Background] = new PdfLiteral("[0 1 0]"); // TODO: respect ColorMode #else // Best we can currently do shading.Elements[PdfShading.Keys.Extend] = new PdfLiteral("[true true]"); #endif } return shading; }
/// <summary> /// Adds the specified shading to this resource dictionary /// and returns its local resource name. /// </summary> public string AddShading(PdfShading shading) { string name; if (!this.resources.TryGetValue(shading, out name)) { name = NextShadingName; this.resources[shading] = name; if (shading.Reference == null) Owner.irefTable.Add(shading); Shadings.Elements[name] = shading.Reference; } return name; }
void RealizeLinearGradientBrush(LinearGradientBrush brush, XForm xform) { XMatrix matrix = this.currentTransform; PdfShadingPattern pattern = new PdfShadingPattern(this.writer.Owner); pattern.Elements[PdfShadingPattern.Keys.PatternType] = new PdfInteger(2); // shading pattern // Setup shading PdfShading shading = new PdfShading(this.writer.Owner); PdfColorMode colorMode = PdfColorMode.Rgb; //this.document.Options.ColorMode; PdfDictionary function = BuildShadingFunction(brush.GradientStops, colorMode); function.Elements.SetString("/@", "This is the shading function of a LinearGradientBrush"); shading.Elements[PdfShading.Keys.Function] = function; shading.Elements[PdfShading.Keys.ShadingType] = new PdfInteger(2); // Axial shading //if (colorMode != PdfColorMode.Cmyk) shading.Elements[PdfShading.Keys.ColorSpace] = new PdfName("/DeviceRGB"); //else //shading.Elements[Keys.ColorSpace] = new PdfName("/DeviceCMYK"); //double x1 = 0, y1 = 0, x2 = 0, y2 = 0; double x1 = brush.StartPoint.X; double y1 = brush.StartPoint.Y; double x2 = brush.EndPoint.X; double y2 = brush.EndPoint.Y; shading.Elements[PdfShading.Keys.Coords] = new PdfLiteral("[{0:0.###} {1:0.###} {2:0.###} {3:0.###}]", x1, y1, x2, y2); // old: Elements[Keys.Background] = new PdfRawItem("[0 1 1]"); // old: Elements[Keys.Domain] = shading.Elements[PdfShading.Keys.Extend] = new PdfLiteral("[true true]"); // Setup pattern pattern.Elements[PdfShadingPattern.Keys.Shading] = shading; pattern.Elements[PdfShadingPattern.Keys.Matrix] = PdfLiteral.FromMatrix(matrix); // new PdfLiteral("[" + PdfEncoders.ToString(matrix) + "]"); string name = this.writer.Resources.AddPattern(pattern); this.writer.WriteLiteral("/Pattern cs\n", name); this.writer.WriteLiteral("{0} scn\n", name); double alpha = brush.Opacity * brush.GradientStops.GetAverageAlpha(); if (alpha < 1 && this.writer.renderMode == RenderMode.Default) { #if true PdfExtGState extGState = this.writer.Owner.ExtGStateTable.GetExtGStateNonStroke(alpha); string gs = this.writer.Resources.AddExtGState(extGState); this.writer.WriteLiteral("{0} gs\n", gs); #else #if true if (xform == null) { PdfExtGState extGState = this.writer.Owner.ExtGStateTable.GetExtGStateNonStroke(alpha); string gs = this.writer.Resources.AddExtGState(extGState); this.writer.WriteGraphicState(extGState); } else { //PdfFormXObject pdfForm = this.writer.Owner.FormTable.GetForm(form); PdfFormXObject pdfForm = xform.pdfForm; pdfForm.Elements.SetString("/@", "This is the Form XObject of the soft mask"); string formName = this.writer.Resources.AddForm(pdfForm); PdfTransparencyGroupAttributes tgAttributes = new PdfTransparencyGroupAttributes(this.writer.Owner); //this.writer.Owner.Internals.AddObject(tgAttributes); tgAttributes.Elements.SetName(PdfTransparencyGroupAttributes.Keys.CS, "/DeviceRGB"); // 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]"); PdfSoftMask softmask = new PdfSoftMask(this.writer.Owner); this.writer.Owner.Internals.AddObject(softmask); softmask.Elements.SetString("/@", "This is the soft mask"); softmask.Elements.SetName(PdfSoftMask.Keys.S, "/Luminosity"); softmask.Elements.SetReference(PdfSoftMask.Keys.G, pdfForm); //pdfForm.Elements.SetName(PdfFormXObject.Keys.Type, "Group"); //pdfForm.Elements.SetName(PdfFormXObject.Keys.ss.Ss.Type, "Group"); PdfExtGState extGState = new PdfExtGState(this.writer.Owner); this.writer.Owner.Internals.AddObject(extGState); extGState.Elements.SetReference(PdfExtGState.Keys.SMask, softmask); this.writer.WriteGraphicState(extGState); } #else XForm form = new XForm(this.writer.Owner, 220, 140); XGraphics formGfx = XGraphics.FromForm(form); // draw something //XSolidBrush xbrush = new XSolidBrush(XColor.FromArgb(128, 128, 128)); XLinearGradientBrush xbrush = new XLinearGradientBrush(new XPoint(0, 0), new XPoint(220,0), XColors.White, XColors.Black); formGfx.DrawRectangle(xbrush, -10000, -10000, 20000, 20000); //formGfx.DrawString("Text, Graphics, Images, and Forms", new XFont("Verdana", 10, XFontStyle.Regular), XBrushes.Navy, 3, 0, XStringFormat.TopLeft); formGfx.Dispose(); // Close form form.Finish(); PdfFormXObject pdfForm = this.writer.Owner.FormTable.GetForm(form); string formName = this.writer.Resources.AddForm(pdfForm); //double x = 20, y = 20; //double cx = 1; //double cy = 1; //this.writer.AppendFormat("q {2:0.###} 0 0 -{3:0.###} {0:0.###} {4:0.###} cm 100 Tz {5} Do Q\n", // x, y, cx, cy, y + 0, formName); //this.writer.AppendFormat("q {2:0.###} 0 0 -{3:0.###} {0:0.###} {4:0.###} cm 100 Tz {5} Do Q\n", // x, y, cx, cy, y + 220/1.5, formName); PdfTransparencyGroupAttributes tgAttributes = new PdfTransparencyGroupAttributes(this.writer.Owner); this.writer.Owner.Internals.AddObject(tgAttributes); tgAttributes.Elements.SetName(PdfTransparencyGroupAttributes.Keys.CS, "/DeviceRGB"); // Set reference to transparency group attributes pdfForm.Elements.SetReference(PdfFormXObject.Keys.Group, tgAttributes); PdfSoftMask softmask = new PdfSoftMask(this.writer.Owner); this.writer.Owner.Internals.AddObject(softmask); softmask.Elements.SetName(PdfSoftMask.Keys.S, "/Luminosity"); softmask.Elements.SetReference(PdfSoftMask.Keys.G, pdfForm); //pdfForm.Elements.SetName(PdfFormXObject.Keys.Type, "Group"); //pdfForm.Elements.SetName(PdfFormXObject.Keys.ss.Ss.Type, "Group"); PdfExtGState extGState = new PdfExtGState(this.writer.Owner); this.writer.Owner.Internals.AddObject(extGState); extGState.Elements.SetReference(PdfExtGState.Keys.SMask, softmask); this.writer.WriteGraphicState(extGState); #endif #endif } }
void RealizeRadialGradientBrush(RadialGradientBrush brush, XForm xform) { XMatrix matrix = new XMatrix(); // this.renderer.defaultViewMatrix; //matrix.MultiplyPrepend(this.Transform); matrix = this.currentTransform; //matrix.MultiplyPrepend(XMatrix.CreateScaling(1.3, 1)); PdfShadingPattern pattern = new PdfShadingPattern(this.writer.Owner); pattern.Elements[PdfShadingPattern.Keys.PatternType] = new PdfInteger(2); // shading pattern // Setup shading PdfShading shading = new PdfShading(this.writer.Owner); PdfColorMode colorMode = PdfColorMode.Rgb; //this.document.Options.ColorMode; PdfDictionary function = BuildShadingFunction(brush.GradientStops, colorMode); shading.Elements[PdfShading.Keys.ShadingType] = new PdfInteger(3); // Radial shading //if (colorMode != PdfColorMode.Cmyk) shading.Elements[PdfShading.Keys.ColorSpace] = new PdfName("/DeviceRGB"); //else //shading.Elements[Keys.ColorSpace] = new PdfName("/DeviceCMYK"); double x0 = brush.GradientOrigin.X; double y0 = brush.GradientOrigin.Y; double r0 = 0; double x1 = brush.Center.X; double y1 = brush.Center.Y; double r1 = brush.RadiusX; shading.Elements[PdfShading.Keys.Coords] = new PdfLiteral("[{0:0.###} {1:0.###} {2:0.###} {3:0.###} {4:0.###} {5:0.###}]", x0, y0, r0, x1, y1, r1); // old: Elements[Keys.Background] = new PdfRawItem("[0 1 1]"); // old: Elements[Keys.Domain] = shading.Elements[PdfShading.Keys.Function] = function; shading.Elements[PdfShading.Keys.Extend] = new PdfLiteral("[true true]"); // Setup pattern pattern.Elements[PdfShadingPattern.Keys.Shading] = shading; pattern.Elements[PdfShadingPattern.Keys.Matrix] = PdfLiteral.FromMatrix(matrix); // new PdfLiteral("[" + PdfEncoders.ToString(matrix) + "]"); string name = this.writer.Resources.AddPattern(pattern); this.writer.WriteLiteral("/Pattern cs\n", name); this.writer.WriteLiteral("{0} scn\n", name); double alpha = brush.Opacity * brush.GradientStops.GetAverageAlpha(); if (alpha < 1) { #if true PdfExtGState extGState = this.writer.Owner.ExtGStateTable.GetExtGStateNonStroke(alpha); string gs = this.writer.Resources.AddExtGState(extGState); this.writer.WriteLiteral("{0} gs\n", gs); #else if (xform == null) { PdfExtGState extGState = this.writer.Owner.ExtGStateTable.GetExtGStateNonStroke(alpha); string gs = this.writer.Resources.AddExtGState(extGState); this.writer.WriteGraphicState(extGState); } else { //PdfFormXObject pdfForm = this.writer.Owner.FormTable.GetForm(form); PdfFormXObject pdfForm = xform.pdfForm; pdfForm.Elements.SetString("/@", "This is the Form XObject of the soft mask"); string formName = this.writer.Resources.AddForm(pdfForm); PdfTransparencyGroupAttributes tgAttributes = new PdfTransparencyGroupAttributes(this.writer.Owner); //this.writer.Owner.Internals.AddObject(tgAttributes); tgAttributes.Elements.SetName(PdfTransparencyGroupAttributes.Keys.CS, "/DeviceRGB"); // 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]"); PdfSoftMask softmask = new PdfSoftMask(this.writer.Owner); this.writer.Owner.Internals.AddObject(softmask); softmask.Elements.SetString("/@", "This is the soft mask"); softmask.Elements.SetName(PdfSoftMask.Keys.S, "/Luminosity"); softmask.Elements.SetReference(PdfSoftMask.Keys.G, pdfForm); //pdfForm.Elements.SetName(PdfFormXObject.Keys.Type, "Group"); //pdfForm.Elements.SetName(PdfFormXObject.Keys.ss.Ss.Type, "Group"); PdfExtGState extGState = new PdfExtGState(this.writer.Owner); this.writer.Owner.Internals.AddObject(extGState); extGState.Elements.SetReference(PdfExtGState.Keys.SMask, softmask); this.writer.WriteGraphicState(extGState); } #endif } }
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> /// Adds the specified shading to this resource dictionary /// and returns its local resource name. /// </summary> public string AddShading(PdfShading shading) { string name = (string)this.resources[shading]; if (name == null) { name = NextShadingName; this.resources[shading] = name; if (shading.Reference == null) this.Owner.irefTable.Add(shading); Shadings.Elements[name] = shading.Reference; } return name; }