public RendererResult Render(Input input) { #pragma warning disable CS0420 // A reference to a volatile field will not be treated as volatile var cacheInfo = new HtmlRendererCache.Info( input.Content, input.Foreground, input.Background, input.Font, input.ZoomScale * ExtensionSettings.Instance.CustomZoomScale, CacheVersion); if (cache.TryGetImage(cacheInfo, out rendererResult)) { return(rendererResult.Value); } #pragma warning restore CS0420 // A reference to a volatile field will not be treated as volatile documentCompleted = false; mathJaxRenderingDone = false; objectForScripting.ClearErrors(); rendererResult = null; webBrowser.DocumentText = GetHtmlSource(input); currentContent = input.Content; //wait until document is loaded while (!documentCompleted) { Thread.Sleep(WaitingIntervalMs); } RenderInternal(input); //wait until result image is ready while (!rendererResult.HasValue) { Thread.Sleep(WaitingIntervalMs); } return(rendererResult.Value); }
private unsafe void RenderInternal(Input input) { if (webBrowser.InvokeRequired) { //wait until MathJax is done with rendering while (!mathJaxRenderingDone) { Thread.Sleep(WaitingIntervalMs); } webBrowser.Invoke(new Action <Input>(RenderInternal), input); } else { webBrowser.Width = (int)(input.ZoomScale * ExtensionSettings.Instance.CustomZoomScale * DefaultBrowserWidth); webBrowser.Height = (int)(input.ZoomScale * ExtensionSettings.Instance.CustomZoomScale * DefaultBrowserHeight); const int ExtraMargin = 4; var myDiv = webBrowser.Document.GetElementById("myDiv"); var width = (myDiv.OffsetRectangle.X + myDiv.ScrollRectangle.Width) + ExtraMargin; var height = (myDiv.OffsetRectangle.Y + myDiv.ScrollRectangle.Height) + ExtraMargin; webBrowser.Width = width; webBrowser.Height = height; webBrowser.Document.BackColor = Color.Transparent; const PixelFormat pixelFormat = PixelFormat.Format32bppArgb; using (var bitmap = new Bitmap(width, height, pixelFormat)) { if (webBrowser.Document.DomDocument is IViewObject viewObject) { var webBrowserRectangle = new TagRECT(myDiv.OffsetRectangle); var bitmapRectangle = new TagRECT(0, 0, width, height); using (var gr = Graphics.FromImage(bitmap)) { var hdc = gr.GetHdc(); try { int hr = viewObject.Draw(1 /*DVASPECT_CONTENT*/, -1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, hdc, ref bitmapRectangle, ref webBrowserRectangle, IntPtr.Zero, 0); } finally { gr.ReleaseHdc(); } } var background = BGRA.From(input.Background); using (var croppedBitmap = CropToContent(bitmap, background)) { MakeBackgroundTransparent(croppedBitmap, background); var bitmapSource = ResourcesManager.CreateBitmapSourceWithCurrentDpi(croppedBitmap); var cacheInfo = new HtmlRendererCache.Info( currentContent, input.Foreground, input.Background, input.Font, input.ZoomScale * ExtensionSettings.Instance.CustomZoomScale, CacheVersion); var errors = objectForScripting.Errors.Count == 0 ? Array.Empty <string>() : objectForScripting.Errors.ToArray(); var cachedImagePath = errors.Length == 0 ? cache.Add(cacheInfo, croppedBitmap) : null; rendererResult = new RendererResult(bitmapSource, cachedImagePath, errors); } } } } }