PdfDictionary BuildShadingFunction3(GradientStopCollection gradients, bool softMask, PdfColorMode colorMode) { int count = gradients.Count; Debug.Assert(count >= 2); // // Build a Type 3 function with an array of n-1 Type 2 functions PdfDictionary fn1 = new PdfDictionary(); fn1.Elements["/FunctionType"] = new PdfInteger(3); // Type 3 - Stitching Function fn1.Elements["/Domain"] = new PdfLiteral("[0 1]"); fn1.Elements["/Range"] = new PdfLiteral("[0 1 0 1 0 1]"); PdfArray fnarray = new PdfArray(); fn1.Elements["/Functions"] = fnarray; StringBuilder bounds = new StringBuilder("["); StringBuilder encode = new StringBuilder("["); for (int idx = 1; idx < count; idx++) { PdfDictionary fn2 = new PdfDictionary(); fn2.Elements["/FunctionType"] = new PdfInteger(2); Color clr0 = gradients[idx - 1].Color; Color clr1 = gradients[idx].Color; if (softMask) { fn2.Elements["/C0"] = new PdfLiteral("[" + PdfEncoders.ToString(clr0.ScA) + "]"); fn2.Elements["/C1"] = new PdfLiteral("[" + PdfEncoders.ToString(clr1.ScA) + "]"); fn2.Elements["/Range"] = new PdfLiteral("[0 1]"); } else { fn2.Elements["/C0"] = new PdfLiteral("[" + PdfEncoders.ToString(clr0, colorMode) + "]"); fn2.Elements["/C1"] = new PdfLiteral("[" + PdfEncoders.ToString(clr1, colorMode) + "]"); fn2.Elements["/Range"] = new PdfLiteral("[0 1 0 1 0 1]"); } fn2.Elements["/Domain"] = new PdfLiteral("[0 1]"); fn2.Elements["/N"] = new PdfInteger(1); fnarray.Elements.Add(fn2); if (idx > 1) { bounds.Append(' '); encode.Append(' '); } if (idx < count - 1) { bounds.Append(PdfEncoders.ToString(gradients[idx].Offset)); } encode.Append("0 1"); } bounds.Append(']'); encode.Append(']'); fn1.Elements["/Bounds"] = new PdfLiteral(bounds.ToString()); fn1.Elements["/Encode"] = new PdfLiteral(encode.ToString()); return(fn1); }
internal void SetupFromBrush(XRadialGradientBrush brush, XGraphicsPdfRenderer renderer) { if (brush == null) { throw new ArgumentNullException("brush"); } PdfColorMode colorMode = _document.Options.ColorMode; XColor color1 = ColorSpaceHelper.EnsureColorMode(colorMode, brush._color1); XColor color2 = ColorSpaceHelper.EnsureColorMode(colorMode, brush._color2); PdfDictionary function = new PdfDictionary(); Elements[Keys.ShadingType] = new PdfInteger(3); if (colorMode != PdfColorMode.Cmyk) { Elements[Keys.ColorSpace] = new PdfName("/DeviceRGB"); } else { Elements[Keys.ColorSpace] = new PdfName("/DeviceCMYK"); } XPoint p1 = renderer.WorldToView(brush._center1); XPoint p2 = renderer.WorldToView(brush._center2); var rv1 = renderer.WorldToView(new XPoint(brush._r1 + brush._center1.X, brush._center1.Y)); var rv2 = renderer.WorldToView(new XPoint(brush._r2 + brush._center2.X, brush._center2.Y)); var dx1 = rv1.X - p1.X; var dy1 = rv1.Y - p1.Y; var dx2 = rv2.X - p2.X; var dy2 = rv2.Y - p2.Y; var r1 = Math.Sqrt(dx1 * dx1 + dy1 * dy1); var r2 = Math.Sqrt(dx2 * dx2 + dy2 * dy2); const string format = Config.SignificantFigures3; Elements[Keys.Coords] = new PdfLiteral("[{0:" + format + "} {1:" + format + "} {2:" + format + "} {3:" + format + "} {4:" + format + "} {5:" + format + "}]", p1.X, p1.Y, r1, p2.X, p2.Y, r2); //Elements[Keys.Background] = new PdfRawItem("[0 1 1]"); //Elements[Keys.Domain] = Elements[Keys.Function] = function; //Elements[Keys.Extend] = new PdfRawItem("[true true]"); string clr1 = "[" + PdfEncoders.ToString(color1, colorMode, true) + "]"; string clr2 = "[" + PdfEncoders.ToString(color2, colorMode, true) + "]"; function.Elements["/FunctionType"] = new PdfInteger(2); function.Elements["/C0"] = new PdfLiteral(clr1); function.Elements["/C1"] = new PdfLiteral(clr2); function.Elements["/Domain"] = new PdfLiteral("[0 1]"); function.Elements["/N"] = new PdfInteger(1); }
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; } }
private void RealizeFillColor(XColor color, bool overPrint, PdfColorMode colorMode) { color = ColorSpaceHelper.EnsureColorMode(colorMode, color); switch (color.ColorSpace) { case XColorSpace.Rgb: if (_realizedFillColor.IsEmpty || _realizedFillColor.Rgb != color.Rgb) { _renderer.Append(PdfEncoders.ToString(color, PdfColorMode.Rgb)); _renderer.Append(" rg\n"); } break; case XColorSpace.Cmyk: if (_realizedFillColor.IsEmpty || !ColorSpaceHelper.IsEqualCmyk(_realizedFillColor, color)) { _renderer.Append(PdfEncoders.ToString(color, PdfColorMode.Cmyk)); _renderer.Append(" k\n"); } break; case XColorSpace.GrayScale: if (_realizedFillColor.IsEmpty || _realizedFillColor.GS != color.GS) { _renderer.Append(PdfEncoders.ToString(color, PdfColorMode.Undefined)); _renderer.Append(" g\n"); } break; default: break; } if (_renderer.Owner.Version >= 14 && color.ColorSpace != XColorSpace.GrayScale && (_realizedFillColor.A != color.A || _realizedNonStrokeOverPrint != overPrint)) { PdfExtGState extGState = _renderer.Owner.ExtGStateTable.GetExtGStateNonStroke(color.A, overPrint); string gs = _renderer.Resources.AddExtGState(extGState); _renderer.AppendFormatString("{0} gs\n", gs); // Must create transparency group. if (_renderer._page != null && color.A < 1) { _renderer._page.TransparencyUsed = true; } } _realizedFillColor = color; _realizedNonStrokeOverPrint = overPrint; }
private void RealizeFillColor(XColor color, bool overPrint, PdfColorMode colorMode) { color = ColorSpaceHelper.EnsureColorMode(colorMode, color); if (colorMode != PdfColorMode.Cmyk) { if (_realizedFillColor.IsEmpty || _realizedFillColor.Rgb != color.Rgb) { _renderer.Append(PdfEncoders.ToString(color, PdfColorMode.Rgb)); _renderer.Append(" rg\n"); } } else { Debug.Assert(colorMode == PdfColorMode.Cmyk); if (_realizedFillColor.IsEmpty || !ColorSpaceHelper.IsEqualCmyk(_realizedFillColor, color)) { _renderer.Append(PdfEncoders.ToString(color, PdfColorMode.Cmyk)); _renderer.Append(" k\n"); } } if (_renderer.Owner.Version >= 14 && (_realizedFillColor.A != color.A || _realizedNonStrokeOverPrint != overPrint)) { PdfExtGState extGState = _renderer.Owner.ExtGStateTable.GetExtGStateNonStroke(color.A, overPrint); string gs = _renderer.Resources.AddExtGState(extGState); _renderer.AppendFormatString("{0} gs\n", gs); // Must create transparency group. if (_renderer._page != null && color.A < 1) { _renderer._page.TransparencyUsed = true; } } _realizedFillColor = color; _realizedNonStrokeOverPrint = overPrint; }
/// <summary> /// Setups the shading from the specified brush. /// </summary> internal void SetupFromBrush(XLinearGradientBrush brush, XGraphicsPdfRenderer renderer) { if (brush == null) { throw new ArgumentNullException("brush"); } PdfColorMode colorMode = _document.Options.ColorMode; XColor color1 = ColorSpaceHelper.EnsureColorMode(colorMode, brush._color1); XColor color2 = ColorSpaceHelper.EnsureColorMode(colorMode, brush._color2); PdfDictionary function = new PdfDictionary(); Elements[Keys.ShadingType] = new PdfInteger(2); if (colorMode != PdfColorMode.Cmyk) { Elements[Keys.ColorSpace] = new PdfName("/DeviceRGB"); } else { Elements[Keys.ColorSpace] = new PdfName("/DeviceCMYK"); } double x1 = 0, y1 = 0, x2 = 0, y2 = 0; if (brush._useRect) { XPoint pt1 = renderer.WorldToView(brush._rect.TopLeft); XPoint pt2 = renderer.WorldToView(brush._rect.BottomRight); switch (brush._linearGradientMode) { case XLinearGradientMode.Horizontal: x1 = pt1.X; y1 = pt1.Y; x2 = pt2.X; y2 = pt1.Y; break; case XLinearGradientMode.Vertical: x1 = pt1.X; y1 = pt1.Y; x2 = pt1.X; y2 = pt2.Y; break; case XLinearGradientMode.ForwardDiagonal: x1 = pt1.X; y1 = pt1.Y; x2 = pt2.X; y2 = pt2.Y; break; case XLinearGradientMode.BackwardDiagonal: x1 = pt2.X; y1 = pt1.Y; x2 = pt1.X; y2 = pt2.Y; break; } } else { XPoint pt1 = renderer.WorldToView(brush._point1); XPoint pt2 = renderer.WorldToView(brush._point2); x1 = pt1.X; y1 = pt1.Y; x2 = pt2.X; y2 = pt2.Y; } const string format = Config.SignificantFigures3; Elements[Keys.Coords] = new PdfLiteral("[{0:" + format + "} {1:" + format + "} {2:" + format + "} {3:" + format + "}]", x1, y1, x2, y2); //Elements[Keys.Background] = new PdfRawItem("[0 1 1]"); //Elements[Keys.Domain] = Elements[Keys.Function] = function; //Elements[Keys.Extend] = new PdfRawItem("[true true]"); string clr1 = "[" + PdfEncoders.ToString(color1, colorMode) + "]"; string clr2 = "[" + PdfEncoders.ToString(color2, colorMode) + "]"; function.Elements["/FunctionType"] = new PdfInteger(2); function.Elements["/C0"] = new PdfLiteral(clr1); function.Elements["/C1"] = new PdfLiteral(clr2); function.Elements["/Domain"] = new PdfLiteral("[0 1]"); function.Elements["/N"] = new PdfInteger(1); }
public void RealizePen(XPen pen, PdfColorMode colorMode) { const string frmt2 = Config.SignificantFigures2; const string format = Config.SignificantFigures3; XColor color = pen.Color; bool overPrint = pen.Overprint; color = ColorSpaceHelper.EnsureColorMode(colorMode, color); if (_realizedLineWith != pen._width) { _renderer.AppendFormatArgs("{0:" + format + "} w\n", pen._width); _realizedLineWith = pen._width; } if (_realizedLineCap != (int)pen._lineCap) { _renderer.AppendFormatArgs("{0} J\n", (int)pen._lineCap); _realizedLineCap = (int)pen._lineCap; } if (_realizedLineJoin != (int)pen._lineJoin) { _renderer.AppendFormatArgs("{0} j\n", (int)pen._lineJoin); _realizedLineJoin = (int)pen._lineJoin; } if (_realizedLineCap == (int)XLineJoin.Miter) { if (_realizedMiterLimit != (int)pen._miterLimit && (int)pen._miterLimit != 0) { _renderer.AppendFormatInt("{0} M\n", (int)pen._miterLimit); _realizedMiterLimit = (int)pen._miterLimit; } } if (_realizedDashStyle != pen._dashStyle || pen._dashStyle == XDashStyle.Custom) { double dot = pen.Width; double dash = 3 * dot; // Line width 0 is not recommended but valid. XDashStyle dashStyle = pen.DashStyle; if (dot == 0) { dashStyle = XDashStyle.Solid; } switch (dashStyle) { case XDashStyle.Solid: _renderer.Append("[]0 d\n"); break; case XDashStyle.Dash: _renderer.AppendFormatArgs("[{0:" + frmt2 + "} {1:" + frmt2 + "}]0 d\n", dash, dot); break; case XDashStyle.Dot: _renderer.AppendFormatArgs("[{0:" + frmt2 + "}]0 d\n", dot); break; case XDashStyle.DashDot: _renderer.AppendFormatArgs("[{0:" + frmt2 + "} {1:" + frmt2 + "} {1:" + frmt2 + "} {1:" + frmt2 + "}]0 d\n", dash, dot); break; case XDashStyle.DashDotDot: _renderer.AppendFormatArgs("[{0:" + frmt2 + "} {1:" + frmt2 + "} {1:" + frmt2 + "} {1:" + frmt2 + "} {1:" + frmt2 + "} {1:" + frmt2 + "}]0 d\n", dash, dot); break; case XDashStyle.Custom: { StringBuilder pdf = new StringBuilder("[", 256); int len = pen._dashPattern == null ? 0 : pen._dashPattern.Length; for (int idx = 0; idx < len; idx++) { if (idx > 0) { pdf.Append(' '); } pdf.Append(PdfEncoders.ToString(pen._dashPattern[idx] * pen._width)); } // Make an even number of values look like in GDI+ if (len > 0 && len % 2 == 1) { pdf.Append(' '); pdf.Append(PdfEncoders.ToString(0.2 * pen._width)); } pdf.AppendFormat(CultureInfo.InvariantCulture, "]{0:" + format + "} d\n", pen._dashOffset * pen._width); string pattern = pdf.ToString(); // BUG: [email protected] reported a realizing problem // HACK: I remove the if clause //if (_realizedDashPattern != pattern) { _realizedDashPattern = pattern; _renderer.Append(pattern); } } break; } _realizedDashStyle = dashStyle; } if (colorMode != PdfColorMode.Cmyk) { if (_realizedStrokeColor.Rgb != color.Rgb) { _renderer.Append(PdfEncoders.ToString(color, PdfColorMode.Rgb)); _renderer.Append(" RG\n"); } } else { if (!ColorSpaceHelper.IsEqualCmyk(_realizedStrokeColor, color)) { _renderer.Append(PdfEncoders.ToString(color, PdfColorMode.Cmyk)); _renderer.Append(" K\n"); } } if (_renderer.Owner.Version >= 14 && (_realizedStrokeColor.A != color.A || _realizedStrokeOverPrint != overPrint)) { PdfExtGState extGState = _renderer.Owner.ExtGStateTable.GetExtGStateStroke(color.A, overPrint); string gs = _renderer.Resources.AddExtGState(extGState); _renderer.AppendFormatString("{0} gs\n", gs); // Must create transparency group. if (_renderer._page != null && color.A < 1) { _renderer._page.TransparencyUsed = true; } } _realizedStrokeColor = color; _realizedStrokeOverPrint = overPrint; }
/// <summary> /// Creates a literal from an XMatrix /// </summary> public static PdfLiteral FromMatrix(XMatrix matrix) { return(new PdfLiteral("[" + PdfEncoders.ToString(matrix) + "]")); }
/// <summary> /// Builds the shading function of the specified gradient stop collection. /// </summary> protected PdfDictionary BuildShadingFunction(GradientStopCollection gradients, bool softMask, PdfColorMode colorMode, bool reverse, out PdfDictionary funcReverse) { PdfDictionary func = new PdfDictionary(); int count = gradients.Count; Debug.Assert(count >= 2); if (CanOptimizeForTwoColors(gradients)) { funcReverse = null; // Build a Type 3 function with an array of 2 Type 2 functions func.Elements["/FunctionType"] = new PdfInteger(3); // Type 3 - Stitching Function func.Elements["/Domain"] = new PdfLiteral("[0 1]"); PdfArray fnarray = new PdfArray(); func.Elements["/Functions"] = fnarray; StringBuilder bounds = new StringBuilder("["); StringBuilder encode = new StringBuilder("["); for (int idx = 1; idx < count; idx++) { PdfDictionary fn2 = new PdfDictionary(); fn2.Elements["/FunctionType"] = new PdfInteger(2); Color clr0 = gradients[idx - 1].Color; Color clr1 = gradients[idx].Color; if (softMask) { fn2.Elements["/C0"] = new PdfLiteral("[" + PdfEncoders.ToString(clr0.ScA) + "]"); fn2.Elements["/C1"] = new PdfLiteral("[" + PdfEncoders.ToString(clr1.ScA) + "]"); fn2.Elements["/Range"] = new PdfLiteral("[0 1]"); } else { fn2.Elements["/C0"] = new PdfLiteral("[" + PdfEncoders.ToString(clr0, colorMode) + "]"); fn2.Elements["/C1"] = new PdfLiteral("[" + PdfEncoders.ToString(clr1, colorMode) + "]"); fn2.Elements["/Range"] = new PdfLiteral("[0 1 0 1 0 1]"); } fn2.Elements["/Domain"] = new PdfLiteral("[0 1]"); fn2.Elements["/N"] = new PdfInteger(1); fnarray.Elements.Add(fn2); if (idx > 1) { bounds.Append(' '); encode.Append(' '); } if (idx < count - 1) { bounds.Append(PdfEncoders.ToString(gradients[idx].Offset)); } encode.Append(reverse ? "1 0" : "0 1"); } bounds.Append(']'); encode.Append(']'); func.Elements["/Bounds"] = new PdfLiteral(bounds.ToString()); func.Elements["/Encode"] = new PdfLiteral(encode.ToString()); } else { #if true funcReverse = BuildShadingFunction3(gradients, softMask, colorMode); Context.PdfDocument.Internals.AddObject(funcReverse); func.Elements["/FunctionType"] = new PdfInteger(3); // Type 3 - Stitching Function func.Elements["/Domain"] = new PdfLiteral("[0 1]"); func.Elements["/Encode"] = new PdfLiteral("[1 0]"); func.Elements["/Bounds"] = new PdfLiteral("[]"); func.Elements["/Range"] = new PdfLiteral("[0 1 0 1 0 1]"); PdfArray fnarray0 = new PdfArray(); fnarray0.Elements.Add(funcReverse); func.Elements["/Functions"] = fnarray0; #else // // Build a Type 3 function with an array of n-1 Type 2 functions PdfDictionary fn1 = new PdfDictionary(); func.Elements["/FunctionType"] = new PdfInteger(3); // Type 3 - Stitching Function func.Elements["/Domain"] = new PdfLiteral("[0 1]"); func.Elements["/Encode"] = new PdfLiteral("[1 0]"); func.Elements["/Bounds"] = new PdfLiteral("[]"); func.Elements["/Range"] = new PdfLiteral("[0 1 0 1 0 1]"); PdfArray fnarray0 = new PdfArray(); fnarray0.Elements.Add(fn1); func.Elements["/Functions"] = fnarray0; fn1.Elements["/FunctionType"] = new PdfInteger(3); // Type 3 - Stitching Function fn1.Elements["/Domain"] = new PdfLiteral("[0 1]"); fn1.Elements["/Range"] = new PdfLiteral("[0 1 0 1 0 1]"); PdfArray fnarray = new PdfArray(); fn1.Elements["/Functions"] = fnarray; StringBuilder bounds = new StringBuilder("["); StringBuilder encode = new StringBuilder("["); for (int idx = 1; idx < count; idx++) { PdfDictionary fn2 = new PdfDictionary(); fn2.Elements["/FunctionType"] = new PdfInteger(2); Color clr0 = gradients[idx - 1].Color; Color clr1 = gradients[idx].Color; if (softMask) { fn2.Elements["/C0"] = new PdfLiteral("[" + PdfEncoders.ToString(clr0.ScA) + "]"); fn2.Elements["/C1"] = new PdfLiteral("[" + PdfEncoders.ToString(clr1.ScA) + "]"); fn2.Elements["/Range"] = new PdfLiteral("[0 1]"); } else { fn2.Elements["/C0"] = new PdfLiteral("[" + PdfEncoders.ToString(clr0, colorMode) + "]"); fn2.Elements["/C1"] = new PdfLiteral("[" + PdfEncoders.ToString(clr1, colorMode) + "]"); fn2.Elements["/Range"] = new PdfLiteral("[0 1 0 1 0 1]"); } fn2.Elements["/Domain"] = new PdfLiteral("[0 1]"); fn2.Elements["/N"] = new PdfInteger(1); //this.renderer.Owner.Internals.AddObject(fn2); //fnarray.Elements.Add(fn2.Reference); fnarray.Elements.Add(fn2); if (idx > 1) { bounds.Append(' '); encode.Append(' '); } if (idx < count - 1) { bounds.Append(PdfEncoders.ToString(gradients[idx].Offset)); } encode.Append("0 1"); } bounds.Append(']'); encode.Append(']'); fn1.Elements["/Bounds"] = new PdfLiteral(bounds.ToString()); fn1.Elements["/Encode"] = new PdfLiteral(encode.ToString()); #endif } return(func); }
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); }
void RealizeStrokeStyle(Path path) { if (this.realizedLineCap != (int)path.StrokeStartLineCap) { // HACK: Set Triangle to Square int[] pdfValue = { 0, 1, 2, 2 }; // Flat, Round, Square, Triangle, //int[] pdfValue = { 1, 1, 1, 1 }; // Flat, Round, Square, Triangle, int value = pdfValue[(int)path.StrokeStartLineCap]; this.writer.WriteLiteral("{0} J\n", value); this.realizedLineCap = value; } if (this.realizedLineJoin != (int)path.StrokeLineJoin) { int[] pdfValue = { 0, 2, 1 }; // Miter, Bevel, Round int value = pdfValue[(int)path.StrokeLineJoin]; this.writer.WriteLiteral("{0} j\n", value); this.realizedLineJoin = value; // TODO: Check implementation in PDFsharp PDF renderer! if (path.StrokeLineJoin == LineJoin.Miter) { if (this.realizedMiterLimit != path.StrokeMiterLimit && path.StrokeMiterLimit != 0) { this.writer.WriteLiteral("{0:0.##} M\n", path.StrokeMiterLimit); this.realizedMiterLimit = path.StrokeMiterLimit; } } } if (!String.IsNullOrEmpty(path.StrokeDashArray)) { string[] values = path.StrokeDashArray.Split(new char[] { ' ' }); int count = values.Length; double[] dashArray = new double[count]; for (int idx = 0; idx < count; idx++) { Double.TryParse(values[idx], NumberStyles.Float, CultureInfo.InvariantCulture, out dashArray[idx]); } // Line width 0 is not recommended but valid //XDashStyle dashStyle = pen.DashStyle; //if (dot == 0) // dashStyle = XDashStyle.Solid; double dot = path.StrokeThickness; double dash = 3 * path.StrokeThickness; if (dot > 0) { #if old //switch (dashStyle) //{ // case XDashStyle.Solid: // this.renderer.Append("[]0 d\n"); // break; // case XDashStyle.Dash: // this.renderer.AppendFormat("[{0:0.##} {1:0.##}]0 d\n", dash, dot); // break; // case XDashStyle.Dot: // this.renderer.AppendFormat("[{0:0.##}]0 d\n", dot); // break; // case XDashStyle.DashDot: // this.renderer.AppendFormat("[{0:0.##} {1:0.##} {1:0.##} {1:0.##}]0 d\n", dash, dot); // break; // case XDashStyle.DashDotDot: // this.renderer.AppendFormat("[{0:0.##} {1:0.##} {1:0.##} {1:0.##} {1:0.##} {1:0.##}]0 d\n", dash, dot); // break; // case XDashStyle.Custom: // { // StringBuilder pdf = new StringBuilder("[", 256); // int len = pen.dashPattern == null ? 0 : pen.dashPattern.Length; // for (int idx = 0; idx < len; idx++) // { // if (idx > 0) // pdf.Append(' '); // pdf.Append(PdfEncoders.ToString(pen.dashPattern[idx] * pen.width)); // } // // Make an even number of values look like in GDI+ // if (len > 0 && len % 2 == 1) // { // pdf.Append(' '); // pdf.Append(PdfEncoders.ToString(0.2 * pen.width)); // } // pdf.AppendFormat(CultureInfo.InvariantCulture, "]{0:0.###} d\n", pen.dashOffset * pen.width); // string pattern = pdf.ToString(); // // BUG: [email protected] reported a realizing problem // // HACK: I romove the if clause // //if (this.realizedDashPattern != pattern) // { // this.realizedDashPattern = pattern; // this.renderer.Append(pattern); // } // } // break; //} //this.realizedDashStyle = dashStyle; #endif StringBuilder pdf = new StringBuilder("[", 256); for (int idx = 0; idx < count; idx++) { if (idx > 0) { pdf.Append(' '); } pdf.Append(PdfEncoders.ToString(dashArray[idx] * path.StrokeThickness)); } // TODO: ?? // Make an even number of values look like in GDI+ if (count > 0 && count % 2 == 1) { pdf.Append(' '); pdf.Append(PdfEncoders.ToString(0.2 * path.StrokeThickness)); } pdf.AppendFormat(CultureInfo.InvariantCulture, "]{0:0.###} d\n", path.StrokeDashOffset * path.StrokeThickness); string pattern = pdf.ToString(); //// BUG: [email protected] reported a realizing problem //// HACK: I romove the if clause ////if (this.realizedDashPattern != pattern) //{ // this.realizedDashPattern = pattern; this.writer.WriteLiteral(pattern); //} } } }
//[Obsolete] // 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 // } // } // [Obsolete] // 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 // } // } //void RealizeImageBrush(ImageBrush brush, XForm xform) //{ //} //void RealizeVisualBrush(VisualBrush brush, XForm xform) //{ //} /// <summary> /// Builds the shading function of the specified gradient stop collection. /// </summary> PdfDictionary BuildShadingFunction(GradientStopCollection gradients, PdfColorMode colorMode) { bool softMask = this.writer.renderMode == RenderMode.SoftMask; PdfDictionary func = new PdfDictionary(); int count = gradients.Count; Debug.Assert(count >= 2); if (count == 2) { // Build one Type 2 function func.Elements["/FunctionType"] = new PdfInteger(2); // Type 2 - Exponential Interpolation Function Color clr0 = gradients[0].Color; Color clr1 = gradients[1].Color; if (softMask) { clr0 = Utils.AlphaToGray(clr0); clr1 = Utils.AlphaToGray(clr1); } func.Elements["/C0"] = new PdfLiteral("[" + PdfEncoders.ToString(clr0, colorMode) + "]"); func.Elements["/C1"] = new PdfLiteral("[" + PdfEncoders.ToString(clr1, colorMode) + "]"); func.Elements["/Domain"] = new PdfLiteral("[0 1]"); func.Elements["/N"] = new PdfInteger(1); // be linear } else { // Build a Type 3 function with an array of n-1 Type 2 functions func.Elements["/FunctionType"] = new PdfInteger(3); // Type 3 - Stitching Function func.Elements["/Domain"] = new PdfLiteral("[0 1]"); PdfArray fnarray = new PdfArray(); func.Elements["/Functions"] = fnarray; StringBuilder bounds = new StringBuilder("["); StringBuilder encode = new StringBuilder("["); for (int idx = 1; idx < count; idx++) { PdfDictionary fn2 = new PdfDictionary(); fn2.Elements["/FunctionType"] = new PdfInteger(2); Color clr0 = gradients[idx - 1].Color; Color clr1 = gradients[idx].Color; if (softMask) { clr0 = Utils.AlphaToGray(clr0); clr1 = Utils.AlphaToGray(clr1); } fn2.Elements["/C0"] = new PdfLiteral("[" + PdfEncoders.ToString(clr0, colorMode) + "]"); fn2.Elements["/C1"] = new PdfLiteral("[" + PdfEncoders.ToString(clr1, colorMode) + "]"); fn2.Elements["/Domain"] = new PdfLiteral("[0 1]"); fn2.Elements["/N"] = new PdfInteger(1); //this.renderer.Owner.Internals.AddObject(fn2); //fnarray.Elements.Add(fn2.Reference); fnarray.Elements.Add(fn2); if (idx > 1) { bounds.Append(' '); encode.Append(' '); } if (idx < count - 1) { bounds.Append(PdfEncoders.ToString(gradients[idx].Offset)); } encode.Append("0 1"); } bounds.Append(']'); //encode.Append(" 0 1"); encode.Append(']'); func.Elements["/Bounds"] = new PdfLiteral(bounds.ToString()); func.Elements["/Encode"] = new PdfLiteral(encode.ToString()); } return(func); }
/// <summary> /// Setups the shading from the specified brush. /// </summary> public void SetupFromBrush(XLinearGradientBrush brush) { if (brush == null) { throw new ArgumentNullException("brush"); } PdfColorMode colorMode = this.document.Options.ColorMode; XColor color1 = ColorSpaceHelper.EnsureColorMode(colorMode, brush.color1); XColor color2 = ColorSpaceHelper.EnsureColorMode(colorMode, brush.color2); PdfDictionary function = new PdfDictionary(); Elements[Keys.ShadingType] = new PdfInteger(2); if (colorMode != PdfColorMode.Cmyk) { Elements[Keys.ColorSpace] = new PdfName("/DeviceRGB"); } else { Elements[Keys.ColorSpace] = new PdfName("/DeviceCMYK"); } double x1 = 0, y1 = 0, x2 = 0, y2 = 0; if (brush.useRect) { switch (brush.linearGradientMode) { case XLinearGradientMode.Horizontal: x1 = brush.rect.x; y1 = brush.rect.y; x2 = brush.rect.x + brush.rect.width; y2 = brush.rect.y; break; case XLinearGradientMode.Vertical: x1 = brush.rect.x; y1 = brush.rect.y; x2 = brush.rect.x; y2 = brush.rect.y + brush.rect.height; break; case XLinearGradientMode.ForwardDiagonal: x1 = brush.rect.x; y1 = brush.rect.y; x2 = brush.rect.x + brush.rect.width; y2 = brush.rect.y + brush.rect.height; break; case XLinearGradientMode.BackwardDiagonal: x1 = brush.rect.x + brush.rect.width; y1 = brush.rect.y; x2 = brush.rect.x; y2 = brush.rect.y + brush.rect.height; break; } } else { x1 = brush.point1.x; y1 = brush.point1.y; x2 = brush.point2.x; y2 = brush.point2.y; } Elements[Keys.Coords] = new PdfLiteral("[{0:0.###} {1:0.###} {2:0.###} {3:0.###}]", x1, y1, x2, y2); //Elements[Keys.Background] = new PdfRawItem("[0 1 1]"); //Elements[Keys.Domain] = Elements[Keys.Function] = function; //Elements[Keys.Extend] = new PdfRawItem("[true true]"); string clr1 = "[" + PdfEncoders.ToString(color1, colorMode) + "]"; string clr2 = "[" + PdfEncoders.ToString(color2, colorMode) + "]"; function.Elements["/FunctionType"] = new PdfInteger(2); function.Elements["/C0"] = new PdfLiteral(clr1); function.Elements["/C1"] = new PdfLiteral(clr2); function.Elements["/Domain"] = new PdfLiteral("[0 1]"); function.Elements["/N"] = new PdfInteger(1); }
/// <summary> /// Creates key/values pairs according to the object structure. /// </summary> internal override void PrepareForSave() { bool hasKids = HasChildren; // Is something to do at all? if (_parent != null || hasKids) { if (_parent == null) { // Case: This is the outline dictionary (the root). // Reference: TABLE 8.3 Entries in the outline dictionary / Page 585 Debug.Assert(_outlines != null && _outlines.Count > 0 && _outlines[0] != null); Elements[Keys.First] = _outlines[0].Reference; Elements[Keys.Last] = _outlines[_outlines.Count - 1].Reference; // TODO: /Count - the meaning is not completely clear to me. // Get PDFs created with Acrobat and analyze what to implement. if (OpenCount > 0) { Elements[Keys.Count] = new PdfInteger(OpenCount); } } else { // Case: This is an outline item dictionary. // Reference: TABLE 8.4 Entries in the outline item dictionary / Page 585 Elements[Keys.Parent] = _parent.Reference; int count = _parent._outlines.Count; int index = _parent._outlines.IndexOf(this); Debug.Assert(index != -1); // Has destination? if (DestinationPage != null) { Elements[Keys.Dest] = CreateDestArray(); } // Not the first element? if (index > 0) { Elements[Keys.Prev] = _parent._outlines[index - 1].Reference; } // Not the last element? if (index < count - 1) { Elements[Keys.Next] = _parent._outlines[index + 1].Reference; } if (hasKids) { Elements[Keys.First] = _outlines[0].Reference; Elements[Keys.Last] = _outlines[_outlines.Count - 1].Reference; } // TODO: /Count - the meaning is not completely clear to me if (OpenCount > 0) { Elements[Keys.Count] = new PdfInteger((_opened ? 1 : -1) * OpenCount); } if (_textColor != XColor.Empty && Owner.HasVersion("1.4")) { Elements[Keys.C] = new PdfLiteral("[{0}]", PdfEncoders.ToString(_textColor, PdfColorMode.Rgb)); } // if (Style != PdfOutlineStyle.Regular && Document.HasVersion("1.4")) // //pdf.AppendFormat("/F {0}\n", (int)_style); // Elements[Keys.F] = new PdfInteger((int)_style); } // Prepare child elements. if (hasKids) { foreach (PdfOutline outline in _outlines) { outline.PrepareForSave(); } } } }
public void WriteMatrix(XMatrix matrix) { WriteIndent(); this.content.Append(PdfEncoders.ToString(matrix) + " cm\n"); }
public void RealizePen(XPen pen, PdfColorMode colorMode) { XColor color = pen.Color; color = ColorSpaceHelper.EnsureColorMode(colorMode, color); if (realizedLineWith != pen.width) { renderer.AppendFormat("{0:0.###} w\n", pen.width); realizedLineWith = pen.width; } if (realizedLineCap != (int)pen.lineCap) { renderer.AppendFormat("{0} J\n", (int)pen.lineCap); realizedLineCap = (int)pen.lineCap; } if (realizedLineJoin != (int)pen.lineJoin) { renderer.AppendFormat("{0} j\n", (int)pen.lineJoin); realizedLineJoin = (int)pen.lineJoin; } if (realizedLineCap == (int)XLineJoin.Miter) { if (realizedMiterLimit != (int)pen.miterLimit && (int)pen.miterLimit != 0) { renderer.AppendFormat("{0} M\n", (int)pen.miterLimit); realizedMiterLimit = (int)pen.miterLimit; } } if (realizedDashStyle != pen.dashStyle || pen.dashStyle == XDashStyle.Custom) { double dot = pen.Width; double dash = 3 * dot; // Line width 0 is not recommended but valid XDashStyle dashStyle = pen.DashStyle; if (dot == 0) { dashStyle = XDashStyle.Solid; } switch (dashStyle) { case XDashStyle.Solid: renderer.Append("[]0 d\n"); break; case XDashStyle.Dash: renderer.AppendFormat("[{0:0.##} {1:0.##}]0 d\n", dash, dot); break; case XDashStyle.Dot: renderer.AppendFormat("[{0:0.##}]0 d\n", dot); break; case XDashStyle.DashDot: renderer.AppendFormat("[{0:0.##} {1:0.##} {1:0.##} {1:0.##}]0 d\n", dash, dot); break; case XDashStyle.DashDotDot: renderer.AppendFormat("[{0:0.##} {1:0.##} {1:0.##} {1:0.##} {1:0.##} {1:0.##}]0 d\n", dash, dot); break; case XDashStyle.Custom: { StringBuilder pdf = new StringBuilder("[", 256); int len = pen.dashPattern == null ? 0 : pen.dashPattern.Length; for (int idx = 0; idx < len; idx++) { if (idx > 0) { pdf.Append(' '); } pdf.Append(PdfEncoders.ToString(pen.dashPattern[idx] * pen.width)); } // Make an even number of values look like in GDI+ if (len > 0 && len % 2 == 1) { pdf.Append(' '); pdf.Append(PdfEncoders.ToString(0.2 * pen.width)); } pdf.AppendFormat(CultureInfo.InvariantCulture, "]{0:0.###} d\n", pen.dashOffset * pen.width); string pattern = pdf.ToString(); // BUG: [email protected] reported a realizing problem // HACK: I romove the if clause //if (this.realizedDashPattern != pattern) { realizedDashPattern = pattern; renderer.Append(pattern); } } break; } realizedDashStyle = dashStyle; } if (colorMode != PdfColorMode.Cmyk) { if (realizedStrokeColor.Rgb != color.Rgb) { renderer.Append(PdfEncoders.ToString(color, PdfColorMode.Rgb)); renderer.Append(" RG\n"); } } else { if (!ColorSpaceHelper.IsEqualCmyk(realizedStrokeColor, color)) { renderer.Append(PdfEncoders.ToString(color, PdfColorMode.Cmyk)); renderer.Append(" K\n"); } } if (renderer.Owner.Version >= 14 && realizedStrokeColor.A != color.A) { PdfExtGState extGState = renderer.Owner.ExtGStateTable.GetExtGStateStroke(color.A); string gs = renderer.Resources.AddExtGState(extGState); renderer.AppendFormat("{0} gs\n", gs); // Must create transparany group if (renderer.page != null && color.A < 1) { renderer.page.transparencyUsed = true; } } realizedStrokeColor = color; }