Low level handling of Html Renderer logic, this class is used by HtmlParser, HtmlLabel, HtmlToolTip and HtmlRender.
Inheritance: IDisposable
コード例 #1
0
ファイル: HtmlRender.cs プロジェクト: zhitian/3P
        /// <summary>
        /// Renders the specified HTML into a new image of unknown size that will be determined by min/max width/height and HTML layout.<br/>
        /// If <paramref name="maxSize.Width"/> is zero the html will use all the required width, otherwise it will perform line
        /// wrap as specified in the html<br/>
        /// If <paramref name="maxSize.Height"/> is zero the html will use all the required height, otherwise it will clip at the
        /// given max height not rendering the html below it.<br/>
        /// If <paramref name="minSize"/> (Width/Height) is above zero the rendered image will not be smaller than the given min size.<br/>
        /// The generated image have transparent background that the html is rendered on.<br/>
        /// GDI+ text rending can be controlled by providing <see cref="TextRenderingHint"/>.<br/>
        /// See "Rendering to image" remarks section on <see cref="HtmlRender"/>.<br/>
        /// </summary>
        /// <param name="html">HTML source to render</param>
        /// <param name="minSize">optional: the min size of the rendered html (zero - not limit the width/height)</param>
        /// <param name="maxSize">optional: the max size of the rendered html, if not zero and html cannot be layout within the limit it will be clipped (zero - not limit the width/height)</param>
        /// <param name="textRenderingHint">optional: (default - SingleBitPerPixelGridFit)</param>
        /// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
        /// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
        /// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
        /// <returns>the generated image of the html</returns>
        public static Image RenderToImageGdiPlus(string html, Size minSize, Size maxSize, TextRenderingHint textRenderingHint = TextRenderingHint.AntiAlias, CssData cssData = null,
                                                 EventHandler <HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler <HtmlImageLoadEventArgs> imageLoad           = null)
        {
            if (string.IsNullOrEmpty(html))
            {
                return(new Bitmap(0, 0, PixelFormat.Format32bppArgb));
            }

            using (var container = new HtmlContainer()) {
                container.AvoidAsyncImagesLoading = true;
                container.AvoidImagesLateLoading  = true;
                container.UseGdiPlusTextRendering = true;

                if (stylesheetLoad != null)
                {
                    container.StylesheetLoad += stylesheetLoad;
                }
                if (imageLoad != null)
                {
                    container.ImageLoad += imageLoad;
                }
                container.SetHtml(html, cssData);

                var finalSize = MeasureHtmlByRestrictions(container, minSize, maxSize);
                container.MaxSize = finalSize;

                // create the final image to render into by measured size
                var image = new Bitmap(finalSize.Width, finalSize.Height, PixelFormat.Format32bppArgb);

                // render HTML into the image
                using (var g = Graphics.FromImage(image)) {
                    g.TextRenderingHint = textRenderingHint;
                    container.PerformPaint(g);
                }

                return(image);
            }
        }
コード例 #2
0
ファイル: HtmlToolTip.cs プロジェクト: devjerome/3P
        /// <summary>
        /// Unsubscribe from events and dispose of <see cref="HtmlContainer"/>.
        /// </summary>
        protected virtual void OnToolTipDisposed(EventArgs e) {
            Popup -= OnToolTipPopup;
            Draw -= OnToolTipDraw;
            Disposed -= OnToolTipDisposed;

            if (HtmlContainer != null) {
                HtmlContainer.RenderError -= OnRenderError;
                HtmlContainer.StylesheetLoad -= OnStylesheetLoad;
                HtmlContainer.ImageLoad -= OnImageLoad;
                HtmlContainer.Dispose();
                HtmlContainer = null;
            }

#if !MONO
            if (_linkHandlingTimer != null) {
                _linkHandlingTimer.Dispose();
                _linkHandlingTimer = null;

                if (HtmlContainer != null)
                    HtmlContainer.LinkClicked -= OnLinkClicked;
            }
#endif
        }
コード例 #3
0
ファイル: HtmlToolTip.cs プロジェクト: jcaillon/3P
        /// <summary>
        /// Init.
        /// </summary>
        public HtmlToolTip()
        {
            OwnerDraw = true;

            HtmlContainer = new HtmlContainer();
            HtmlContainer.IsSelectionEnabled = false;
            HtmlContainer.IsContextMenuEnabled = false;
            HtmlContainer.AvoidGeometryAntialias = true;
            HtmlContainer.AvoidImagesLateLoading = true;
            HtmlContainer.RenderError += OnRenderError;
            HtmlContainer.StylesheetLoad += OnStylesheetLoad;
            HtmlContainer.ImageLoad += OnImageLoad;

            Popup += OnToolTipPopup;
            Draw += OnToolTipDraw;
            Disposed += OnToolTipDisposed;

            #if !MONO
            _linkHandlingTimer = new Timer();
            _linkHandlingTimer.Tick += OnLinkHandlingTimerTick;
            _linkHandlingTimer.Interval = 40;

            HtmlContainer.LinkClicked += OnLinkClicked;
            #endif
            AutoPopDelay = 90000;
            InitialDelay = 300;
        }
コード例 #4
0
ファイル: HtmlToolTip.cs プロジェクト: jcaillon/3P
        /// <summary>
        /// Unsubscribe from events and dispose of <see cref="HtmlContainer"/>.
        /// </summary>
        protected virtual void OnToolTipDisposed(EventArgs e)
        {
            Popup -= OnToolTipPopup;
            Draw -= OnToolTipDraw;
            Disposed -= OnToolTipDisposed;

            if (HtmlContainer != null) {
                HtmlContainer.RenderError -= OnRenderError;
                HtmlContainer.StylesheetLoad -= OnStylesheetLoad;
                HtmlContainer.ImageLoad -= OnImageLoad;
                HtmlContainer.Dispose();
                HtmlContainer = null;
            }

            #if !MONO
            if (_linkHandlingTimer != null) {
                _linkHandlingTimer.Dispose();
                _linkHandlingTimer = null;

                if (HtmlContainer != null)
                    HtmlContainer.LinkClicked -= OnLinkClicked;
            }
            #endif
        }
コード例 #5
0
ファイル: HtmlPanel.cs プロジェクト: jcaillon/YamuiFramework
 /// <summary>
 /// Release the html container resources.
 /// </summary>
 protected override void Dispose(bool disposing)
 {
     if (_htmlContainer != null)
     {
         _htmlContainer.LinkClicked -= OnLinkClicked;
         _htmlContainer.BoxClicked -= OnBoxClicked;
         _htmlContainer.RenderError -= OnRenderError;
         _htmlContainer.Refresh -= OnRefresh;
         _htmlContainer.ScrollChange -= OnScrollChange;
         _htmlContainer.StylesheetLoad -= OnStylesheetLoad;
         _htmlContainer.ImageLoad -= OnImageLoad;
         _htmlContainer.Dispose();
         _htmlContainer = null;
     }
     base.Dispose(disposing);
 }
コード例 #6
0
ファイル: HtmlPanel.cs プロジェクト: jcaillon/YamuiFramework
        /// <summary>
        /// Creates a new HtmlPanel and sets a basic css for it's styling.
        /// </summary>
        public HtmlPanel()
        {
            AutoScroll = true;
            BackColor = SystemColors.Window;
            DoubleBuffered = true;
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);

            _htmlContainer = new HtmlContainer();
            _htmlContainer.LinkClicked += OnLinkClicked;
            _htmlContainer.BoxClicked += OnBoxClicked;
            _htmlContainer.RenderError += OnRenderError;
            _htmlContainer.Refresh += OnRefresh;
            _htmlContainer.ScrollChange += OnScrollChange;
            _htmlContainer.StylesheetLoad += OnStylesheetLoad;
            _htmlContainer.ImageLoad += OnImageLoad;

            // subscribe to an event called when the BaseCss sheet changes
            YamuiThemeManager.OnCssSheetChanged += YamuiThemeManagerOnOnCssSheetChanged;
        }
コード例 #7
0
ファイル: HtmlLabel.cs プロジェクト: jcaillon/3P
        /// <summary>
        /// Creates a new HTML Label
        /// </summary>
        public HtmlLabel()
        {
            SuspendLayout();

            AutoSize = true;
            BackColor = SystemColors.Window;
            DoubleBuffered = true;
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            SetStyle(ControlStyles.Opaque, false);

            _htmlContainer = new HtmlContainer();
            _htmlContainer.AvoidImagesLateLoading = true;
            _htmlContainer.MaxSize = MaximumSize;
            _htmlContainer.LinkClicked += OnLinkClicked;
            _htmlContainer.RenderError += OnRenderError;
            _htmlContainer.Refresh += OnRefresh;
            _htmlContainer.StylesheetLoad += OnStylesheetLoad;
            _htmlContainer.ImageLoad += OnImageLoad;

            ResumeLayout(false);

            TabStop = false;

            // subscribe to an event called when the BaseCss sheet changes
            YamuiThemeManager.OnCssChanged += YamuiThemeManagerOnOnCssChanged;
        }
コード例 #8
0
ファイル: HtmlRender.cs プロジェクト: jcaillon/YamuiFramework
        /// <summary>
        /// Renders the specified HTML into a new image of unknown size that will be determined by min/max width/height and HTML layout.<br/>
        /// If <paramref name="maxSize.Width"/> is zero the html will use all the required width, otherwise it will perform line 
        /// wrap as specified in the html<br/>
        /// If <paramref name="maxSize.Height"/> is zero the html will use all the required height, otherwise it will clip at the
        /// given max height not rendering the html below it.<br/>
        /// If <paramref name="minSize"/> (Width/Height) is above zero the rendered image will not be smaller than the given min size.<br/>
        /// <p>
        /// Limitation: The image cannot have transparent background, by default it will be white.<br/>
        /// See "Rendering to image" remarks section on <see cref="HtmlRender"/>.<br/>
        /// </p>
        /// </summary>
        /// <param name="html">HTML source to render</param>
        /// <param name="minSize">optional: the min size of the rendered html (zero - not limit the width/height)</param>
        /// <param name="maxSize">optional: the max size of the rendered html, if not zero and html cannot be layout within the limit it will be clipped (zero - not limit the width/height)</param>
        /// <param name="backgroundColor">optional: the color to fill the image with (default - white)</param>
        /// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
        /// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
        /// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
        /// <returns>the generated image of the html</returns>
        /// <exception cref="ArgumentOutOfRangeException">if <paramref name="backgroundColor"/> is <see cref="Color.Transparent"/></exception>.
        public static Image RenderToImage(string html, Size minSize, Size maxSize, Color backgroundColor = new Color(), CssData cssData = null,
            EventHandler<HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler<HtmlImageLoadEventArgs> imageLoad = null)
        {
            if (backgroundColor == Color.Transparent)
                throw new ArgumentOutOfRangeException("backgroundColor", "Transparent background in not supported");

            if (string.IsNullOrEmpty(html))
                return new Bitmap(0, 0, PixelFormat.Format32bppArgb);

            using (var container = new HtmlContainer())
            {
                container.AvoidAsyncImagesLoading = true;
                container.AvoidImagesLateLoading = true;

                if (stylesheetLoad != null)
                    container.StylesheetLoad += stylesheetLoad;
                if (imageLoad != null)
                    container.ImageLoad += imageLoad;
                container.SetHtml(html, cssData);

                var finalSize = MeasureHtmlByRestrictions(container, minSize, maxSize);
                container.MaxSize = finalSize;

                // create the final image to render into by measured size
                var image = new Bitmap(finalSize.Width, finalSize.Height, PixelFormat.Format32bppArgb);

                // create memory buffer from desktop handle that supports alpha channel
                IntPtr dib;
                var memoryHdc = Win32Utils.CreateMemoryHdc(IntPtr.Zero, image.Width, image.Height, out dib);
                try
                {
                    // render HTML into the memory buffer
                    using (var memoryGraphics = Graphics.FromHdc(memoryHdc))
                    {
                        memoryGraphics.Clear(backgroundColor != Color.Empty ? backgroundColor : Color.White);
                        container.PerformPaint(memoryGraphics);
                    }

                    // copy from memory buffer to image
                    CopyBufferToImage(memoryHdc, image);
                }
                finally
                {
                    Win32Utils.ReleaseMemoryHdc(memoryHdc, dib);
                }

                return image;
            }
        }
コード例 #9
0
ファイル: HtmlRender.cs プロジェクト: jcaillon/YamuiFramework
        /// <summary>
        /// Renders the specified HTML source on the specified location and max size restriction.<br/>
        /// If <paramref name="maxSize"/>.Width is zero the html will use all the required width, otherwise it will perform line 
        /// wrap as specified in the html<br/>
        /// If <paramref name="maxSize"/>.Height is zero the html will use all the required height, otherwise it will clip at the
        /// given max height not rendering the html below it.<br/>
        /// Returned is the actual width and height of the rendered html.<br/>
        /// </summary>
        /// <param name="g">Device to render with</param>
        /// <param name="html">HTML source to render</param>
        /// <param name="location">the top-left most location to start render the html at</param>
        /// <param name="maxSize">the max size of the rendered html (if height above zero it will be clipped)</param>
        /// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
        /// <param name="useGdiPlusTextRendering">true - use GDI+ text rendering, false - use GDI text rendering</param>
        /// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
        /// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
        /// <returns>the actual size of the rendered html</returns>
        private static SizeF RenderHtml(Graphics g, string html, PointF location, SizeF maxSize, CssData cssData, bool useGdiPlusTextRendering, EventHandler<HtmlStylesheetLoadEventArgs> stylesheetLoad, EventHandler<HtmlImageLoadEventArgs> imageLoad)
        {
            SizeF actualSize = SizeF.Empty;

            if (!string.IsNullOrEmpty(html))
            {
                using (var container = new HtmlContainer())
                {
                    container.Location = location;
                    container.MaxSize = maxSize;
                    container.AvoidAsyncImagesLoading = true;
                    container.AvoidImagesLateLoading = true;
                    container.UseGdiPlusTextRendering = useGdiPlusTextRendering;

                    if (stylesheetLoad != null)
                        container.StylesheetLoad += stylesheetLoad;
                    if (imageLoad != null)
                        container.ImageLoad += imageLoad;

                    container.SetHtml(html, cssData);
                    container.PerformLayout(g);
                    container.PerformPaint(g);

                    actualSize = container.ActualSize;
                }
            }

            return actualSize;
        }
コード例 #10
0
ファイル: HtmlRender.cs プロジェクト: jcaillon/YamuiFramework
 /// <summary>
 /// Measure the size of the html by performing layout under the given restrictions.
 /// </summary>
 /// <param name="htmlContainer">the html to calculate the layout for</param>
 /// <param name="minSize">the minimal size of the rendered html (zero - not limit the width/height)</param>
 /// <param name="maxSize">the maximum size of the rendered html, if not zero and html cannot be layout within the limit it will be clipped (zero - not limit the width/height)</param>
 /// <returns>return: the size of the html to be rendered within the min/max limits</returns>
 private static Size MeasureHtmlByRestrictions(HtmlContainer htmlContainer, Size minSize, Size maxSize)
 {
     // use desktop created graphics to measure the HTML
     using (var g = Graphics.FromHwnd(IntPtr.Zero))
     using (var mg = new GraphicsAdapter(g, htmlContainer.UseGdiPlusTextRendering))
     {
         var sizeInt = HtmlRendererUtils.MeasureHtmlByRestrictions(mg, htmlContainer.HtmlContainerInt, Utils.Convert(minSize), Utils.Convert(maxSize));
         return Utils.ConvertRound(sizeInt);
     }
 }
コード例 #11
0
ファイル: HtmlRender.cs プロジェクト: jcaillon/YamuiFramework
        /// <summary>
        /// Renders the specified HTML into a new image of unknown size that will be determined by min/max width/height and HTML layout.<br/>
        /// If <paramref name="maxSize.Width"/> is zero the html will use all the required width, otherwise it will perform line 
        /// wrap as specified in the html<br/>
        /// If <paramref name="maxSize.Height"/> is zero the html will use all the required height, otherwise it will clip at the
        /// given max height not rendering the html below it.<br/>
        /// If <paramref name="minSize"/> (Width/Height) is above zero the rendered image will not be smaller than the given min size.<br/>
        /// The generated image have transparent background that the html is rendered on.<br/>
        /// GDI+ text rending can be controlled by providing <see cref="TextRenderingHint"/>.<br/>
        /// See "Rendering to image" remarks section on <see cref="HtmlRender"/>.<br/>
        /// </summary>
        /// <param name="html">HTML source to render</param>
        /// <param name="minSize">optional: the min size of the rendered html (zero - not limit the width/height)</param>
        /// <param name="maxSize">optional: the max size of the rendered html, if not zero and html cannot be layout within the limit it will be clipped (zero - not limit the width/height)</param>
        /// <param name="textRenderingHint">optional: (default - SingleBitPerPixelGridFit)</param>
        /// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
        /// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
        /// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
        /// <returns>the generated image of the html</returns>
        public static Image RenderToImageGdiPlus(string html, Size minSize, Size maxSize, TextRenderingHint textRenderingHint = TextRenderingHint.AntiAlias, CssData cssData = null,
            EventHandler<HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler<HtmlImageLoadEventArgs> imageLoad = null)
        {
            if (string.IsNullOrEmpty(html))
                return new Bitmap(0, 0, PixelFormat.Format32bppArgb);

            using (var container = new HtmlContainer())
            {
                container.AvoidAsyncImagesLoading = true;
                container.AvoidImagesLateLoading = true;
                container.UseGdiPlusTextRendering = true;

                if (stylesheetLoad != null)
                    container.StylesheetLoad += stylesheetLoad;
                if (imageLoad != null)
                    container.ImageLoad += imageLoad;
                container.SetHtml(html, cssData);

                var finalSize = MeasureHtmlByRestrictions(container, minSize, maxSize);
                container.MaxSize = finalSize;

                // create the final image to render into by measured size
                var image = new Bitmap(finalSize.Width, finalSize.Height, PixelFormat.Format32bppArgb);

                // render HTML into the image
                using (var g = Graphics.FromImage(image))
                {
                    g.TextRenderingHint = textRenderingHint;
                    container.PerformPaint(g);
                }

                return image;
            }
        }