/// <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); }
/// <summary> /// Used to execute performance test run for memory profiler so the form is not loaded, /// only html container is working. /// </summary> public static void Run(bool layout, bool paint) { try { LoadRunSamples(); var htmlContainer = new HtmlContainer(); htmlContainer.MaxSize = new SizeF(800, 0); GC.Collect(); Thread.Sleep(3000); using (var img = new Bitmap(1, 1)) using (var g = Graphics.FromImage(img)) { for (int i = 0; i < Iterations; i++) { foreach (var html in _perfTestSamples) { htmlContainer.SetHtml(html); if (layout) htmlContainer.PerformLayout(g); if (paint) htmlContainer.PerformPaint(g); } } } } catch (Exception ex) { MessageBox.Show(ex.ToString(), "Error"); } }
/// <summary> /// On tooltip appear set the html by the associated control, layout and set the tooltip size by the html size. /// </summary> protected virtual void OnToolTipPopup(PopupEventArgs e) { //Create fragment container var cssClass = string.IsNullOrEmpty(_tooltipCssClass) ? null : string.Format(" class=\"{0}\"", _tooltipCssClass); var toolipHtml = string.Format("<div{0}>{1}</div>", cssClass, GetToolTip(e.AssociatedControl)); _htmlContainer.SetHtml(toolipHtml, _baseCssData); _htmlContainer.MaxSize = MaximumSize; //Measure size of the container using (var g = e.AssociatedControl.CreateGraphics()) { g.TextRenderingHint = _textRenderingHint; _htmlContainer.PerformLayout(g); } //Set the size of the tooltip var desiredWidth = (int)Math.Ceiling(MaximumSize.Width > 0 ? Math.Min(_htmlContainer.ActualSize.Width, MaximumSize.Width) : _htmlContainer.ActualSize.Width); var desiredHeight = (int)Math.Ceiling(MaximumSize.Height > 0 ? Math.Min(_htmlContainer.ActualSize.Height, MaximumSize.Height) : _htmlContainer.ActualSize.Height); e.ToolTipSize = new Size(desiredWidth, desiredHeight); #if !MONO // start mouse handle timer if (_allowLinksHandling) { _associatedControl = e.AssociatedControl; _linkHandlingTimer.Start(); } #endif }
/// <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); } }
/// <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); } }
/// <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; }
/// <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; } }
/// <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; } }