Пример #1
0
        /// <summary>
        /// Builds a shading pattern from an radial gradient brush.
        /// </summary>
        public static PdfShadingPattern BuildFromRadialGradientBrush(DocumentRenderingContext context, RadialGradientBrush brush, XRect boundingBox, XMatrix transform)
        {
            RadialShadingBuilder builder = new RadialShadingBuilder(context);
            PdfShadingPattern    pattern = builder.BuildPattern(brush, boundingBox, transform);

            return(pattern);
        }
 /// <summary>
 /// Builds a shading pattern from an radial gradient brush.
 /// </summary>
 public static PdfShadingPattern BuildFromRadialGradientBrush(DocumentRenderingContext context, RadialGradientBrush brush, XRect boundingBox, XMatrix transform)
 {
   RadialShadingBuilder builder = new RadialShadingBuilder(context);
   PdfShadingPattern pattern = builder.BuildPattern(brush, boundingBox, transform);
   return pattern;
 }
Пример #3
0
        /// <summary>
        /// Writes a Path to the content stream.
        /// </summary>
        private void WritePath(Path path)
        {
            if (WriteSingleLineStrokeWithSpecialCaps(path))
            {
                return;
            }

            WriteSaveState("begin Path", path.Name);

            // Transform also affects clipping and opacity mask
            if (path.RenderTransform != null && this.renderMode == RenderMode.Default)
            {
                MultiplyTransform(path.RenderTransform);
                WriteRenderTransform(path.RenderTransform);
            }

            if (path.Clip != null && this.renderMode == RenderMode.Default)
            {
                WriteClip(path.Clip);
            }

            if (path.Opacity < 1)
            {
                MultiplyOpacity(path.Opacity);
            }

            if (path.OpacityMask != null)
            {
                WriteOpacityMask(path.OpacityMask);
            }

            if (path.Fill == null)
            {
                if (path.Stroke != null)
                {
                    WriteStrokeGeometry(path);
                }
                else
                {
                    Debug.Assert(false, "??? Path with neither Stroke nor Fill encountered.");
                }
            }
            else
            {
                SolidColorBrush     sBrush;
                LinearGradientBrush lgBrush;
                RadialGradientBrush rgBrush;
                ImageBrush          iBrush;
                VisualBrush         vBrush;
                if ((sBrush = path.Fill as SolidColorBrush) != null)
                {
                    Color  color   = sBrush.Color;
                    double opacity = Opacity * color.ScA;
                    if (opacity < 1)
                    {
                        RealizeFillOpacity(opacity);
                    }

                    WriteRgb(color, " rg\n");

                    if (path.Stroke != null)
                    {
                        RealizeStroke(path);
                    }

                    WriteGeometry(path.Data);
                    WritePathFillStroke(path);
                }
                else if ((lgBrush = path.Fill as LinearGradientBrush) != null)
                {
                    // TODO: For better visual compatibility use a Shading Pattern if Opacity is not 1 and
                    // the Stroke Style is not solid. Acrobat 8 ignores this case.

                    PdfExtGState xgState = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();
                    xgState.SetDefault1();

                    double opacity = Opacity * lgBrush.Opacity;;
                    if (opacity < 1)
                    {
                        xgState.StrokeAlpha    = opacity;
                        xgState.NonStrokeAlpha = opacity;
                    }
                    RealizeExtGState(xgState);

                    // 1st draw fill
                    if (lgBrush.GradientStops.HasTransparency)
                    {
                        // Create a FormXObject with a soft mask
                        PdfFormXObject form   = LinearShadingBuilder.BuildFormFromLinearGradientBrush(Context, lgBrush, path.Data);
                        string         foName = Resources.AddForm(form);
                        WriteLiteral(foName + " Do\n");
                    }
                    else
                    {
                        // Create just a shading
                        PdfShading shading = LinearShadingBuilder.BuildShadingFromLinearGradientBrush(Context, lgBrush);
                        string     shName  = Resources.AddShading(shading);
                        WriteLiteral("q\n");
                        WriteClip(path.Data);
                        WriteLiteral("BX " + shName + " sh EX Q\n");
                    }

                    // 2nd draw stroke
                    if (path.Stroke != null)
                    {
                        WriteStrokeGeometry(path);
                    }
                }
                else if ((rgBrush = path.Fill as RadialGradientBrush) != null)
                {
                    PdfExtGState xgState = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();
                    xgState.SetDefault1();

                    double avGradientOpacity = rgBrush.GradientStops.GetAverageAlpha(); // HACK
                    double opacity           = Opacity * rgBrush.Opacity * avGradientOpacity;
                    if (opacity < 1)
                    {
                        xgState.StrokeAlpha    = opacity;
                        xgState.NonStrokeAlpha = opacity;
                    }
                    //RealizeExtGState(xgState);

                    XRect boundingBox = path.Data.GetBoundingBox();
                    // Always creates a pattern, because the background must be filled
                    PdfShadingPattern pattern = RadialShadingBuilder.BuildFromRadialGradientBrush(Context, rgBrush, boundingBox, Transform);
                    string            paName  = Resources.AddPattern(pattern);

                    // stream
                    // /CS0 cs /P0 scn
                    // /GS0 gs
                    // 0 480 180 -90 re
                    // f*
                    // endstream
                    // endobj
                    WriteLiteral("/Pattern cs " + paName + " scn\n");
                    // move to here: RealizeExtGState(xgState);
                    RealizeExtGState(xgState);
                    WriteGeometry(path.Data);
                    if (path.Data.FillRule == FillRule.NonZero) // NonZero means Winding
                    {
                        WriteLiteral("f\n");
                    }
                    else
                    {
                        WriteLiteral("f*\n");
                    }

                    // 2nd draw stroke
                    if (path.Stroke != null)
                    {
                        WriteStrokeGeometry(path);
                    }
                }
                else if ((iBrush = path.Fill as ImageBrush) != null)
                {
                    PdfExtGState xgState = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();
                    xgState.SetDefault1();

                    double opacity = Opacity * iBrush.Opacity;
                    if (opacity <= 1)
                    {
                        xgState.StrokeAlpha    = opacity;
                        xgState.NonStrokeAlpha = opacity;
                    }
                    RealizeExtGState(xgState);

                    // 1st draw fill
                    PdfTilingPattern pattern = TilingPatternBuilder.BuildFromImageBrush(Context, iBrush, Transform);
                    string           name    = Resources.AddPattern(pattern);

                    WriteLiteral("/Pattern cs " + name + " scn\n");
                    WriteGeometry(path.Data);
                    WritePathFillStroke(path);

                    // 2nd draw stroke
                    if (path.Stroke != null)
                    {
                        WriteStrokeGeometry(path);
                    }
                }
                else if ((vBrush = path.Fill as VisualBrush) != null)
                {
                    PdfExtGState xgState = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();
                    xgState.SetDefault1();

                    double opacity = Opacity * vBrush.Opacity;
                    if (opacity < 1)
                    {
                        xgState.StrokeAlpha    = opacity;
                        xgState.NonStrokeAlpha = opacity;
                    }
                    RealizeExtGState(xgState);

                    // 1st draw fill
                    PdfTilingPattern pattern = TilingPatternBuilder.BuildFromVisualBrush(Context, vBrush, Transform);
                    string           name    = Resources.AddPattern(pattern);

                    WriteLiteral("/Pattern cs " + name + " scn\n");
                    WriteGeometry(path.Data);
                    WritePathFillStroke(path);

                    // 2nd draw stroke
                    if (path.Stroke != null)
                    {
                        WriteStrokeGeometry(path);
                    }
                }
                else
                {
                    Debug.Assert(false, "Unknown brush type encountered.");
                }
            }
            WriteRestoreState("end Path", path.Name);
        }