Esempio n. 1
0
        private Image GetImage(RectangleF bounds)
        {
            _patternElement.PatternBounds = new SvgRect(bounds.X, bounds.Y, bounds.Width, bounds.Height);

            // For single image pattern...
            if (_patternElement.ChildNodes.Count == 1)
            {
                var imageElement = _patternElement.ChildNodes[0] as SvgImageElement;
                if (imageElement != null)
                {
                    var image = GdiImageRendering.GetBitmap(imageElement);
                    if (image != null)
                    {
                        return(image);
                    }
                }
            }

            GdiGraphicsRenderer renderer = new GdiGraphicsRenderer(true, false);
            var svgWindow   = _patternElement.OwnerDocument.Window as SvgWindow;
            var ownedWindow = svgWindow.CreateOwnedWindow();

            renderer.Window = ownedWindow;

            SvgSvgElement elm = MoveIntoSvgElement();

            int winWidth  = (int)elm.Width.BaseVal.Value;
            int winHeight = (int)elm.Height.BaseVal.Value;

            if (winWidth == 0 || winHeight == 0)
            {
                var size = elm.GetSize();
                if (size.Width.Equals(0) || size.Height.Equals(0))
                {
                    winWidth  = (int)bounds.Width;
                    winHeight = (int)bounds.Height;
                }
                else
                {
                    winWidth  = (int)size.Width;
                    winHeight = (int)size.Height;
                }
            }

            ownedWindow.Resize(winWidth, winHeight);

            renderer.Render(elm as SvgElement);
            Image img = renderer.RasterImage;

            MoveOutOfSvgElement(elm);

            return(img);
        }
Esempio n. 2
0
        private void InvalidateAndRender()
        {
            try
            {
                if (_svgRenderer != null)
                {
                    SvgSvgElement svgEl = (SvgSvgElement)_svgWindow.Document.RootElement;

                    SvgSizeF r = svgEl.GetSize();

                    int winWidth  = (int)svgEl.Width.BaseVal.Value;
                    int winHeight = (int)svgEl.Height.BaseVal.Value;

                    if (!r.Width.Equals(0.0) && !r.Height.Equals(0.0) && (r.Width * 4 * r.Height) < BitmapLimit)
                    {
                        winWidth  = (int)r.Width;
                        winHeight = (int)r.Height;
                    }
                    if ((winWidth * 4 * winHeight) >= BitmapLimit)
                    {
                        winWidth  = this.Width;
                        winHeight = this.Height;
                    }

                    _svgWindow.Resize(winWidth, winHeight);

                    _svgRenderer.Render(_svgWindow.Document as SvgDocument);
                }
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());

                if (this.DesignMode)
                {
                    return;
                }

                var errorArgs = new SvgErrorArgs("An exception occurred while rendering", ex);
                _svgErrors?.Invoke(this, errorArgs);
                if (!errorArgs.Handled)
                {
                    MessageBox.Show(errorArgs.Message + ": " + ex.Message,
                                    _appTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
Esempio n. 3
0
        protected virtual void Load()
        {
            try
            {
                if (!string.IsNullOrWhiteSpace(_svgSource))
                {
                    // Load the source
                    _svgWindow.Source = _svgSource;
                    // Initialize the style sheets
                    SetupStyleSheets();
                    // Execute all script elements
                    //UnloadEngines();
                    //InitializeEvents();
                    //ExecuteScripts();

                    SvgSvgElement svgEl = (SvgSvgElement)_svgWindow.Document.RootElement;
                    SvgSizeF      r     = svgEl.GetSize();

                    int winWidth  = (int)svgEl.Width.BaseVal.Value;
                    int winHeight = (int)svgEl.Height.BaseVal.Value;
                    if (!r.Width.Equals(0.0) && !r.Height.Equals(0.0) && (r.Width * 4 * r.Height) < BitmapLimit)
                    {
                        winWidth  = (int)r.Width;
                        winHeight = (int)r.Height;
                    }
                    if ((winWidth * 4 * winHeight) >= BitmapLimit)
                    {
                        winWidth  = this.Width;
                        winHeight = this.Height;
                    }

                    _svgWindow.Resize(winWidth, winHeight);

                    _svgRenderer.InvalidRect = SvgRectF.Empty;

                    this.Render();
                    _isSvgLoaded = true;
                }
                else if (!string.IsNullOrWhiteSpace(_xmlSource) && _xmlSource.Length > ValidSVG.Length)
                {
                    SvgDocument doc = _svgWindow.CreateEmptySvgDocument();
                    doc.LoadXml(_xmlSource);
                    _svgWindow.Document = doc;

                    SetupStyleSheets();

                    SvgSvgElement svgEl = (SvgSvgElement)_svgWindow.Document.RootElement;
                    SvgSizeF      r     = svgEl.GetSize();

                    int winWidth  = (int)svgEl.Width.BaseVal.Value;
                    int winHeight = (int)svgEl.Height.BaseVal.Value;
                    if (!r.Width.Equals(0.0) && !r.Height.Equals(0.0) && (r.Width * 4 * r.Height) < BitmapLimit)
                    {
                        winWidth  = (int)r.Width;
                        winHeight = (int)r.Height;
                    }
                    if ((winWidth * 4 * winHeight) >= BitmapLimit)
                    {
                        winWidth  = this.Width;
                        winHeight = this.Height;
                    }
                    _svgWindow.Resize(winWidth, winHeight);

                    _svgRenderer.InvalidRect = SvgRectF.Empty;

                    this.Render();
                    _isSvgLoaded = true;
                }
                else if (_uriSource != null)
                {
                    // Load the source
                    _svgWindow.Source = _uriSource.AbsoluteUri;
                    // Initialize the style sheets
                    SetupStyleSheets();
                    // Execute all script elements
                    //UnloadEngines();
                    //InitializeEvents();
                    //ExecuteScripts();

                    SvgSvgElement svgEl = (SvgSvgElement)_svgWindow.Document.RootElement;
                    SvgSizeF      r     = svgEl.GetSize();

                    int winWidth  = (int)svgEl.Width.BaseVal.Value;
                    int winHeight = (int)svgEl.Height.BaseVal.Value;
                    if (!r.Width.Equals(0.0) && !r.Height.Equals(0.0) && (r.Width * 4 * r.Height) < BitmapLimit)
                    {
                        winWidth  = (int)r.Width;
                        winHeight = (int)r.Height;
                    }
                    if ((winWidth * 4 * winHeight) >= BitmapLimit)
                    {
                        winWidth  = this.Width;
                        winHeight = this.Height;
                    }

                    _svgWindow.Resize(winWidth, winHeight);

                    _svgRenderer.InvalidRect = SvgRectF.Empty;

                    this.Render();
                    _isSvgLoaded = true;
                }
                else if (_streamSource != null)
                {
                    SvgDocument doc = _svgWindow.CreateEmptySvgDocument();
                    doc.Load(_streamSource);
                    _svgWindow.Document = doc;

                    SetupStyleSheets();

                    SvgSvgElement svgEl = (SvgSvgElement)_svgWindow.Document.RootElement;
                    SvgSizeF      r     = svgEl.GetSize();

                    int winWidth  = (int)svgEl.Width.BaseVal.Value;
                    int winHeight = (int)svgEl.Height.BaseVal.Value;
                    if (!r.Width.Equals(0.0) && !r.Height.Equals(0.0) && (r.Width * 4 * r.Height) < BitmapLimit)
                    {
                        winWidth  = (int)r.Width;
                        winHeight = (int)r.Height;
                    }
                    if ((winWidth * 4 * winHeight) >= BitmapLimit)
                    {
                        winWidth  = this.Width;
                        winHeight = this.Height;
                    }

                    _svgWindow.Resize(winWidth, winHeight);

                    _svgRenderer.InvalidRect = SvgRectF.Empty;

                    this.Render();
                    _isSvgLoaded = true;
                }
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());

                if (this.DesignMode)
                {
                    return;
                }
                var errorArgs = new SvgErrorArgs("An error occurred while loading the document", ex);
                _svgErrors?.Invoke(this, errorArgs);
                if (!errorArgs.Handled)
                {
                    MessageBox.Show(errorArgs.Message + ": " + ex.Message,
                                    _appTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
        public override void Render(GdiGraphicsRenderer renderer)
        {
            base.Render(renderer);

            var             graphics = renderer.GdiGraphics;
            SvgImageElement iElement = (SvgImageElement)_svgElement;

            ImageAttributes imageAttributes = new ImageAttributes();

            float opacityValue = -1;

            string opacity = iElement.GetAttribute("opacity");

            if (string.IsNullOrWhiteSpace(opacity))
            {
                opacity = iElement.GetPropertyValue("opacity");
            }
            if (!string.IsNullOrWhiteSpace(opacity))
            {
                opacityValue = (float)SvgNumber.ParseNumber(opacity);
                opacityValue = Math.Min(opacityValue, 1);
                opacityValue = Math.Max(opacityValue, 0);
            }

            if (opacityValue >= 0 && opacityValue < 1)
            {
                ColorMatrix colorMatrix = new ColorMatrix();
                colorMatrix.Matrix00 = 1.00f;                 // Red
                colorMatrix.Matrix11 = 1.00f;                 // Green
                colorMatrix.Matrix22 = 1.00f;                 // Blue
                colorMatrix.Matrix33 = opacityValue;          // alpha
                colorMatrix.Matrix44 = 1.00f;                 // w

                imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
            }

            float width  = (float)iElement.Width.AnimVal.Value;
            float height = (float)iElement.Height.AnimVal.Value;

            RectangleF destRect = new RectangleF((float)iElement.X.AnimVal.Value,
                                                 (float)iElement.Y.AnimVal.Value, (float)iElement.Width.AnimVal.Value,
                                                 (float)iElement.Height.AnimVal.Value);

            RectangleF srcRect;
            RectangleF clipRect = destRect;

//            var container = graphics.BeginContainer();
            graphics.SetClip(new Region(clipRect), CombineMode.Intersect);

            Image     image  = null;
            SvgWindow svgWnd = null;

            if (iElement.IsSvgImage)
            {
                svgWnd = GetSvgWindow(graphics);
                if (width > 0 && height > 0)
                {
                    srcRect = new RectangleF(0, 0, width, height);
                }
                else
                {
                    SvgSvgElement svgEl = (SvgSvgElement)svgWnd.Document.RootElement;

                    SvgSizeF size = svgEl.GetSize();

                    srcRect = new RectangleF(new PointF(0, 0), new SizeF(size.Width, size.Height));
                }
            }
            else
            {
                image = GetBitmap(iElement);
                if (image == null)
                {
                    return;
                }
                srcRect = new RectangleF(0, 0, image.Width, image.Height);
            }

            ISvgAnimatedPreserveAspectRatio animatedAspectRatio = iElement.PreserveAspectRatio;

            if (animatedAspectRatio != null && animatedAspectRatio.AnimVal != null)
            {
                SvgPreserveAspectRatio     aspectRatio     = animatedAspectRatio.AnimVal as SvgPreserveAspectRatio;
                SvgPreserveAspectRatioType aspectRatioType =
                    (aspectRatio != null) ? aspectRatio.Align : SvgPreserveAspectRatioType.Unknown;

                if (aspectRatio != null && aspectRatioType != SvgPreserveAspectRatioType.None &&
                    aspectRatioType != SvgPreserveAspectRatioType.Unknown)
                {
                    var fScaleX = destRect.Width / srcRect.Width;
                    var fScaleY = destRect.Height / srcRect.Height;
                    var xOffset = 0.0f;
                    var yOffset = 0.0f;

                    SvgMeetOrSlice meetOrSlice = aspectRatio.MeetOrSlice;
                    if (meetOrSlice == SvgMeetOrSlice.Slice)
                    {
                        fScaleX = Math.Max(fScaleX, fScaleY);
                        fScaleY = Math.Max(fScaleX, fScaleY);
                    }
                    else
                    {
                        fScaleX = Math.Min(fScaleX, fScaleY);
                        fScaleY = Math.Min(fScaleX, fScaleY);
                    }

                    switch (aspectRatioType)
                    {
                    case SvgPreserveAspectRatioType.XMinYMin:
                        break;

                    case SvgPreserveAspectRatioType.XMidYMin:
                        xOffset = (destRect.Width - srcRect.Width * fScaleX) / 2;
                        break;

                    case SvgPreserveAspectRatioType.XMaxYMin:
                        xOffset = (destRect.Width - srcRect.Width * fScaleX);
                        break;

                    case SvgPreserveAspectRatioType.XMinYMid:
                        yOffset = (destRect.Height - srcRect.Height * fScaleY) / 2;
                        break;

                    case SvgPreserveAspectRatioType.XMidYMid:
                        xOffset = (destRect.Width - srcRect.Width * fScaleX) / 2;
                        yOffset = (destRect.Height - srcRect.Height * fScaleY) / 2;
                        break;

                    case SvgPreserveAspectRatioType.XMaxYMid:
                        xOffset = (destRect.Width - srcRect.Width * fScaleX);
                        yOffset = (destRect.Height - srcRect.Height * fScaleY) / 2;
                        break;

                    case SvgPreserveAspectRatioType.XMinYMax:
                        yOffset = (destRect.Height - srcRect.Height * fScaleY);
                        break;

                    case SvgPreserveAspectRatioType.XMidYMax:
                        xOffset = (destRect.Width - srcRect.Width * fScaleX) / 2;
                        yOffset = (destRect.Height - srcRect.Height * fScaleY);
                        break;

                    case SvgPreserveAspectRatioType.XMaxYMax:
                        xOffset = (destRect.Width - srcRect.Width * fScaleX);
                        yOffset = (destRect.Height - srcRect.Height * fScaleY);
                        break;
                    }

                    destRect = new RectangleF(destRect.X + xOffset, destRect.Y + yOffset,
                                              srcRect.Width * fScaleX, srcRect.Height * fScaleY);
                }
                if (image != null)
                {
                    SvgColorProfileElement colorProfile = (SvgColorProfileElement)iElement.ColorProfile;
                    if (colorProfile != null)
                    {
                        SvgUriReference svgUri     = colorProfile.UriReference;
                        Uri             profileUri = new Uri(svgUri.AbsoluteUri);

                        imageAttributes.SetOutputChannelColorProfile(profileUri.LocalPath, ColorAdjustType.Default);
                    }

                    graphics.DrawImage(this, image, destRect, srcRect, GraphicsUnit.Pixel, imageAttributes);

                    image.Dispose();
                    image = null;
                }
                else if (iElement.IsSvgImage && svgWnd != null)
                {
                    svgWnd.Resize((int)srcRect.Width, (int)srcRect.Height);

                    var currOffset = new PointF(graphics.Transform.OffsetX, graphics.Transform.OffsetY);
                    if (!currOffset.IsEmpty)
                    {
                        graphics.TranslateTransform(-currOffset.X, -currOffset.Y);
                    }
                    graphics.ScaleTransform(destRect.Width / srcRect.Width, destRect.Height / srcRect.Height);
                    if (!currOffset.IsEmpty)
                    {
                        graphics.TranslateTransform(currOffset.X + destRect.X, currOffset.Y + destRect.Y);
                    }

                    _embeddedRenderer.Render(svgWnd.Document);
                }

                graphics.ResetClip();
//                graphics.EndContainer(container);
            }

            if (_embeddedRenderer != null)
            {
                _embeddedRenderer.GdiGraphics = null;
                _embeddedRenderer.Dispose();
                _embeddedRenderer = null;
            }

            if (imageAttributes != null)
            {
                imageAttributes.Dispose();
                imageAttributes = null;
            }
        }
        public static Image GetBitmap(SvgImageElement element)
        {
            var comparer = StringComparison.OrdinalIgnoreCase;

            if (!element.IsSvgImage)
            {
                if (!element.Href.AnimVal.StartsWith("data:", comparer))
                {
                    SvgUriReference svgUri   = element.UriReference;
                    Uri             imageUri = new Uri(svgUri.AbsoluteUri);
                    if (imageUri.IsFile && File.Exists(imageUri.LocalPath))
                    {
                        return(Image.FromFile(imageUri.LocalPath, element.ColorProfile != null));
                    }

                    WebResponse resource = svgUri.ReferencedResource;
                    if (resource == null)
                    {
                        return(null);
                    }

                    Stream stream = resource.GetResponseStream();
                    if (stream == null)
                    {
                        return(null);
                    }

                    return(Image.FromStream(stream, element.ColorProfile != null));
                }

                string sURI = element.Href.AnimVal.Replace(" ", "").Trim();
                sURI = sURI.Replace(@"\n", "");
                int nColon     = sURI.IndexOf(":", comparer);
                int nSemiColon = sURI.IndexOf(";", comparer);
                int nComma     = sURI.IndexOf(",", comparer);

                string sMimeType = sURI.Substring(nColon + 1, nSemiColon - nColon - 1);
                string sContent  = sURI.Substring(nComma + 1);

                sContent = sContent.Replace('-', '+').Replace('_', '/');
                sContent = sContent.PadRight(4 * ((sContent.Length + 3) / 4), '=');
                byte[] bResult = Convert.FromBase64CharArray(sContent.ToCharArray(),
                                                             0, sContent.Length);

                if (sMimeType.Equals("image/svg+xml", StringComparison.OrdinalIgnoreCase))
                {
                    GdiGraphicsRenderer renderer = new GdiGraphicsRenderer(true, false);

                    var currentWindow = element.OwnerDocument.Window as SvgWindow;
                    var svgWindow     = currentWindow.CreateOwnedWindow();
                    renderer.Window = svgWindow;

                    SvgDocument doc      = svgWindow.CreateEmptySvgDocument();
                    bool        isGZiped = sContent.StartsWith(GdiObject.GZipSignature, StringComparison.Ordinal);
                    if (isGZiped)
                    {
                        byte[] imageBytes = Convert.FromBase64CharArray(sContent.ToCharArray(),
                                                                        0, sContent.Length);
                        using (var stream = new MemoryStream(imageBytes))
                        {
                            using (GZipStream zipStream = new GZipStream(stream, CompressionMode.Decompress))
                            {
                                doc.Load(zipStream);
                            }
                        }
                    }
                    else
                    {
                        var svgData     = Convert.FromBase64String(Convert.ToBase64String(bResult));
                        var svgFragment = Encoding.ASCII.GetString(svgData);

                        doc.LoadXml(svgFragment);
                    }
                    svgWindow.Document = doc;

                    SvgSvgElement elm = (SvgSvgElement)doc.RootElement;

                    int winWidth  = (int)elm.Width.BaseVal.Value;
                    int winHeight = (int)elm.Height.BaseVal.Value;
                    if (winWidth == 0 || winHeight == 0)
                    {
                        var size = elm.GetSize();
                        winWidth  = (int)size.Width;
                        winHeight = (int)size.Height;
                    }

                    svgWindow.Resize(winWidth, winHeight);

                    renderer.Render(elm as SvgElement);
                    Image img = renderer.RasterImage;

                    return(img);
                }

                MemoryStream ms = new MemoryStream(bResult);
                return(Image.FromStream(ms, element.ColorProfile != null));
            }
            return(null);
        }