public async Task <List <Annotation> > GetAnnotationsAsync(int pageNumber)
        {
            string annotationJSON = await chromePage.EvaluateFunctionAsync <string>("getAnnotations", new[] { (pageNumber + 1).ToString() });

            PageViewport viewport = await GetPageViewport(pageNumber, 1);

            List <Annotation> annotations = Newtonsoft.Json.JsonConvert.DeserializeObject <List <Annotation> >(annotationJSON);

            foreach (Annotation a in annotations)
            {
                // reverse the Y-coordinate to convert from PDF coordinates
                if (a.rect != null)
                {
                    if (a.rect.Count == 4)
                    {
                        a.rect[1] = viewport.height - a.rect[1];
                        a.rect[3] = viewport.height - a.rect[3];
                        float newY = a.rect[3];
                        a.rect[3] = a.rect[1];
                        a.rect[1] = newY;
                    }
                }
            }

            return(annotations);
        }
        /// <summary>
        /// Renders a page to a System.Drawing.Bitmap object, and sets a maximum width and height for the resultant image.
        /// Note that using the maximum width and height will not force the page to use those sizes. First, aspect-ratio is
        /// always maintained, so this method is designed to ensure the rendered page will fit inside the box defined by
        /// maxWidth and maxHeight. Secondly, this method will not scale the document up to fill the requested space.
        /// </summary>
        /// <param name="pageNumber">The zero-based page number.</param>
        /// <param name="maxWidth">The maximum width in pixels that the rendered page is allowed to be.</param>
        /// <param name="maxHeight">The maximum height in pixels that the rendered page is allowed to be.</param>
        /// <returns>The Bitmap object containing the rendered page.</returns>
        public async Task <Bitmap> RenderPageAsync(int pageNumber, int maxWidth, int maxHeight)
        {
            // This function is slightly annoying in that it's going to end up calling GetPageViewport twice,
            // when one call would really suffice. Should really restructure to remove the unnecessary call.
            double       pageScale = 1.0;
            PageViewport viewport  = await GetPageViewport(pageNumber, 1.0f);

            if (viewport.width > maxWidth || viewport.height > maxHeight)
            {
                // the viewport width or height is bigger than the maximum we want to allow, so we need to alter the page scale
                pageScale = Math.Min(maxWidth / viewport.width, maxHeight / viewport.height);
            }
            return(await RenderPageAsync(pageNumber, pageScale));
        }
        /// <summary>
        /// Renders a page to a System.Drawing.Bitmap object.
        /// </summary>
        /// <param name="pageNumber">The zero-based page number.</param>
        /// <param name="pageScale">The page scale to use - a larger scale equates to a bigger final image. If you unsure of what scale to use, start at 1.0.</param>
        /// <returns>The Bitmap object containing the rendered page.</returns>
        public async Task <Bitmap> RenderPageAsync(int pageNumber, double pageScale)
        {
            PageViewport viewport = await GetPageViewport(pageNumber, (float)pageScale);

            int newWidth  = (int)Math.Round(viewport.width);
            int newHeight = (int)Math.Round(viewport.height);

            if (chromePage.Viewport.Width != newWidth || chromePage.Viewport.Height != newHeight)
            {
                await chromePage.SetViewportAsync(new ViewPortOptions()
                {
                    Width  = (int)Math.Round(viewport.width),
                    Height = (int)Math.Round(viewport.height)
                });
            }

            bool rendered = await chromePage.EvaluateFunctionAsync <bool>("renderPage", new[] { (pageNumber + 1).ToString(), pageScale.ToString() });

            //if (!renderEvent.WaitOne(5000))
            //{
            //    Console.WriteLine("RenderPage renderEvent timed out.");
            //}
            return(await GetPage(pageScale));
        }
        public async Task <Size> GetPageSizeAsync(int pageNumber, float scale)
        {
            PageViewport viewport = await GetPageViewport(pageNumber, scale);

            return(new Size((int)Math.Round(viewport.width), (int)Math.Round(viewport.height)));
        }