public Page GetPage(int pageNumber) { if (locatedPages.TryGetValue(pageNumber, out DictionaryToken targetPageDictionary)) { // TODO: cache the page return(pageFactory.Create(pageNumber, targetPageDictionary, new PageTreeMembers(), isLenientParsing)); } var observed = new List <int>(); var pageTreeMembers = new PageTreeMembers(); // todo: running a search for a different, unloaded, page number, results in a bug. var isFound = FindPage(rootPageDictionary, pageNumber, observed, pageTreeMembers); if (!isFound || !locatedPages.TryGetValue(pageNumber, out targetPageDictionary)) { throw new ArgumentOutOfRangeException("Could not find the page with number: " + pageNumber); } var page = pageFactory.Create(pageNumber, targetPageDictionary, pageTreeMembers, isLenientParsing); locatedPages[pageNumber] = targetPageDictionary; return(page); }
public Page GetPage(int pageNumber) { if (pageNumber <= 0 || pageNumber > Count) { throw new ArgumentOutOfRangeException(nameof(pageNumber), $"Page number {pageNumber} invalid, must be between 1 and {Count}."); } var pageNode = catalog.GetPageNode(pageNumber); var pageStack = new Stack <PageTreeNode>(); var currentNode = pageNode; while (currentNode != null) { pageStack.Push(currentNode); currentNode = currentNode.Parent; } var pageTreeMembers = new PageTreeMembers(); while (pageStack.Count > 0) { currentNode = pageStack.Pop(); if (currentNode.NodeDictionary.TryGet(NameToken.Resources, pdfScanner, out DictionaryToken resourcesDictionary)) { pageTreeMembers.ParentResources.Enqueue(resourcesDictionary); } if (currentNode.NodeDictionary.TryGet(NameToken.MediaBox, pdfScanner, out ArrayToken mediaBox)) { pageTreeMembers.MediaBox = new MediaBox(mediaBox.ToRectangle()); } if (currentNode.NodeDictionary.TryGet(NameToken.Rotate, pdfScanner, out NumericToken rotateToken)) { pageTreeMembers.Rotation = rotateToken.Int; } } var page = pageFactory.Create(pageNumber, pageNode.NodeDictionary, pageTreeMembers, isLenientParsing); return(page); }
public bool FindPage(DictionaryToken currentPageDictionary, int soughtPageNumber, List <int> pageNumbersObserved, PageTreeMembers pageTreeMembers) { var type = currentPageDictionary.GetNameOrDefault(NameToken.Type); if (type?.Equals(NameToken.Page) == true) { var pageNumber = GetNextPageNumber(pageNumbersObserved); bool found = pageNumber == soughtPageNumber; locatedPages[pageNumber] = currentPageDictionary; pageNumbersObserved.Add(pageNumber); return(found); } if (type?.Equals(NameToken.Pages) != true) { log.Warn("Did not find the expected type (Page or Pages) in dictionary: " + currentPageDictionary); return(false); } if (currentPageDictionary.TryGet(NameToken.MediaBox, out var token)) { var mediaBox = DirectObjectFinder.Get <ArrayToken>(token, pdfScanner); pageTreeMembers.MediaBox = new MediaBox(mediaBox.ToRectangle()); } if (currentPageDictionary.TryGet(NameToken.Rotate, pdfScanner, out NumericToken rotateToken)) { pageTreeMembers.Rotation = rotateToken.Int; } if (!currentPageDictionary.TryGet(NameToken.Kids, out var kids) || !(kids is ArrayToken kidsArray)) { return(false); } pageFactory.LoadResources(currentPageDictionary, isLenientParsing); bool childFound = false; foreach (var kid in kidsArray.Data) { // todo: exit early var child = DirectObjectFinder.Get <DictionaryToken>(kid, pdfScanner); var thisPageMatches = FindPage(child, soughtPageNumber, pageNumbersObserved, pageTreeMembers); if (thisPageMatches) { childFound = true; break; } } return(childFound); }