Implement Box instance from Layer to Object, either all at once or indexed by an ObjectId
This commit is contained in:
parent
85ee8519c4
commit
83a63d4b02
1 changed files with 44 additions and 3 deletions
|
@ -1,19 +1,28 @@
|
||||||
{-# LANGUAGE NamedFieldPuns #-}
|
{-# LANGUAGE NamedFieldPuns #-}
|
||||||
|
{-# LANGUAGE FlexibleInstances #-}
|
||||||
|
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||||
module PDF.Layer (
|
module PDF.Layer (
|
||||||
Layer(..)
|
Layer(..)
|
||||||
, unify
|
, unify
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import Control.Monad.Fail (MonadFail(..))
|
||||||
import Data.Map (Map, (!), mapWithKey, member)
|
import Data.Map (Map, (!), mapWithKey, member)
|
||||||
import qualified Data.Map as Map (empty, union)
|
import qualified Data.Map as Map (
|
||||||
|
empty, insert, keysSet, lookup, member, union
|
||||||
|
)
|
||||||
|
import qualified Data.Set as Set (delete, toList)
|
||||||
|
import PDF.Box (Box(..))
|
||||||
import PDF.Object (
|
import PDF.Object (
|
||||||
IndexedObjects, IndirectObjCoordinates(..), Occurrence(..)
|
IndexedObjects, IndirectObjCoordinates(..), Object, Occurrence(..)
|
||||||
, Structure(..), XRefEntry(..), XRefSection, eofMarker, outputBody
|
, Structure(..), XRefEntry(..), XRefSection, eofMarker, outputBody
|
||||||
)
|
)
|
||||||
import qualified PDF.Output as Output (line)
|
import qualified PDF.Output as Output (line)
|
||||||
import PDF.Output (
|
import PDF.Output (
|
||||||
Offset, Output(..), Resource(..), byteString, getOffset, getOffsets, newLine
|
ObjectId, Offset(..), Output(..), Resource(..), byteString, getOffset
|
||||||
|
, getOffsets, newLine
|
||||||
)
|
)
|
||||||
|
import Prelude hiding (fail)
|
||||||
import Text.Printf (printf)
|
import Text.Printf (printf)
|
||||||
|
|
||||||
data Layer = Layer {
|
data Layer = Layer {
|
||||||
|
@ -44,6 +53,38 @@ instance Output Layer where
|
||||||
where
|
where
|
||||||
Structure {xRef, trailer} = docStructure
|
Structure {xRef, trailer} = docStructure
|
||||||
|
|
||||||
|
data AllObjects = AllObjects
|
||||||
|
|
||||||
|
instance MonadFail m => Box m AllObjects Layer (Map ObjectId Object) where
|
||||||
|
r AllObjects = return . objects
|
||||||
|
w AllObjects layer@(Layer {occurrences, docStructure}) newObjects =
|
||||||
|
return $ layer {
|
||||||
|
occurrences = keptOccurrences ++ newOccurrences
|
||||||
|
, objects = newObjects
|
||||||
|
, docStructure = docStructure {
|
||||||
|
xRef = (const $ InUse (Offset 0) 0) <$> newObjects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
where
|
||||||
|
filterOccurrences c@(Comment _) (occ, newObjIds) = (c:occ, newObjIds)
|
||||||
|
filterOccurrences i@(Indirect (IndirectObjCoordinates {objectId})) (occ, newObjIds)
|
||||||
|
| Map.member objectId newObjects = (i:occ, Set.delete objectId newObjIds)
|
||||||
|
| otherwise = (occ, newObjIds)
|
||||||
|
(keptOccurrences, newObjectIds) =
|
||||||
|
foldr filterOccurrences ([], Map.keysSet newObjects) occurrences
|
||||||
|
makeOccurrence objectId =
|
||||||
|
Indirect (IndirectObjCoordinates {objectId, versionNumber = 0})
|
||||||
|
newOccurrences = makeOccurrence <$> Set.toList newObjectIds
|
||||||
|
|
||||||
|
instance MonadFail m => Box m ObjectId Layer Object where
|
||||||
|
r objectId = maybe (fail errorMsg) return . Map.lookup objectId . objects
|
||||||
|
where
|
||||||
|
errorMsg = "Unknown " ++ show objectId
|
||||||
|
w objectId layer@(Layer {objects}) object
|
||||||
|
| Map.member objectId objects =
|
||||||
|
return $ layer {objects = Map.insert objectId object objects}
|
||||||
|
| otherwise = fail $ "Unknown " ++ show objectId
|
||||||
|
|
||||||
emptyLayer :: Layer
|
emptyLayer :: Layer
|
||||||
emptyLayer = Layer {
|
emptyLayer = Layer {
|
||||||
docStructure = Structure {xRef = Map.empty, trailer = Map.empty}
|
docStructure = Structure {xRef = Map.empty, trailer = Map.empty}
|
||||||
|
|
Loading…
Reference in a new issue