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);
        }
        internal override void WriteObject(PdfWriter writer)
        {
            PdfPage dest = null;

            //pdf.AppendFormat(CultureInfo.InvariantCulture,
            //  "{0} 0 obj\n<<\n/Type/Annot\n/Subtype/Link\n" +
            //  "/Rect[{1} {2} {3} {4}]\n/BS<</Type/Border>>\n/Border[0 0 0]\n/C[0 0 0]\n",
            //  ObjectID.ObjectNumber, rect.X1, rect.Y1, rect.X2, rect.Y2);

            // Older Adobe Reader versions uses a border width of 0 as default value if neither Border nor BS are present.
            // But the PDF Reference specifies:
            // "If neither the Border nor the BS entry is present, the border is drawn as a solid line with a width of 1 point."
            // After this issue was fixed in newer Reader versions older PDFsharp created documents show an ugly solid border.
            // The following hack fixes this by specifying a 0 width border.
            if (Elements[PdfAnnotation.Keys.BS] == null)
            {
                Elements[PdfAnnotation.Keys.BS] = new PdfLiteral("<</Type/Border/W 0>>");
            }

            // May be superfluous. See comment above.
            if (Elements[PdfAnnotation.Keys.Border] == null)
            {
                Elements[PdfAnnotation.Keys.Border] = new PdfLiteral("[0 0 0]");
            }

            switch (_linkType)
            {
            case LinkType.None:
                break;

            case LinkType.Document:
                // destIndex > Owner.PageCount can happen when rendering pages using PDFsharp directly.
                int destIndex = _destPage;
                if (destIndex > Owner.PageCount)
                {
                    destIndex = Owner.PageCount;
                }
                destIndex--;
                dest = Owner.Pages[destIndex];
                //pdf.AppendFormat("/Dest[{0} 0 R/XYZ null null 0]\n", dest.ObjectID);
                Elements[Keys.Dest] = new PdfLiteral("[{0} 0 R/XYZ null null 0]", dest.ObjectNumber);
                break;

            case LinkType.Web:
                //pdf.AppendFormat("/A<</S/URI/URI{0}>>\n", PdfEncoders.EncodeAsLiteral(url));
                Elements[PdfAnnotation.Keys.A] = new PdfLiteral("<</S/URI/URI{0}>>",     //PdfEncoders.EncodeAsLiteral(url));
                                                                PdfEncoders.ToStringLiteral(_url, PdfStringEncoding.WinAnsiEncoding, writer.SecurityHandler));
                break;

            case LinkType.File:
                //pdf.AppendFormat("/A<</Type/Action/S/Launch/F<</Type/Filespec/F{0}>> >>\n",
                //  PdfEncoders.EncodeAsLiteral(url));
                Elements[PdfAnnotation.Keys.A] = new PdfLiteral("<</Type/Action/S/Launch/F<</Type/Filespec/F{0}>> >>",
                                                                //PdfEncoders.EncodeAsLiteral(url));
                                                                PdfEncoders.ToStringLiteral(_url, PdfStringEncoding.WinAnsiEncoding, writer.SecurityHandler));
                break;
            }
            base.WriteObject(writer);
        }
Exemple #3
0
        public void Write(PdfRectangle rect)
        {
            const string format = Config.SignificantFigures3;

            WriteSeparator(CharCat.Delimiter, '/');
            WriteRaw(PdfEncoders.Format("[{0:" + format + "} {1:" + format + "} {2:" + format + "} {3:" + format + "}]", rect.X1, rect.Y1, rect.X2, rect.Y2));
            _lastCat = CharCat.Delimiter;
        }
Exemple #4
0
 public void WriteDocStringHex(string text)
 {
     WriteSeparator(CharCat.Delimiter);
     //WriteRaw(PdfEncoders.DocEncodeHex(text));
     byte[] bytes = PdfEncoders.DocEncoding.GetBytes(text);
     bytes = PdfEncoders.FormatStringLiteral(bytes, false, false, true, _securityHandler);
     _stream.Write(bytes, 0, bytes.Length);
     _lastCat = CharCat.Delimiter;
 }
Exemple #5
0
 public void WriteDocString(string text)
 {
     WriteSeparator(CharCat.Delimiter);
     //WriteRaw(PdfEncoders.DocEncode(text, false));
     byte[] bytes = PdfEncoders.DocEncoding.GetBytes(text);
     bytes = PdfEncoders.FormatStringLiteral(bytes, false, false, false, _securityHandler);
     Write(bytes);
     _lastCat = CharCat.Delimiter;
 }
Exemple #6
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);
        }
Exemple #7
0
        /// <summary>
        /// Writes the specified value to the PDF stream.
        /// </summary>
        public void Write(PdfString value)
        {
            WriteSeparator(CharCat.Delimiter);
            PdfStringEncoding encoding = (PdfStringEncoding)(value.Flags & PdfStringFlags.EncodingMask);
            string            pdf      = (value.Flags & PdfStringFlags.HexLiteral) == 0 ?
                                         PdfEncoders.ToStringLiteral(value.Value, encoding, SecurityHandler) :
                                         PdfEncoders.ToHexStringLiteral(value.Value, encoding, SecurityHandler);

            WriteRaw(pdf);
            _lastCat = CharCat.Delimiter;
        }
        /// <summary>
        /// Returns the string.
        /// </summary>
        public override string ToString()
        {
#if true
            PdfStringEncoding encoding = (PdfStringEncoding)(_flags & PdfStringFlags.EncodingMask);
            string            pdf      = (_flags & PdfStringFlags.HexLiteral) == 0 ?
                                         PdfEncoders.ToStringLiteral(_value, encoding, null) :
                                         PdfEncoders.ToHexStringLiteral(_value, encoding, null);
            return(pdf);
#else
            return(_value);
#endif
        }
Exemple #9
0
        /// <summary>
        /// Writes the specified value to the PDF stream.
        /// </summary>
        public void Write(PdfString value)
        {
            WriteSeparator(CharCat.Delimiter);
#if true
            PdfStringEncoding encoding = (PdfStringEncoding)(value.Flags & PdfStringFlags.EncodingMask);
            string            pdf;
            if ((value.Flags & PdfStringFlags.HexLiteral) == 0)
            {
                pdf = PdfEncoders.ToStringLiteral(value.Value, encoding, SecurityHandler);
            }
            else
            {
                pdf = PdfEncoders.ToHexStringLiteral(value.Value, encoding, SecurityHandler);
            }
            WriteRaw(pdf);
#else
            switch (value.Flags & PdfStringFlags.EncodingMask)
            {
            case PdfStringFlags.Undefined:
            case PdfStringFlags.PDFDocEncoding:
                if ((value.Flags & PdfStringFlags.HexLiteral) == 0)
                {
                    WriteRaw(PdfEncoders.DocEncode(value.Value, false));
                }
                else
                {
                    WriteRaw(PdfEncoders.DocEncodeHex(value.Value, false));
                }
                break;

            case PdfStringFlags.WinAnsiEncoding:
                throw new NotImplementedException("Unexpected encoding: WinAnsiEncoding");

            case PdfStringFlags.Unicode:
                if ((value.Flags & PdfStringFlags.HexLiteral) == 0)
                {
                    WriteRaw(PdfEncoders.DocEncode(value.Value, true));
                }
                else
                {
                    WriteRaw(PdfEncoders.DocEncodeHex(value.Value, true));
                }
                break;

            case PdfStringFlags.StandardEncoding:
            case PdfStringFlags.MacRomanEncoding:
            case PdfStringFlags.MacExpertEncoding:
            default:
                throw new NotImplementedException("Unexpected encoding");
            }
#endif
            this.lastCat = CharCat.Delimiter;
        }
Exemple #10
0
        private static string Format(string format, params double?[] values)
        {
            int length = values.Length;

            object[] objValues = new object[length];
            for (int i = 0; i < length; i++)
            {
                objValues[i] = values[i] ?? (object)"null";
            }

            return(PdfEncoders.Format(format, objValues));
        }
        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;
            }
        }
        internal override void WriteObject(PdfWriter writer)
        {
            PdfPage dest = null;

            //pdf.AppendFormat(CultureInfo.InvariantCulture,
            //  "{0} 0 obj\n<<\n/Type/Annot\n/Subtype/Link\n" +
            //  "/Rect[{1} {2} {3} {4}]\n/BS<</Type/Border>>\n/Border[0 0 0]\n/C[0 0 0]\n",
            //  this.ObjectID.ObjectNumber, rect.X1, rect.Y1, rect.X2, rect.Y2);

            if (Elements[Keys.BS] == null)
            {
                Elements[Keys.BS] = new PdfLiteral("<</Type/Border>>");
            }

            if (Elements[Keys.Border] == null)
            {
                Elements[Keys.Border] = new PdfLiteral("[0 0 0]");
            }

            switch (this.linkType)
            {
            case LinkType.Document:
                // destIndex > Owner.PageCount can happen rendering pages using PDFsharp directly
                int destIndex = this.destPage;
                if (destIndex > Owner.PageCount)
                {
                    destIndex = Owner.PageCount;
                }
                destIndex--;
                dest = this.Owner.Pages[destIndex];
                //pdf.AppendFormat("/Dest[{0} 0 R/XYZ null null 0]\n", dest.ObjectID);
                Elements[Keys.Dest] = new PdfLiteral("[{0} 0 R/XYZ null null 0]", dest.ObjectNumber);
                break;

            case LinkType.Web:
                //pdf.AppendFormat("/A<</S/URI/URI{0}>>\n", PdfEncoders.EncodeAsLiteral(this.url));
                Elements[Keys.A] = new PdfLiteral("<</S/URI/URI{0}>>", //PdfEncoders.EncodeAsLiteral(this.url));
                                                  PdfEncoders.ToStringLiteral(this.url, PdfStringEncoding.WinAnsiEncoding, writer.SecurityHandler));
                break;

            case LinkType.File:
                //pdf.AppendFormat("/A<</Type/Action/S/Launch/F<</Type/Filespec/F{0}>> >>\n",
                //  PdfEncoders.EncodeAsLiteral(this.url));
                Elements[Keys.A] = new PdfLiteral("<</Type/Action/S/Launch/F<</Type/Filespec/F{0}>> >>",
                                                  //PdfEncoders.EncodeAsLiteral(this.url));
                                                  PdfEncoders.ToStringLiteral(this.url, PdfStringEncoding.WinAnsiEncoding, writer.SecurityHandler));
                break;
            }
            base.WriteObject(writer);
        }
Exemple #13
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;
        }
Exemple #14
0
 public void WriteDocString(string text, bool unicode)
 {
     WriteSeparator(CharCat.Delimiter);
     //WriteRaw(PdfEncoders.DocEncode(text, unicode));
     byte[] bytes;
     if (!unicode)
     {
         bytes = PdfEncoders.DocEncoding.GetBytes(text);
     }
     else
     {
         bytes = PdfEncoders.UnicodeEncoding.GetBytes(text);
     }
     bytes = PdfEncoders.FormatStringLiteral(bytes, unicode, true, false, _securityHandler);
     Write(bytes);
     _lastCat = CharCat.Delimiter;
 }
Exemple #15
0
        /// <summary>
        /// Writes the specified value to the PDF stream.
        /// </summary>
        public void Write(PdfString value)
        {
            WriteSeparator(CharCat.Delimiter);
//#if true
            PdfStringEncoding encoding = (PdfStringEncoding)(value.Flags & PdfStringFlags.EncodingMask);
            string            pdf      = (value.Flags & PdfStringFlags.HexLiteral) == 0 ?
                                         PdfEncoders.ToStringLiteral(value.Value, encoding, SecurityHandler) :
                                         PdfEncoders.ToHexStringLiteral(value.Value, encoding, SecurityHandler);

            WriteRaw(pdf);
//#else
//            switch (value.Flags & PdfStringFlags.EncodingMask)
//            {
//                case PdfStringFlags.Undefined:
//                case PdfStringFlags.PDFDocEncoding:
//                    if ((value.Flags & PdfStringFlags.HexLiteral) == 0)
//                        WriteRaw(PdfEncoders.DocEncode(value.Value, false));
//                    else
//                        WriteRaw(PdfEncoders.DocEncodeHex(value.Value, false));
//                    break;

//                case PdfStringFlags.WinAnsiEncoding:
//                    throw new NotImplementedException("Unexpected encoding: WinAnsiEncoding");

//                case PdfStringFlags.Unicode:
//                    if ((value.Flags & PdfStringFlags.HexLiteral) == 0)
//                        WriteRaw(PdfEncoders.DocEncode(value.Value, true));
//                    else
//                        WriteRaw(PdfEncoders.DocEncodeHex(value.Value, true));
//                    break;

//                case PdfStringFlags.StandardEncoding:
//                case PdfStringFlags.MacRomanEncoding:
//                case PdfStringFlags.MacExpertEncoding:
//                default:
//                    throw new NotImplementedException("Unexpected encoding");
//            }
//#endif
            _lastCat = CharCat.Delimiter;
        }
        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>
 /// Initializes a new instance with the culture invariant formatted specified arguments.
 /// </summary>
 public PdfLiteral(string format, params object[] args)
 {
     _value = PdfEncoders.Format(format, args);
 }
Exemple #18
0
 public void Write(PdfRectangle rect)
 {
     WriteSeparator(CharCat.Delimiter, '/');
     WriteRaw(PdfEncoders.Format("[{0:0.###} {1:0.###} {2:0.###} {3:0.###}]", rect.X1, rect.Y1, rect.X2, rect.Y2));
     this.lastCat = CharCat.Delimiter;
 }
        /// <summary>
        /// Returns the rectangle as a string in the form «[x1 y1 x2 y2]».
        /// </summary>
        public override string ToString()
        {
            const string format = Config.SignificantFigures3;

            return(PdfEncoders.Format("[{0:" + format + "} {1:" + format + "} {2:" + format + "} {3:" + format + "}]", _x1, _y1, _x2, _y2));
        }
Exemple #20
0
 /// <summary>
 /// Returns the rectangle as a string in the form «[x1 y1 x2 y2]».
 /// </summary>
 public override string ToString()
 {
     return(PdfEncoders.Format("[{0:0.###} {1:0.###} {2:0.###} {3:0.###}]", this.x1, this.y1, this.x2, this.y2));
 }
        /// <summary>
        /// Writes a Glyphs to the content stream.
        /// </summary>
        private void WriteGlyphs(Glyphs glyphs)
        {
            WriteSaveState("begin Glyphs", glyphs.Name);

            // Transform also affects clipping and opacity mask
            bool transformed = glyphs.RenderTransform != null;

            if (transformed)
            {
                WriteRenderTransform(glyphs.RenderTransform);
            }

            bool clipped = glyphs.Clip != null;

            if (clipped)
            {
                WriteClip(glyphs.Clip);
            }

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

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

            XMatrix textMatrix = new XMatrix();

            textMatrix.TranslatePrepend(glyphs.OriginX, glyphs.OriginY);
            glyphs.OriginX = glyphs.OriginY = 0; // HACK: do not change model

            double emSize = glyphs.FontRenderingEmSize;

            textMatrix.ScalePrepend(glyphs.FontRenderingEmSize);
            glyphs.FontRenderingEmSize = 1; // HACK: do not change model


            bool boldSimulation = (glyphs.StyleSimulations & StyleSimulations.BoldSimulation) == StyleSimulations.BoldSimulation;

            // just a draft...
            if (boldSimulation)
            {
                boldSimulation = true;

                // draw black stroke if it is not a solid color brush
                XColor color = XColor.FromArgb(0, 0, 0);
                if (glyphs.Fill is SolidColorBrush)
                {
                    SolidColorBrush brush = glyphs.Fill as SolidColorBrush;
                    color = brush.Color;
                }
                WriteLiteral(String.Format(CultureInfo.InvariantCulture, "{0:0.###} {1:0.###} {2:0.###}  RG\n", color.R / 255.0, color.G / 255.0, color.B / 255.0));
                WriteLiteral("{0:0.###} w\n", emSize / 50);
            }

            if ((glyphs.StyleSimulations & StyleSimulations.ItalicSimulation) == StyleSimulations.ItalicSimulation)
            {
                textMatrix.SkewPrepend(-20, 0);
            }

            XForm  xform  = null;
            XImage ximage = null;

            RealizeFill(glyphs.Fill, ref xform, ref ximage);
            RealizeFont(glyphs);

            if (boldSimulation)
            {
                WriteLiteral("2 Tr\n", 1);
            }

            double x = glyphs.OriginX;
            double y = glyphs.OriginY;


            //switch (format.Alignment)
            //{
            //  case XStringAlignment.Near:
            //    // nothing to do
            //    break;

            //  case XStringAlignment.Center:
            //    x += (rect.Width - width) / 2;
            //    break;

            //  case XStringAlignment.Far:
            //    x += rect.Width - width;
            //    break;
            //}

            PdfFont realizedFont = this.graphicsState.realizedFont;

            Debug.Assert(realizedFont != null);
            realizedFont.AddChars(glyphs.UnicodeString);

            OpenTypeDescriptor descriptor = realizedFont.FontDescriptor._descriptor;

            //if (bold && !descriptor.IsBoldFace)
            //{
            //  // TODO: emulate bold by thicker outline
            //}

            //if (italic && !descriptor.IsBoldFace)
            //{
            //  // TODO: emulate italic by shearing transformation
            //}

#if true
            string s2 = "";
            string s  = glyphs.UnicodeString;
            if (!String.IsNullOrEmpty(s))
            {
                int length = s.Length;
                for (int idx = 0; idx < length; idx++)
                {
                    char ch      = s[idx];
                    int  glyphID = 0;
                    if (descriptor.FontFace.cmap.symbol)
                    {
                        glyphID = (int)ch + (descriptor.FontFace.os2.usFirstCharIndex & 0xFF00);
                        glyphID = descriptor.CharCodeToGlyphIndex((char)glyphID);
                    }
                    else
                    {
                        glyphID = descriptor.CharCodeToGlyphIndex(ch);
                    }
                    s2 += (char)glyphID;
                }
            }
            s = s2;
#endif

            byte[] bytes = PdfEncoders.RawUnicodeEncoding.GetBytes(s);
            bytes = PdfEncoders.FormatStringLiteral(bytes, true, false, true, null);
            string text = PdfEncoders.RawEncoding.GetString(bytes);
            if (glyphs.IsSideways)
            {
                textMatrix.RotateAtPrepend(-90, new XPoint(x, y));
                XPoint pos = new XPoint(x, y);
                AdjustTextMatrix(ref pos);
                //WriteTextTransform(textMatrix);
                WriteLiteral("{0} Tj\n", text);
            }
            else
            {
#if true
                //if (glyphs.BidiLevel % 2 == 1)
                //  WriteLiteral("-1 Tc\n");

                if (!textMatrix.IsIdentity)
                {
                    WriteTextTransform(textMatrix);
                }

                WriteGlyphsInternal(glyphs, null);
#else
                XPoint pos = new XPoint(x, y);
                AdjustTextMatrix(ref pos);
                WriteLiteral("{0:0.###} {1:0.###} Td {2} Tj\n", pos.x, pos.y, text);
                //PdfEncoders.ToStringLiteral(s, PdfStringEncoding.RawEncoding, null));
#endif
            }
            WriteRestoreState("end Glyphs", glyphs.Name);
        }
        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>
        /// This is just a draft to see what to do in detail.
        /// </summary>
        private void WriteGlyphs_ClusterMapping(Glyphs glyphs)
        {
            string unicodeString = glyphs.UnicodeString;

#if DEBUG_
            if (!String.IsNullOrEmpty(unicodeString))
            {
                if (unicodeString.StartsWith("abc"))
                {
                    GetType();
                }
            }
#endif

            bool   boldSimulation       = (glyphs.StyleSimulations & StyleSimulations.BoldSimulation) == StyleSimulations.BoldSimulation;
            double boldSimulationFactor = 1;
            if (boldSimulation)
            {
                boldSimulationFactor = 1;
            }

            bool RightToLeft = glyphs.BidiLevel % 2 == 1; // TODOWPF: why is this a level?? what means "bidirectional nesting"?

            GlyphIndices indices = glyphs.Indices;
            if (indices == null)
            {
                indices = new GlyphIndices();
            }
            int  codeIdx    = 0;
            int  codeCount  = String.IsNullOrEmpty(unicodeString) ? 0 : unicodeString.Length;
            int  glyphCount = indices.Count;
            int  glyphIdx   = 0;
            bool stop       = false;

            PdfFont            realizedFont = this.graphicsState.realizedFont;
            OpenTypeDescriptor descriptor   = realizedFont.FontDescriptor._descriptor;
            int glyphIndex;

            double x       = glyphs.OriginX;
            double y       = glyphs.OriginY;
            XPoint pos     = new XPoint(x, y); // accumulation may lead to rounding error -> check it!
            double uOffset = 0;
            double vOffset = 0;

            StringBuilder outputText       = new StringBuilder();
            double        accumulatedWidth = 0;
            int           outputGlyphCount = 0;
            bool          mustRender       = false;
            bool          hasOffset        = false;

            do
            {
                GlyphIndices.GlyphMapping clusterMapping = new GlyphIndices.GlyphMapping(42);
                if (glyphIdx < glyphCount)
                {
                    clusterMapping = indices[glyphIdx];
                }

                for (int clusterGlyphIdx = 0; clusterGlyphIdx < clusterMapping.ClusterGlyphCount; clusterGlyphIdx++)
                {
                    GlyphIndices.GlyphMapping mapping = new GlyphIndices.GlyphMapping(42);
                    if (glyphIdx + clusterGlyphIdx < glyphCount)
                    {
                        mapping = indices[glyphIdx + clusterGlyphIdx];
                    }

                    Debug.Assert(mustRender == false);

                    // Determine whether to render accumulated glyphs
                    if (outputGlyphCount > 0 && (hasOffset || mapping.HasAdvanceWidthOrOffset))
                    {
                        outputText.Append('>');

                        WriteLiteral("{0:0.####} {1:0.####} Td {2}Tj\n", pos.X, pos.Y, outputText.ToString());

                        //double width = descriptor.GlyphIndexToPdfWidth(glyphIndex);
                        //if (!PdfSharp.Internal.DoubleUtil.IsNaN(mapping.AdvanceWidth))
                        //  width = mapping.AdvanceWidth * 10;
                        //pos = new XPoint(accumulatedWidth + width / 1000 * glyphs.FontRenderingEmSize, 0);
                        pos = new XPoint(accumulatedWidth, 0);

                        // reset values
                        accumulatedWidth  = 0;
                        outputGlyphCount  = 0;
                        outputText.Length = 0;
                        mustRender        = false;
                    }

                    mustRender = mapping.HasAdvanceWidth;
                    //mustRender = true;

                    // Adjust former uOffset
                    if (uOffset != 0)
                    {
                        pos.X     -= uOffset;
                        uOffset    = 0;
                        mustRender = true;
                    }

                    // Adjust position by current former uOffset
                    if (mapping.HasUOffset)
                    {
                        uOffset    = mapping.UOffset * glyphs.FontRenderingEmSize / 100;
                        pos.X     += uOffset;
                        mustRender = true;
                        hasOffset  = true;
                    }

                    // Adjust former vOffset
                    if (vOffset != 0)
                    {
                        pos.Y     += vOffset;
                        vOffset    = 0;
                        mustRender = true;
                    }

                    // Adjust position by current former vOffset
                    if (mapping.HasVOffset)
                    {
                        vOffset    = mapping.VOffset * glyphs.FontRenderingEmSize / 100;
                        pos.Y     -= vOffset;
                        mustRender = true;
                        hasOffset  = true;
                    }


                    // get index of current glyph
                    if (mapping.HasGlyphIndex)
                    {
                        glyphIndex = mapping.GlyphIndex;
                    }
                    else
                    {
                        glyphIndex = descriptor.CharCodeToGlyphIndex(unicodeString[codeIdx]);
                    }

                    // add glyph index to the fonts 'used glyph table'
                    realizedFont.AddGlyphIndices(new string((char)glyphIndex, 1));

#if true
                    if (outputGlyphCount == 0)
                    {
                        outputText.Append('<');
                    }
                    outputText.AppendFormat("{0:X2}{1:X2}", (byte)(glyphIndex >> 8), (byte)glyphIndex);
#else
                    byte[] bytes = new byte[2] {
                        (byte)(glyphIndex >> 8), (byte)glyphIndex
                    };
                    bytes = PdfEncoders.FormatStringLiteral(bytes, true, false, true, null);
                    string output = PdfEncoders.RawEncoding.GetString(bytes);
#endif

                    // At the end of the glyph run we must always render
                    if (!mustRender)
                    {
                        mustRender = codeIdx + clusterMapping.ClusterCodeUnitCount >= codeCount && // is it the last code unit cluster
                                     glyphIdx + clusterGlyphIdx + 1 >= glyphCount; // is it the last glyph index
                    }
                    //mustRender = true;
                    if (mustRender)
                    {
                        outputText.Append('>');

                        WriteLiteral("{0:0.####} {1:0.####} Td {2}Tj\n", pos.X, pos.Y, outputText.ToString());

                        double width = descriptor.GlyphIndexToPdfWidth(glyphIndex);
                        if (!PdfSharp.Internal.DoubleUtil.IsNaN(mapping.AdvanceWidth))
                        {
                            width = mapping.AdvanceWidth * 10;
                        }
                        pos = new XPoint(accumulatedWidth + width * boldSimulationFactor / 1000 * glyphs.FontRenderingEmSize, 0);

                        // reset values
                        accumulatedWidth  = 0;
                        outputGlyphCount  = 0;
                        outputText.Length = 0;
                        mustRender        = false;
                    }
                    else // deferred rendering
                    {
                        // accumulate width
                        Debug.Assert(DoubleUtil.IsNaN(mapping.AdvanceWidth));
                        double width = descriptor.GlyphIndexToPdfWidth(glyphIndex);
                        width             = width * boldSimulationFactor / 1000 * glyphs.FontRenderingEmSize;
                        accumulatedWidth += width;

                        outputGlyphCount++;
                    }
                }
                codeIdx  += clusterMapping.ClusterCodeUnitCount;
                glyphIdx += clusterMapping.ClusterGlyphCount;

                if (codeIdx >= codeCount && glyphIdx >= glyphCount)
                {
                    stop = true;
                }
            }while (!stop);
        }
Exemple #25
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 #26
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);
        }
        //[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);
        }
        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);
                    //}
                }
            }
        }
Exemple #29
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);
        }
Exemple #30
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);
        }