{-# LANGUAGE CPP #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE DeriveFunctor #-}
---------------------------------------------------------
-- |
-- Copyright   : (c) 2006-2016, alpheccar.org
-- License     : BSD-style
--
-- Maintainer  : misc@NOSPAMalpheccar.org
-- Stability   : experimental
-- Portability : portable
--
-- PDF Text
---------------------------------------------------------
{-# LANGUAGE FlexibleContexts #-}
module Graphics.PDF.Text(
   -- * Text
   -- ** Types
     PDFFont(..)
   , FontName(..)
   , TextMode(..)
   , PDFText
   , UnscaledUnit
   -- ** Functions
   , drawText
   , text
   , startNewLine
   , displayGlyphs
   , displayText
   , textStart
   , setFont
   , leading
   , charSpace
   , wordSpace
   , textScale
   , renderMode
   , rise
   , setTextMatrix
   , textWidth
   , pdfGlyph
   , glyph
 ) where

import Graphics.PDF.LowLevel.Types
import Graphics.PDF.Draw
import Control.Monad.State
import Graphics.PDF.Resources
import Control.Monad.Writer
import qualified Data.Set as Set
import Data.List(foldl')
import Data.Binary.Builder(Builder)
import Graphics.PDF.LowLevel.Serializer
import qualified Data.ByteString as S
import qualified Data.Text as T
import Graphics.PDF.Fonts.Font
import Graphics.PDF.Fonts.StandardFont


glyphStreamWidth :: PDFFont
                 -> PDFGlyph 
                 -> PDFFloat
glyphStreamWidth :: PDFFont -> PDFGlyph -> PDFFloat
glyphStreamWidth (PDFFont AnyFont
f Int
s) (PDFGlyph ByteString
t) = 
 let w :: PDFFloat
w = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\PDFFloat
a Word8
b -> PDFFloat
a forall a. Num a => a -> a -> a
+ forall f. IsFont f => f -> Int -> GlyphCode -> PDFFloat
glyphWidth AnyFont
f Int
s (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b)) PDFFloat
0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [Word8]
S.unpack forall a b. (a -> b) -> a -> b
$ ByteString
t
 in
  PDFFloat
w forall a. Num a => a -> a -> a
+ (forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\PDFFloat
a (GlyphCode
x,GlyphCode
y) -> PDFFloat
a forall a. Num a => a -> a -> a
+ forall f.
IsFont f =>
f -> Int -> GlyphCode -> GlyphCode -> PDFFloat
getKern AnyFont
f Int
s GlyphCode
x GlyphCode
y) PDFFloat
0 forall a b. (a -> b) -> a -> b
$ [(Word8 -> GlyphCode
GlyphCode Word8
ca,Word8 -> GlyphCode
GlyphCode Word8
cb) | (Word8
ca,Word8
cb) <- ByteString -> ByteString -> [(Word8, Word8)]
S.zip ByteString
t (HasCallStack => ByteString -> ByteString
S.tail ByteString
t)])

textWidth :: PDFFont -> T.Text -> PDFFloat
textWidth :: PDFFont -> Text -> PDFFloat
textWidth PDFFont
f Text
t = PDFFont -> PDFGlyph -> PDFFloat
glyphStreamWidth PDFFont
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. PDFFont -> Text -> PDFGlyph
pdfGlyph PDFFont
f forall a b. (a -> b) -> a -> b
$ Text
t
      
pdfGlyph :: PDFFont
         -> T.Text 
         -> PDFGlyph 
pdfGlyph :: PDFFont -> Text -> PDFGlyph
pdfGlyph (PDFFont AnyFont
f Int
_) Text
t = ByteString -> PDFGlyph
PDFGlyph forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Word8] -> ByteString
S.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall f. IsFont f => f -> Char -> GlyphCode
charGlyph AnyFont
f) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack forall a b. (a -> b) -> a -> b
$ Text
t 


type FontState = (Set.Set AnyFont)

data TextParameter = TextParameter { TextParameter -> PDFFloat
tc :: !PDFFloat
                                   , TextParameter -> PDFFloat
tw :: !PDFFloat
                                   , TextParameter -> PDFFloat
tz :: !PDFFloat
                                   , TextParameter -> PDFFloat
tl :: !PDFFloat
                                   , TextParameter -> PDFFloat
ts :: !PDFFloat
                                   , TextParameter -> FontState
fontState :: FontState
                                   , TextParameter -> Maybe PDFFont
currentFont :: Maybe PDFFont
                                   }
defaultParameters ::  TextParameter
defaultParameters :: TextParameter
defaultParameters = PDFFloat
-> PDFFloat
-> PDFFloat
-> PDFFloat
-> PDFFloat
-> FontState
-> Maybe PDFFont
-> TextParameter
TextParameter PDFFloat
0 PDFFloat
0 PDFFloat
100 PDFFloat
0 PDFFloat
0 (forall a. Set a
Set.empty) forall a. Maybe a
Nothing

     
-- | The text monad 
newtype PDFText a = PDFText {forall a. PDFText a -> WriterT Builder (State TextParameter) a
unText :: WriterT Builder (State TextParameter) a}          
#ifndef __HADDOCK__                    
  deriving(Applicative PDFText
forall a. a -> PDFText a
forall a b. PDFText a -> PDFText b -> PDFText b
forall a b. PDFText a -> (a -> PDFText b) -> PDFText b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: forall a. a -> PDFText a
$creturn :: forall a. a -> PDFText a
>> :: forall a b. PDFText a -> PDFText b -> PDFText b
$c>> :: forall a b. PDFText a -> PDFText b -> PDFText b
>>= :: forall a b. PDFText a -> (a -> PDFText b) -> PDFText b
$c>>= :: forall a b. PDFText a -> (a -> PDFText b) -> PDFText b
Monad,Functor PDFText
forall a. a -> PDFText a
forall a b. PDFText a -> PDFText b -> PDFText a
forall a b. PDFText a -> PDFText b -> PDFText b
forall a b. PDFText (a -> b) -> PDFText a -> PDFText b
forall a b c. (a -> b -> c) -> PDFText a -> PDFText b -> PDFText c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: forall a b. PDFText a -> PDFText b -> PDFText a
$c<* :: forall a b. PDFText a -> PDFText b -> PDFText a
*> :: forall a b. PDFText a -> PDFText b -> PDFText b
$c*> :: forall a b. PDFText a -> PDFText b -> PDFText b
liftA2 :: forall a b c. (a -> b -> c) -> PDFText a -> PDFText b -> PDFText c
$cliftA2 :: forall a b c. (a -> b -> c) -> PDFText a -> PDFText b -> PDFText c
<*> :: forall a b. PDFText (a -> b) -> PDFText a -> PDFText b
$c<*> :: forall a b. PDFText (a -> b) -> PDFText a -> PDFText b
pure :: forall a. a -> PDFText a
$cpure :: forall a. a -> PDFText a
Applicative,forall a b. a -> PDFText b -> PDFText a
forall a b. (a -> b) -> PDFText a -> PDFText b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> PDFText b -> PDFText a
$c<$ :: forall a b. a -> PDFText b -> PDFText a
fmap :: forall a b. (a -> b) -> PDFText a -> PDFText b
$cfmap :: forall a b. (a -> b) -> PDFText a -> PDFText b
Functor,MonadWriter Builder,MonadState TextParameter)
#else
instance Monad PDFText
instance Functor PDFText
instance MonadWriter Builder PDFText
instance MonadState TextParameter PDFText
#endif
    
instance MonadPath PDFText

-- | Unscaled unit (not scaled by the font size)
type UnscaledUnit = PDFFloat  

-- | Rendering mode for text display
data TextMode = FillText
              | StrokeText
              | FillAndStrokeText
              | InvisibleText
              | FillTextAndAddToClip
              | StrokeTextAndAddToClip
              | FillAndStrokeTextAndAddToClip
              | AddToClip
              deriving(TextMode -> TextMode -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TextMode -> TextMode -> Bool
$c/= :: TextMode -> TextMode -> Bool
== :: TextMode -> TextMode -> Bool
$c== :: TextMode -> TextMode -> Bool
Eq,Eq TextMode
TextMode -> TextMode -> Bool
TextMode -> TextMode -> Ordering
TextMode -> TextMode -> TextMode
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: TextMode -> TextMode -> TextMode
$cmin :: TextMode -> TextMode -> TextMode
max :: TextMode -> TextMode -> TextMode
$cmax :: TextMode -> TextMode -> TextMode
>= :: TextMode -> TextMode -> Bool
$c>= :: TextMode -> TextMode -> Bool
> :: TextMode -> TextMode -> Bool
$c> :: TextMode -> TextMode -> Bool
<= :: TextMode -> TextMode -> Bool
$c<= :: TextMode -> TextMode -> Bool
< :: TextMode -> TextMode -> Bool
$c< :: TextMode -> TextMode -> Bool
compare :: TextMode -> TextMode -> Ordering
$ccompare :: TextMode -> TextMode -> Ordering
Ord,Int -> TextMode
TextMode -> Int
TextMode -> [TextMode]
TextMode -> TextMode
TextMode -> TextMode -> [TextMode]
TextMode -> TextMode -> TextMode -> [TextMode]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: TextMode -> TextMode -> TextMode -> [TextMode]
$cenumFromThenTo :: TextMode -> TextMode -> TextMode -> [TextMode]
enumFromTo :: TextMode -> TextMode -> [TextMode]
$cenumFromTo :: TextMode -> TextMode -> [TextMode]
enumFromThen :: TextMode -> TextMode -> [TextMode]
$cenumFromThen :: TextMode -> TextMode -> [TextMode]
enumFrom :: TextMode -> [TextMode]
$cenumFrom :: TextMode -> [TextMode]
fromEnum :: TextMode -> Int
$cfromEnum :: TextMode -> Int
toEnum :: Int -> TextMode
$ctoEnum :: Int -> TextMode
pred :: TextMode -> TextMode
$cpred :: TextMode -> TextMode
succ :: TextMode -> TextMode
$csucc :: TextMode -> TextMode
Enum)

-- | Select a font to use
setFont :: PDFFont -> PDFText ()
setFont :: PDFFont -> PDFText ()
setFont f :: PDFFont
f@(PDFFont AnyFont
n Int
size) = forall a. WriterT Builder (State TextParameter) a -> PDFText a
PDFText forall a b. (a -> b) -> a -> b
$ do
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modifyStrict forall a b. (a -> b) -> a -> b
$ \TextParameter
s -> TextParameter
s {fontState :: FontState
fontState = forall a. Ord a => a -> Set a -> Set a
Set.insert AnyFont
n (TextParameter -> FontState
fontState TextParameter
s), currentFont :: Maybe PDFFont
currentFont = forall a. a -> Maybe a
Just PDFFont
f})
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$ [ forall s a. SerializeValue s a => a -> s
serialize String
"\n/" 
                     , forall s a. SerializeValue s a => a -> s
serialize (forall f. IsFont f => f -> String
name AnyFont
n)
                     , forall s a. SerializeValue s a => a -> s
serialize Char
' '
                     , forall a. PdfObject a => a -> Builder
toPDF Int
size
                     , forall s a. SerializeValue s a => a -> s
serialize String
" Tf"
                     ]
                    
  
-- | Draw a text in the draw monad
drawText :: PDFText a
         -> Draw a
drawText :: forall a. PDFText a -> Draw a
drawText PDFText a
t = do
    let ((a
a,Builder
w),TextParameter
s) = (forall s a. State s a -> s -> (a, s)
runState forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
runWriterT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. PDFText a -> WriterT Builder (State TextParameter) a
unText forall a b. (a -> b) -> a -> b
$ PDFText a
t) TextParameter
defaultParameters
    forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall {m :: * -> *} {a}.
(MonadState DrawState m, IsFont a, PdfResourceObject a) =>
a -> m ()
addFontRsrc (forall a. Set a -> [a]
Set.elems (TextParameter -> FontState
fontState TextParameter
s))
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s a. SerializeValue s a => a -> s
serialize forall a b. (a -> b) -> a -> b
$ String
"\nBT"
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell Builder
w
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s a. SerializeValue s a => a -> s
serialize forall a b. (a -> b) -> a -> b
$ String
"\nET"
    forall (m :: * -> *) a. Monad m => a -> m a
return a
a
 where
   addFontRsrc :: a -> m ()
addFontRsrc a
font = forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modifyStrict forall a b. (a -> b) -> a -> b
$ \DrawState
s ->
       DrawState
s { rsrc :: PDFResource
rsrc = PDFName -> PDFName -> AnyPdfObject -> PDFResource -> PDFResource
addResource (String -> PDFName
PDFName String
"Font") (String -> PDFName
PDFName (forall f. IsFont f => f -> String
name a
font)) (forall a. PdfResourceObject a => a -> AnyPdfObject
toRsrc a
font) (DrawState -> PDFResource
rsrc DrawState
s)}
   
-- | Set position for the text beginning
textStart :: PDFFloat
          -> PDFFloat
          -> PDFText ()
textStart :: PDFFloat -> PDFFloat -> PDFText ()
textStart PDFFloat
x PDFFloat
y = forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$ [ forall s a. SerializeValue s a => a -> s
serialize Char
'\n'
                                 , forall a. PdfObject a => a -> Builder
toPDF PDFFloat
x
                                 , forall s a. SerializeValue s a => a -> s
serialize Char
' '
                                 , forall a. PdfObject a => a -> Builder
toPDF PDFFloat
y
                                 , forall s a. SerializeValue s a => a -> s
serialize String
" Td"
                                 ]
 --writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " Td"         


glyph :: GlyphCode -> PDFGlyph 
glyph :: GlyphCode -> PDFGlyph
glyph GlyphCode
c = ByteString -> PDFGlyph
PDFGlyph forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> ByteString
S.singleton forall a b. (a -> b) -> a -> b
$ (forall a b. (Integral a, Num b) => a -> b
fromIntegral GlyphCode
c)

-- | Display glyphs
displayGlyphs :: PDFGlyph
              -> PDFText ()
displayGlyphs :: PDFGlyph -> PDFText ()
displayGlyphs PDFGlyph
t = do
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall a b. (a -> b) -> a -> b
$ forall s a. SerializeValue s a => a -> s
serialize Char
' '
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. PdfObject a => a -> Builder
toPDF forall a b. (a -> b) -> a -> b
$ PDFGlyph
t
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s a. SerializeValue s a => a -> s
serialize forall a b. (a -> b) -> a -> b
$ String
" Tj"

-- | Display text
displayText :: T.Text
            -> PDFText ()
displayText :: Text -> PDFText ()
displayText Text
t = do
    Maybe PDFFont
f <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets TextParameter -> Maybe PDFFont
currentFont
    case Maybe PDFFont
f of 
      Maybe PDFFont
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
      Just PDFFont
aFont -> do
         let g :: PDFGlyph
g = PDFFont -> Text -> PDFGlyph
pdfGlyph PDFFont
aFont Text
t
         PDFGlyph -> PDFText ()
displayGlyphs PDFGlyph
g


--    f <- gets currentFont
--    let rt = ripText f t
--    tell . serialize $ '\n'
--    tell lbracket
--    mapM_ displayGlyphs rt
--    tell rbracket
--    tell $ serialize " TJ"
-- where
-- 	displayGlyphs (w,c) = do
-- 		tell $ toPDF (toPDFString $ c:[])
-- 		tell bspace
-- 		tell . toPDF $ w
-- 		tell bspace

 
-- | Start a new line (leading value must have been set)
startNewLine :: PDFText ()
startNewLine :: PDFText ()
startNewLine = forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s a. SerializeValue s a => a -> s
serialize forall a b. (a -> b) -> a -> b
$ String
"\nT*"    

-- | Set leading value
leading :: UnscaledUnit -> PDFText ()
leading :: PDFFloat -> PDFText ()
leading PDFFloat
v = forall a. WriterT Builder (State TextParameter) a -> PDFText a
PDFText forall a b. (a -> b) -> a -> b
$ do
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modifyStrict forall a b. (a -> b) -> a -> b
$ \TextParameter
s -> TextParameter
s {tl :: PDFFloat
tl = PDFFloat
v})
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$  [ forall s a. SerializeValue s a => a -> s
serialize Char
'\n'
                      , forall a. PdfObject a => a -> Builder
toPDF PDFFloat
v
                      , forall s a. SerializeValue s a => a -> s
serialize String
" TL"
                      ]

-- | Set the additional char space
charSpace :: UnscaledUnit -> PDFText ()
charSpace :: PDFFloat -> PDFText ()
charSpace PDFFloat
v = forall a. WriterT Builder (State TextParameter) a -> PDFText a
PDFText forall a b. (a -> b) -> a -> b
$ do
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modifyStrict forall a b. (a -> b) -> a -> b
$ \TextParameter
s -> TextParameter
s {tc :: PDFFloat
tc = PDFFloat
v})
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat  forall a b. (a -> b) -> a -> b
$ [ forall s a. SerializeValue s a => a -> s
serialize Char
'\n'
                      , forall a. PdfObject a => a -> Builder
toPDF PDFFloat
v
                      , forall s a. SerializeValue s a => a -> s
serialize String
" Tc"
                      ]

-- | Set the additional word space
wordSpace :: UnscaledUnit -> PDFText ()
wordSpace :: PDFFloat -> PDFText ()
wordSpace PDFFloat
v = forall a. WriterT Builder (State TextParameter) a -> PDFText a
PDFText forall a b. (a -> b) -> a -> b
$ do
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modifyStrict forall a b. (a -> b) -> a -> b
$ \TextParameter
s -> TextParameter
s {tw :: PDFFloat
tw = PDFFloat
v})
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$ [ forall s a. SerializeValue s a => a -> s
serialize Char
'\n'
                      , forall a. PdfObject a => a -> Builder
toPDF PDFFloat
v
                      , forall s a. SerializeValue s a => a -> s
serialize String
" Tw"
                      ]

-- | Set scaling factor for text
textScale :: PDFFloat -> PDFText ()
textScale :: PDFFloat -> PDFText ()
textScale PDFFloat
v = forall a. WriterT Builder (State TextParameter) a -> PDFText a
PDFText forall a b. (a -> b) -> a -> b
$ do
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modifyStrict forall a b. (a -> b) -> a -> b
$ \TextParameter
s -> TextParameter
s {tz :: PDFFloat
tz = PDFFloat
v})
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat  forall a b. (a -> b) -> a -> b
$ [ forall s a. SerializeValue s a => a -> s
serialize Char
'\n'
                      , forall a. PdfObject a => a -> Builder
toPDF PDFFloat
v
                      , forall s a. SerializeValue s a => a -> s
serialize String
" Tz"
                      ]

-- | Choose the text rendering mode
renderMode :: TextMode -> PDFText ()
renderMode :: TextMode -> PDFText ()
renderMode TextMode
v = 
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$  [ forall s a. SerializeValue s a => a -> s
serialize Char
'\n'
                      , forall a. PdfObject a => a -> Builder
toPDF (forall a. Enum a => a -> Int
fromEnum TextMode
v)
                      , forall s a. SerializeValue s a => a -> s
serialize String
" Tr"
                      ]

-- | Set the rise value
rise :: UnscaledUnit -> PDFText ()
rise :: PDFFloat -> PDFText ()
rise PDFFloat
v = forall a. WriterT Builder (State TextParameter) a -> PDFText a
PDFText forall a b. (a -> b) -> a -> b
$ do
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modifyStrict forall a b. (a -> b) -> a -> b
$ \TextParameter
s -> TextParameter
s {ts :: PDFFloat
ts = PDFFloat
v})
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$  [ forall s a. SerializeValue s a => a -> s
serialize Char
'\n'
                      , forall a. PdfObject a => a -> Builder
toPDF PDFFloat
v
                      , forall s a. SerializeValue s a => a -> s
serialize String
" Ts"
                      ]

-- | Set the text transformation matrix
setTextMatrix :: Matrix -> PDFText()
setTextMatrix :: Matrix -> PDFText ()
setTextMatrix (Matrix PDFFloat
a PDFFloat
b PDFFloat
c PDFFloat
d PDFFloat
e PDFFloat
f) = 
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$ [ forall s a. SerializeValue s a => a -> s
serialize Char
'\n'
                     , forall a. PdfObject a => a -> Builder
toPDF PDFFloat
a
                     , forall s a. SerializeValue s a => a -> s
serialize Char
' '
                     , forall a. PdfObject a => a -> Builder
toPDF PDFFloat
b
                     , forall s a. SerializeValue s a => a -> s
serialize Char
' '
                     , forall a. PdfObject a => a -> Builder
toPDF PDFFloat
c
                     , forall s a. SerializeValue s a => a -> s
serialize Char
' '
                     , forall a. PdfObject a => a -> Builder
toPDF PDFFloat
d
                     , forall s a. SerializeValue s a => a -> s
serialize Char
' '
                     , forall a. PdfObject a => a -> Builder
toPDF PDFFloat
e
                     , forall s a. SerializeValue s a => a -> s
serialize Char
' '
                     , forall a. PdfObject a => a -> Builder
toPDF PDFFloat
f
                     , forall s a. SerializeValue s a => a -> s
serialize String
" Tm"
                     ]
    
-- | Utility function to quickly display one line of text
text :: PDFFont
     -> PDFFloat
     -> PDFFloat
     -> T.Text
     -> PDFText ()
text :: PDFFont -> PDFFloat -> PDFFloat -> Text -> PDFText ()
text PDFFont
f PDFFloat
x PDFFloat
y Text
t = do
    PDFFont -> PDFText ()
setFont PDFFont
f
    let g :: PDFGlyph
g = PDFFont -> Text -> PDFGlyph
pdfGlyph PDFFont
f Text
t
    PDFFloat -> PDFFloat -> PDFText ()
textStart PDFFloat
x PDFFloat
y
    PDFGlyph -> PDFText ()
displayGlyphs PDFGlyph
g