private void RefreshPage_INTERNAL_FAST() { while (true) { // Get the next piece of work PendingRefreshWork pending_refresh_work = null; lock (pending_refresh_work_lock) { pending_refresh_work = pending_refresh_work_fast; pending_refresh_work_fast = null; // If there is nothing to do, then return if (null == pending_refresh_work) { pending_refresh_work_fast_running = false; return; } } // Do the work try { if (page_is_in_view) { double desired_rescaled_image_height = remembered_image_height * pdf_renderer_control_stats.zoom_factor * pdf_renderer_control_stats.DPI; if (null != CurrentlyShowingImage && CurrentlyShowingImage.requested_height == desired_rescaled_image_height) { ImagePage_HIDDEN.Stretch = Stretch.None; } else { ImagePage_HIDDEN.Stretch = Stretch.Uniform; } } Height = (int)(remembered_image_height * pdf_renderer_control_stats.zoom_factor); Width = (int)(remembered_image_width * pdf_renderer_control_stats.zoom_factor); } catch (Exception ex) { Logging.Error(ex, "There was a problem while trying to FAST render the page image for page {0} of document {1}", page, pdf_renderer_control_stats.pdf_document.Fingerprint); } } }
/// <summary> /// Queues the page for refresh, holding onto the most recent recommended_pretty_image_rescale. /// Any previous queued refresh is ignored. If another refresh is busy running, then the most recently received request is queued. /// </summary> /// <param name="requested_image_rescale">The suggested image to use, if null then will be requested asynchronously.</param> private void RefreshPage(BitmapSource requested_image_rescale, double requested_height) { PendingRefreshWork pending_refresh_work = new PendingRefreshWork { requested_image_rescale = requested_image_rescale, requested_height = requested_height }; lock (pending_refresh_work_lock) { pending_refresh_work_fast = pending_refresh_work; if (!pending_refresh_work_fast_running) { pending_refresh_work_fast_running = true; Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() => RefreshPage_INTERNAL_FAST())); } pending_refresh_work_slow = pending_refresh_work; if (!pending_refresh_work_slow_running) { pending_refresh_work_slow_running = true; Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)(() => RefreshPage_INTERNAL_SLOW())); } } }
private void RefreshPage_INTERNAL_SLOW() { while (true) { // Get the next piece of work PendingRefreshWork pending_refresh_work = null; lock (pending_refresh_work_lock) { pending_refresh_work = pending_refresh_work_slow; pending_refresh_work_slow = null; // If there is nothing to do, then return if (null == pending_refresh_work) { pending_refresh_work_slow_running = false; return; } } // Do the work try { // Invert colours if required if (page_is_in_view) { InvertColours(pdf_renderer_control_stats.are_colours_inverted); } // Page is not in view, be nice to memory and clean up if (!page_is_in_view) { CurrentlyShowingImage = null; Height = (int)(remembered_image_height * pdf_renderer_control_stats.zoom_factor); Width = (int)(remembered_image_width * pdf_renderer_control_stats.zoom_factor); continue; } if (page_is_in_view) { // Work out the size of the image we would like to have double desired_rescaled_image_height = remembered_image_height * pdf_renderer_control_stats.zoom_factor * pdf_renderer_control_stats.DPI; // Is the current image not good enough? Then perhaps use a provided one if (null == CurrentlyShowingImage || CurrentlyShowingImage.requested_height != desired_rescaled_image_height) { // Check if we want to use the supplied image if (null != pending_refresh_work.requested_image_rescale) { // Choose the closer image double discrepancy_existing_image = (null == CurrentlyShowingImage) ? Double.MaxValue : Math.Abs(CurrentlyShowingImage.requested_height - desired_rescaled_image_height); double discrepancy_supplied_image = (null == pending_refresh_work.requested_image_rescale) ? Double.MaxValue : Math.Abs(pending_refresh_work.requested_height - desired_rescaled_image_height); // If the request image is better, use it if (discrepancy_supplied_image < discrepancy_existing_image) { CurrentlyShowingImage = new CurrentlyShowingImageClass { Image = pending_refresh_work.requested_image_rescale, requested_height = pending_refresh_work.requested_height }; } } } // If our current image is still not good enough, request one if (null == CurrentlyShowingImage || CurrentlyShowingImage.requested_height != desired_rescaled_image_height) { pdf_renderer_control_stats.GetResizedPageImage(this, page, desired_rescaled_image_height, RefreshPage_ResizedImageCallback); } // Recalculate the aspect ratio if (null != CurrentlyShowingImage) { if (CurrentlyShowingImage.requested_height == desired_rescaled_image_height) { ImagePage_HIDDEN.Stretch = Stretch.None; } else { ImagePage_HIDDEN.Stretch = Stretch.Uniform; } remembered_image_height = BASIC_PAGE_HEIGHT; remembered_image_width = BASIC_PAGE_HEIGHT * CurrentlyShowingImage.Image.Width / CurrentlyShowingImage.Image.Height; pdf_renderer_control_stats.largest_page_image_width = Math.Max(pdf_renderer_control_stats.largest_page_image_width, remembered_image_width); pdf_renderer_control_stats.largest_page_image_height = Math.Max(pdf_renderer_control_stats.largest_page_image_height, remembered_image_height); Height = (int)(remembered_image_height * pdf_renderer_control_stats.zoom_factor); Width = (int)(remembered_image_width * pdf_renderer_control_stats.zoom_factor); } } } catch (Exception ex) { Logging.Error(ex, "There was a problem while trying to SLOW render the page image for page {0} of document {1}", page, pdf_renderer_control_stats.pdf_document.Fingerprint); } } }