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);
                        }
                    }
                }
            }
        }