/// <summary> /// Gets all pages to be drawn in specified region. /// </summary> /// <param name="pageOnCenter">The page on which is center of vertical direction of the viewport.</param> /// <param name="topLine">Top line of viewport.</param> /// <param name="bottomLine">Bottom line of viewport.</param> /// <param name="pageMargin">Margin around the page.</param> /// <param name="zoomFactor">Zoom factor to use for pages. Not for page margin.</param> /// <returns>Pages to draw in required region.</returns> protected virtual IList <IPDFPageRenderInfo> DeterminePagesToRenderVirtual(IPDFPageRenderInfo pageOnCenter, ref double topLine, ref double bottomLine, double pageMargin, double zoomFactor) { // Base check. if (pageOnCenter == null || !pageOnCenter.IsOnCenter || pageOnCenter.Page == null || pageOnCenter.Page.PageIndex >= PageComponent.PageCount) { // We don't have required information. return(DeterminePagesToRenderVirtual(topLine, bottomLine, pageMargin, zoomFactor)); } // Height of viewport. var height = bottomLine - topLine; // Let's say, the middle point of height is on position 0. Create virtual top line. var virtualTopLine = -1d * (bottomLine - topLine) / 2d; // List of all pages to render. var list = new List <IPDFPageRenderInfo>(); // Let's take the page witch vertical center on it has this point on position 0. // We'll correct all top and bottom lines later. var pageOnMiddle = new PDFPageRenderInfo(pageOnCenter.Page) { Left = 0, Right = PageWidth(pageOnCenter.Page) * zoomFactor, Top = -1d * pageOnCenter.PagePositionOnCenter * PageHeight(pageOnCenter.Page) * zoomFactor, Bottom = (1d - pageOnCenter.PagePositionOnCenter) * PageHeight(pageOnCenter.Page) * zoomFactor, IsOnCenter = pageOnCenter.IsOnCenter, PagePositionOnCenter = pageOnCenter.PagePositionOnCenter, }; // Add this page to the list. list.Add(pageOnMiddle); // Current position on Y-axis. var currentPositionOnY = pageOnMiddle.Top; currentPositionOnY -= pageMargin; // Iterate through pages from 'page on middle' to the first page. // Iterate through all of them, don't break on page above virtual top line. for (var index = pageOnCenter.Page.PageIndex - 1; index >= 0; index--) { // Get page to check. var page = PageComponent.Pages[index]; // Check the curreint position on y relative to the virtual top line. if (currentPositionOnY > virtualTopLine) { // This page is still visible. var nextPageToAdd = new PDFPageRenderInfo(page) { Left = 0, Right = PageWidth(page) * zoomFactor, Top = currentPositionOnY - (PageHeight(page) * zoomFactor), Bottom = currentPositionOnY, }; // Insert this page to the first position of list. list.Insert(0, nextPageToAdd); } // Adjust current position on y. currentPositionOnY -= PageHeight(page) * zoomFactor; currentPositionOnY -= pageMargin; } // Set new top and bottom line returned back. topLine = (-1d * currentPositionOnY) - (height / 2d); bottomLine = topLine + height; // A negative top line means that the first page is displayed and not positioned at the top. if (topLine < 0d) { topLine = 0d; bottomLine = topLine + height; currentPositionOnY = pageMargin; // Adjust top and bottom line of all already added pages to render. foreach (var pageRenderInfo in list) { pageRenderInfo.Top = currentPositionOnY; pageRenderInfo.Bottom = currentPositionOnY + (PageHeight(pageRenderInfo.Page) * zoomFactor); // Adjust current position on y axis. currentPositionOnY += pageMargin + (PageHeight(pageRenderInfo.Page) * zoomFactor); } } else { // Adjust top and bottom line of all already added pages to render. foreach (var pageRenderInfo in list) { pageRenderInfo.Top += topLine + (height / 2d); pageRenderInfo.Bottom += topLine + (height / 2d); currentPositionOnY = pageRenderInfo.Bottom; } // Adjust current position on y axis. currentPositionOnY += pageMargin; } // Iterate through pages from 'page on middle' to the last page. for (var index = pageOnCenter.Page.PageIndex + 1; index < PageComponent.Pages.Count; index++) { // Filter out all pages below bottom line. if (currentPositionOnY > bottomLine) { // Page is below bottom line. // End foreach. break; } // Part of this page is between top and bottom line. // Add this page to the list. var nextPageToAdd = new PDFPageRenderInfo(PageComponent.Pages[index]) { Left = 0, Right = PageWidth(PageComponent.Pages[index]) * zoomFactor, Top = currentPositionOnY, Bottom = currentPositionOnY + (PageHeight(PageComponent.Pages[index]) * zoomFactor), }; // Add the page to the list. list.Add(nextPageToAdd); // Adjust current position on y axis. currentPositionOnY += pageMargin + (PageHeight(PageComponent.Pages[index]) * zoomFactor); } return(list); }
/// <summary> /// Gets all pages to be drawn in specified region. /// </summary> /// <param name="topLine">Top line of viewport.</param> /// <param name="bottomLine">Bottom line of viewport.</param> /// <param name="pageMargin">Margin around the page.</param> /// <param name="zoomFactor">Zoom factor to use for pages. Not for page margin.</param> /// <param name="setCurrentPageIndex">If <c>true</c>, page on middle of height will be set as current page.</param> /// <returns>Pages to draw in required region.</returns> protected virtual IList <IPDFPageRenderInfo> DeterminePagesToRenderVirtual(double topLine, double bottomLine, double pageMargin, double zoomFactor, bool setCurrentPageIndex = false) { // List of all pages to render. var list = new List <IPDFPageRenderInfo>(); // Current position on Y-axis. var currentPositionOnY = pageMargin; // Center line on viewport var centerLine = (topLine + bottomLine) / 2; var isCenterSet = false; // Iterate through all pages. foreach (var page in PageComponent.Pages) { // Filter out all pages above top line. if (currentPositionOnY + (PageHeight(page) * zoomFactor) < topLine) { // Page is above top line. // Adjust the current position on y and continue. currentPositionOnY += pageMargin + (PageHeight(page) * zoomFactor); continue; } // Filter out all pages below bottom line. if (currentPositionOnY > bottomLine) { // Page is below bottom line. // End foreach. break; } // Part of this page is between top and bottom line. // Add this page to the list. var pageToAdd = new PDFPageRenderInfo(page) { Left = 0, Right = PageWidth(page) * zoomFactor, Top = currentPositionOnY, Bottom = currentPositionOnY + (PageHeight(page) * zoomFactor), }; // Check if the middle point of height of viewport is over this page. if (pageToAdd.Top < centerLine && pageToAdd.Bottom > centerLine) { // Middle point of height of viewport is over this page. // Store thid information to use it later during zoom manipulation. pageToAdd.IsOnCenter = true; pageToAdd.PagePositionOnCenter = (centerLine - pageToAdd.Top) / (pageToAdd.Bottom - pageToAdd.Top); isCenterSet = true; if (setCurrentPageIndex) { PageComponent.SetCurrentInformation(pageToAdd.Page); } } // Special behaviour. Middle point of height of viewport may be between to pages. // In this case use current page to add. if (!isCenterSet && pageToAdd.Top > centerLine) { pageToAdd.IsOnCenter = true; pageToAdd.PagePositionOnCenter = 0d; isCenterSet = true; if (setCurrentPageIndex) { PageComponent.SetCurrentInformation(pageToAdd.Page); } } // Add the page to the list. list.Add(pageToAdd); // Adjust current position on y. currentPositionOnY += pageMargin + (PageHeight(page) * zoomFactor); } return(list); }