Exemple #1
0
        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);
        }
Exemple #2
0
        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;
            }
        }
Exemple #4
0
        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;
        }
Exemple #6
0
        /// <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) + "]"));
 }
Exemple #9
0
        /// <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);
        }
Exemple #10
0
        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);
        }
Exemple #13
0
        /// <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);
        }
Exemple #14
0
        /// <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");
 }
Exemple #16
0
        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;
        }