module Pdf.Toolbox.Document.PageNode
(
PageNode,
PageTree(..),
pageNodeNKids,
pageNodeParent,
pageNodeKids,
loadPageNode,
pageNodePageByNum
)
where
import Pdf.Toolbox.Core
import Pdf.Toolbox.Document.Monad
import Pdf.Toolbox.Document.Internal.Types
import Pdf.Toolbox.Document.Internal.Util
pageNodeNKids :: MonadPdf m => PageNode -> PdfE m Int
pageNodeNKids (PageNode _ dict) =
lookupDict "Count" dict >>= fromObject >>= intValue
pageNodeParent :: MonadPdf m => PageNode -> PdfE m (Maybe PageNode)
pageNodeParent (PageNode _ dict) =
case lookupDict' "Parent" dict of
Nothing -> return Nothing
Just o -> do
ref <- fromObject o
node <- lookupObject ref >>= fromObject
ensureType "Pages" node
return $ Just $ PageNode ref node
pageNodeKids :: MonadPdf m => PageNode -> PdfE m [Ref]
pageNodeKids (PageNode _ dict) = do
Array kids <- lookupDict "Kids" dict >>= fromObject
mapM fromObject kids
loadPageNode :: MonadPdf m => Ref -> PdfE m PageTree
loadPageNode ref = do
node <- lookupObject ref >>= fromObject
nodeType <- dictionaryType node
case nodeType of
"Pages" -> return $ PageTreeNode $ PageNode ref node
"Page" -> return $ PageTreeLeaf $ Page ref node
_ -> throwE $ UnexpectedError $ "Unexpected page tree node type: " ++ show nodeType
pageNodePageByNum :: MonadPdf m => PageNode -> Int -> PdfE m Page
pageNodePageByNum node num = annotateError ("page #" ++ show num ++ " for node: " ++ show node) $ do
pageNodeKids node >>= loop num
where
loop _ [] = throwE $ UnexpectedError "Page not found"
loop i (x:xs) = do
kid <- loadPageNode x
case kid of
PageTreeNode n -> do
nkids <- pageNodeNKids n
if i < nkids
then pageNodePageByNum n i
else loop (i nkids) xs
PageTreeLeaf page ->
if i == 0
then return page
else loop (i 1) xs